commands.g 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600
  1. /* $Header$ */
  2. /* Command grammar */
  3. {
  4. #include <stdio.h>
  5. #include <alloc.h>
  6. #include <signal.h>
  7. #include "ops.h"
  8. #include "class.h"
  9. #include "position.h"
  10. #include "file.h"
  11. #include "idf.h"
  12. #include "symbol.h"
  13. #include "tree.h"
  14. #include "langdep.h"
  15. #include "token.h"
  16. #include "expr.h"
  17. extern char *Salloc();
  18. extern char *strindex();
  19. extern FILE *db_in;
  20. extern int disable_intr;
  21. extern p_tree run_command, print_command;
  22. int errorgiven = 0;
  23. int child_interrupted = 0;
  24. int interrupted = 0;
  25. int eof_seen = 0;
  26. static int extended_charset = 0;
  27. static int in_expression = 0;
  28. struct token tok, aside;
  29. #define binprio(op) ((*(currlang->binop_prio))(op))
  30. #define unprio(op) ((*(currlang->unop_prio))(op))
  31. }
  32. %start Commands, commands;
  33. %lexical LLlex;
  34. commands
  35. { p_tree com, lastcom = 0;
  36. int give_prompt;
  37. }
  38. :
  39. [ %persistent command_line(&com)
  40. [ '\n' { give_prompt = 1; }
  41. | %default ';' { give_prompt = 0; }
  42. ]
  43. { if (com) {
  44. if (lastcom) {
  45. freenode(lastcom);
  46. lastcom = 0;
  47. }
  48. if (errorgiven) {
  49. freenode(com);
  50. com = 0;
  51. }
  52. else {
  53. eval(com);
  54. if (repeatable(com)) {
  55. lastcom = com;
  56. }
  57. else if (! in_status(com) &&
  58. com != run_command &&
  59. com != print_command) {
  60. freenode(com);
  61. com = 0;
  62. }
  63. }
  64. } else if (lastcom && ! errorgiven) {
  65. eval(lastcom);
  66. }
  67. if (give_prompt) {
  68. errorgiven = 0;
  69. interrupted = 0;
  70. prompt();
  71. }
  72. }
  73. ]*
  74. { signal_child(SIGKILL); }
  75. ;
  76. command_line(p_tree *p;)
  77. :
  78. { *p = 0; }
  79. [
  80. list_command(p)
  81. | file_command(p)
  82. | run_command(p)
  83. | stop_command(p)
  84. | when_command(p)
  85. | continue_command(p)
  86. | step_command(p)
  87. | next_command(p)
  88. | regs_command(p)
  89. | where_command(p)
  90. | STATUS { *p = mknode(OP_STATUS); }
  91. | DUMP { *p = mknode(OP_DUMP); }
  92. | RESTORE count(p)? { *p = mknode(OP_RESTORE, *p); }
  93. | delete_command(p)
  94. | print_command(p)
  95. | display_command(p)
  96. | trace_command(p)
  97. | set_command(p)
  98. | help_command(p)
  99. | FIND qualified_name(p){ *p = mknode(OP_FIND, *p); }
  100. | WHICH qualified_name(p){ *p = mknode(OP_WHICH, *p); }
  101. | able_command(p)
  102. |
  103. ]
  104. ;
  105. where_command(p_tree *p;)
  106. :
  107. WHERE { *p = mknode(OP_WHERE, (p_tree) 0); }
  108. [ count(&(*p)->t_args[0])?
  109. | '-' count(&(*p)->t_args[0])
  110. { (*p)->t_args[0]->t_ival = - (*p)->t_args[0]->t_ival; }
  111. ]
  112. ;
  113. list_command(p_tree *p;)
  114. { p_tree t1 = 0, t2 = 0; }
  115. :
  116. LIST
  117. [
  118. | count(&t1)
  119. | qualified_name(&t1)
  120. ]
  121. [ ',' count(&t2)
  122. | '-'
  123. [ count(&t2) { t2->t_ival = - t2->t_ival; }
  124. | { t2 = mknode(OP_INTEGER, -100000000L); }
  125. ]
  126. |
  127. ]
  128. { *p = mknode(OP_LIST, t1, t2); }
  129. ;
  130. file_command(p_tree *p;)
  131. :
  132. XFILE { extended_charset = 1; }
  133. [ { *p = 0; }
  134. | name(p) { (*p)->t_idf = str2idf((*p)->t_str, 0); }
  135. ] { *p = mknode(OP_FILE, *p);
  136. extended_charset = 0;
  137. }
  138. ;
  139. help_command(p_tree *p;)
  140. :
  141. [ HELP | '?' ]
  142. { *p = mknode(OP_HELP, (p_tree) 0); }
  143. [ name(&(*p)->t_args[0])?
  144. | '?' { (*p)->t_args[0] = mknode(OP_NAME, str2idf("help",0), (char *) 0); }
  145. ]
  146. ;
  147. run_command(p_tree *p;)
  148. :
  149. RUN { extended_charset = 1; }
  150. args(p) { *p = mknode(OP_RUN, *p);
  151. extended_charset = 0;
  152. }
  153. | RERUN { if (! run_command) {
  154. error("no run command given yet");
  155. }
  156. else *p = run_command;
  157. }
  158. ;
  159. stop_command(p_tree *p;)
  160. { p_tree whr = 0, cond = 0; }
  161. :
  162. STOP
  163. where(&whr)?
  164. condition(&cond)? { if (! whr && ! cond) {
  165. error("no position or condition");
  166. *p = 0;
  167. }
  168. else *p = mknode(OP_STOP, whr, cond);
  169. }
  170. ;
  171. trace_command(p_tree *p;)
  172. { p_tree whr = 0, cond = 0, exp = 0; }
  173. :
  174. TRACE
  175. [ ON expression(&exp, 0) ]?
  176. where(&whr)?
  177. condition(&cond)? { *p = mknode(OP_TRACE, whr, cond, exp); }
  178. ;
  179. continue_command(p_tree *p;)
  180. { long l; p_tree pos = 0; }
  181. :
  182. CONT
  183. [ INTEGER { l = tok.ival; }
  184. | { l = 1; }
  185. ]
  186. position(&pos)?
  187. { *p = mknode(OP_CONT, mknode(OP_INTEGER, l), pos); }
  188. ;
  189. when_command(p_tree *p;)
  190. { p_tree whr = 0, cond = 0; }
  191. :
  192. WHEN
  193. where(&whr)?
  194. condition(&cond)? { *p = mknode(OP_WHEN, whr, cond, (p_tree) 0);
  195. p = &(*p)->t_args[2];
  196. }
  197. '{'
  198. command_line(p)
  199. [ ';' { if (*p) {
  200. *p = mknode(OP_LINK, *p, (p_tree) 0);
  201. p = &((*p)->t_args[1]);
  202. }
  203. }
  204. command_line(p)
  205. ]*
  206. '}'
  207. { if (! whr && ! cond) {
  208. error("no position or condition");
  209. }
  210. else if (! *p) {
  211. error("no commands given");
  212. }
  213. }
  214. ;
  215. step_command(p_tree *p;)
  216. :
  217. STEP { *p = mknode(OP_STEP, (p_tree) 0); }
  218. count(&(*p)->t_args[0])?
  219. ;
  220. next_command(p_tree *p;)
  221. :
  222. NEXT { *p = mknode(OP_NEXT, (p_tree) 0); }
  223. count(&(*p)->t_args[0])?
  224. ;
  225. regs_command(p_tree *p;)
  226. :
  227. REGS { *p = mknode(OP_REGS, (p_tree) 0); }
  228. count(&(*p)->t_args[0])?
  229. ;
  230. delete_command(p_tree *p;)
  231. :
  232. DELETE count_list(p)? { *p = mknode(OP_DELETE, *p); }
  233. ;
  234. print_command(p_tree *p;)
  235. :
  236. PRINT
  237. [ format_expression_list(p)
  238. { *p = mknode(OP_PRINT, *p); }
  239. |
  240. { *p = mknode(OP_PRINT, (p_tree) 0); }
  241. ]
  242. ;
  243. display_command(p_tree *p;)
  244. :
  245. DISPLAY format_expression_list(p)
  246. { *p = mknode(OP_DISPLAY, *p); }
  247. ;
  248. format_expression_list(p_tree *p;)
  249. :
  250. format_expression(p)
  251. [ ',' { *p = mknode(OP_LINK, *p, (p_tree) 0);
  252. p = &((*p)->t_args[1]);
  253. }
  254. format_expression(p)
  255. ]*
  256. ;
  257. format_expression(p_tree *p;)
  258. { p_tree p1; }
  259. :
  260. expression(p, 0)
  261. [ '\\'
  262. [ name(&p1) { register char *c = p1->t_str;
  263. while (*c) {
  264. if (! strindex("doshcax", *c)) {
  265. error("illegal format: %c", *c);
  266. break;
  267. }
  268. c++;
  269. }
  270. *p = mknode(OP_FORMAT, *p, p1);
  271. }
  272. |
  273. ]
  274. |
  275. ]
  276. ;
  277. set_command(p_tree *p;)
  278. :
  279. SET expression(p, 0) { *p = mknode(OP_SET, *p, (p_tree) 0); }
  280. TO expression(&((*p)->t_args[1]), 0)
  281. ;
  282. able_command(p_tree *p;)
  283. :
  284. [ ENABLE { *p = mknode(OP_ENABLE, (p_tree) 0); }
  285. | DISABLE { *p = mknode(OP_DISABLE, (p_tree) 0); }
  286. ]
  287. count_list(&(*p)->t_args[0])?
  288. ;
  289. count_list(p_tree *p;)
  290. :
  291. count(p)
  292. [ ',' { *p = mknode(OP_LINK, *p, (p_tree) 0); }
  293. count(&(*p)->t_args[1])
  294. ]*
  295. ;
  296. condition(p_tree *p;)
  297. :
  298. IF expression(p, 0)
  299. ;
  300. where(p_tree *p;)
  301. :
  302. IN qualified_name(p) { *p = mknode(OP_IN, *p, (p_tree) 0); }
  303. position(&((*p)->t_args[1]))?
  304. |
  305. position(p)
  306. ;
  307. expression(p_tree *p; int level;)
  308. { int currprio, currop; }
  309. : { in_expression++; }
  310. factor(p)
  311. [ %while ((currprio = binprio(currop = (int) tok.ival)) > level)
  312. [ BIN_OP | PREF_OR_BIN_OP ]
  313. { *p = mknode(OP_BINOP, *p, (p_tree) 0);
  314. (*p)->t_whichoper = currop;
  315. }
  316. expression(&((*p)->t_args[1]), currprio)
  317. |
  318. SEL_OP { *p = mknode(OP_BINOP, *p, (p_tree) 0);
  319. (*p)->t_whichoper = (int) tok.ival;
  320. }
  321. name(&(*p)->t_args[1])
  322. |
  323. '[' { *p = mknode(OP_BINOP, *p, (p_tree) 0);
  324. (*p)->t_whichoper = E_ARRAY;
  325. }
  326. expression(&(*p)->t_args[1], 0)
  327. [ ',' { *p = mknode(OP_BINOP, *p, (p_tree) 0);
  328. (*p)->t_whichoper = E_ARRAY;
  329. }
  330. expression(&(*p)->t_args[1], 0)
  331. ]*
  332. ']'
  333. ]*
  334. { in_expression--; }
  335. ;
  336. factor(p_tree *p;)
  337. :
  338. [
  339. %default EXPRESSION /* lexical analyzer will never return this token */
  340. { *p = mknode(OP_INTEGER, 0L); }
  341. |
  342. '(' expression(p, 0) ')'
  343. |
  344. INTEGER { *p = mknode(OP_INTEGER, tok.ival); }
  345. |
  346. REAL { *p = mknode(OP_REAL, tok.fval); }
  347. |
  348. STRING { *p = mknode(OP_STRING, tok.str); }
  349. |
  350. qualified_name(p)
  351. |
  352. { *p = mknode(OP_UNOP, (p_tree) 0);
  353. (*p)->t_whichoper = (int) tok.ival;
  354. }
  355. [ PREF_OP
  356. | PREF_OR_BIN_OP
  357. { (*currlang->fix_bin_to_pref)(*p); }
  358. ]
  359. expression(&(*p)->t_args[0], unprio((*p)->t_whichoper))
  360. ]
  361. [ %while(1)
  362. POST_OP { *p = mknode(OP_UNOP, *p);
  363. (*p)->t_whichoper = (int) tok.ival;
  364. }
  365. ]*
  366. ;
  367. position(p_tree *p;)
  368. { p_tree lin;
  369. char *str;
  370. }
  371. :
  372. AT
  373. [ STRING { str = tok.str; }
  374. ':'
  375. | { if (! listfile) str = 0;
  376. else str = listfile->sy_idf->id_text;
  377. }
  378. ]
  379. count(&lin) { *p = mknode(OP_AT, lin->t_ival, str);
  380. freenode(lin);
  381. }
  382. ;
  383. args(p_tree *p;)
  384. { int first_time = 1; }
  385. :
  386. [ { if (! first_time) {
  387. *p = mknode(OP_LINK, *p, (p_tree) 0);
  388. p = &((*p)->t_args[1]);
  389. }
  390. first_time = 0;
  391. }
  392. arg(p)
  393. ]*
  394. ;
  395. arg(p_tree *p;)
  396. :
  397. name(p)
  398. |
  399. '>' name(p) { (*p)->t_oper = OP_OUTPUT; }
  400. |
  401. '<' name(p) { (*p)->t_oper = OP_INPUT; }
  402. ;
  403. count(p_tree *p;)
  404. :
  405. INTEGER { *p = mknode(OP_INTEGER, tok.ival); }
  406. ;
  407. qualified_name(p_tree *p;)
  408. :
  409. name(p)
  410. [ '`' { *p = mknode(OP_SELECT, *p, (p_tree) 0); }
  411. name(&((*p)->t_args[1]))
  412. ]*
  413. ;
  414. name(p_tree *p;)
  415. :
  416. [ XFILE
  417. | LIST
  418. | RUN
  419. | RERUN
  420. | STOP
  421. | WHEN
  422. | AT
  423. | IN
  424. | IF
  425. | %default NAME
  426. | CONT
  427. | STEP
  428. | NEXT
  429. | REGS
  430. | WHERE
  431. | STATUS
  432. | PRINT
  433. | DELETE
  434. | DUMP
  435. | RESTORE
  436. | TRACE
  437. | ON
  438. | SET
  439. | TO
  440. | FIND
  441. | DISPLAY
  442. | WHICH
  443. | HELP
  444. | DISABLE
  445. | ENABLE
  446. ] { *p = mknode(OP_NAME, tok.idf, tok.str); }
  447. ;
  448. {
  449. int
  450. LLlex()
  451. {
  452. register int c;
  453. if (ASIDE) {
  454. tok = aside;
  455. ASIDE = 0;
  456. return TOK;
  457. }
  458. do {
  459. c = getc(db_in);
  460. } while (c != EOF && class(c) == STSKIP);
  461. if (c == EOF) {
  462. eof_seen = 1;
  463. return c;
  464. }
  465. if (extended_charset && in_ext(c)) {
  466. TOK = get_name(c);
  467. return TOK;
  468. }
  469. switch(class(c)) {
  470. case STSTR:
  471. TOK = (*currlang->get_string)(c);
  472. break;
  473. case STIDF:
  474. if (in_expression) TOK = (*currlang->get_name)(c);
  475. else TOK = get_name(c);
  476. break;
  477. case STNUM:
  478. TOK = (*currlang->get_number)(c);
  479. break;
  480. case STNL:
  481. TOK = c;
  482. break;
  483. case STSIMP:
  484. if (! in_expression) {
  485. TOK = c;
  486. break;
  487. }
  488. /* Fall through */
  489. default:
  490. TOK = (*currlang->get_token)(c);
  491. break;
  492. }
  493. return TOK;
  494. }
  495. int
  496. get_name(c)
  497. register int c;
  498. {
  499. char buf[512+1];
  500. register char *p = &buf[0];
  501. register struct idf *id;
  502. do {
  503. if (p - buf < 512) *p++ = c;
  504. c = getc(db_in);
  505. } while ((extended_charset && in_ext(c)) || in_idf(c));
  506. ungetc(c, db_in);
  507. *p++ = 0;
  508. if (extended_charset) {
  509. tok.idf = 0;
  510. tok.str = Salloc(buf, (unsigned) (p - buf));
  511. return NAME;
  512. }
  513. id = str2idf(buf, 1);
  514. tok.idf = id;
  515. tok.str = id->id_text;
  516. return id->id_reserved ? id->id_reserved : NAME;
  517. }
  518. extern char * symbol2str();
  519. LLmessage(t)
  520. {
  521. if (t > 0) {
  522. if (! errorgiven) {
  523. error("%s missing before %s", symbol2str(t), symbol2str(TOK));
  524. }
  525. aside = tok;
  526. }
  527. else if (t == 0) {
  528. if (! errorgiven) {
  529. error("%s unexpected", symbol2str(TOK));
  530. }
  531. }
  532. else if (! errorgiven) {
  533. error("EOF expected");
  534. }
  535. errorgiven = 1;
  536. }
  537. static int
  538. catch_del()
  539. {
  540. signal(SIGINT, catch_del);
  541. if (! disable_intr) {
  542. signal_child(SIGEMT);
  543. child_interrupted = 1;
  544. }
  545. interrupted = 1;
  546. }
  547. int
  548. init_del()
  549. {
  550. signal(SIGINT, catch_del);
  551. }
  552. }