123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590 |
- /* $Header$ */
- /* Command grammar */
- {
- #include <stdio.h>
- #include <alloc.h>
- #include <setjmp.h>
- #include <signal.h>
- #include "ops.h"
- #include "class.h"
- #include "position.h"
- #include "file.h"
- #include "idf.h"
- #include "symbol.h"
- #include "tree.h"
- extern char *Salloc();
- extern t_lineno currline;
- extern FILE *db_in;
- int errorgiven;
- int extended_charset = 0;
- jmp_buf jmpbuf;
- static int init_del();
- static int skip_to_eol();
- static struct token {
- int tokno;
- long ival;
- char *str;
- double fval;
- struct idf *idf;
- } tok, aside;
- #define TOK tok.tokno
- #define ASIDE aside.tokno
- }
- %start Commands, commands;
- %lexical LLlex;
- commands
- { p_tree com, lastcom = 0;
- }
- :
- { if (! setjmp(jmpbuf)) {
- init_del();
- }
- else {
- skip_to_eol();
- goto prmpt;
- }
- }
- [ %persistent command_line(&com)
- { if (com) {
- if (errorgiven) {
- freenode(com);
- com = 0;
- }
- if (lastcom && !in_status(lastcom) &&
- lastcom != run_command) {
- freenode(lastcom);
- lastcom = 0;
- }
- if (com) {
- if (repeatable(com)) {
- lastcom = com;
- }
- eval(com);
- if (! repeatable(com) &&
- ! in_status(com) &&
- com != run_command) {
- freenode(com);
- }
- }
- } else if (lastcom && ! errorgiven) eval(lastcom);
- }
- [ '\n' { prmpt: prompt(); }
- | ';'
- ] { errorgiven = 0; }
- ]*
- { signal_child(SIGKILL); }
- ;
- command_line(p_tree *p;)
- :
- list_command(p)
- | file_command(p)
- | run_command(p)
- | stop_command(p)
- | when_command(p)
- | continue_command(p)
- | step_command(p)
- | next_command(p)
- | regs_command(p)
- | WHERE { *p = mknode(OP_WHERE); }
- | STATUS { *p = mknode(OP_STATUS); }
- | DUMP { *p = mknode(OP_DUMP); }
- | RESTORE INTEGER { *p = mknode(OP_RESTORE, tok.ival); }
- | delete_command(p)
- | print_command(p)
- | trace_command(p)
- | { *p = 0; }
- ;
- list_command(p_tree *p;)
- { p_tree t1 = 0, t2 = 0; }
- :
- LIST
- [
- | lin_num(&t1)
- [ ',' lin_num(&t2)
- | { t2 = mknode(OP_INTEGER, t1->t_ival); }
- ]
- ] { *p = mknode(OP_LIST, t1, t2); }
- ;
- file_command(p_tree *p;)
- :
- XFILE { extended_charset = 1; }
- [ { *p = 0; }
- | name(p) { (*p)->t_idf = str2idf((*p)->t_str, 0); }
- ] { *p = mknode(OP_FILE, *p);
- extended_charset = 0;
- }
- ;
- run_command(p_tree *p;)
- :
- RUN { extended_charset = 1; *p = 0; }
- args(p) { *p = mknode(OP_RUN, *p);
- extended_charset = 0;
- freenode(run_command);
- run_command = *p;
- }
- | RERUN { if (! run_command) {
- error("no run command given yet");
- }
- else *p = run_command;
- }
- ;
- stop_command(p_tree *p;)
- { p_tree whr = 0, cond = 0; }
- :
- STOP
- where(&whr)?
- condition(&cond)? { if (! whr && ! cond) {
- error("no position or condition");
- *p = 0;
- }
- else *p = mknode(OP_STOP, whr, cond);
- }
- ;
- trace_command(p_tree *p;)
- { p_tree whr = 0, cond = 0, exp = 0; }
- :
- TRACE
- [ ON expression(&exp) ]?
- where(&whr)?
- condition(&cond)? { *p = mknode(OP_TRACE, whr, cond, exp); }
- ;
- continue_command(p_tree *p;)
- { long l; p_tree pos = 0; }
- :
- CONT
- [ INTEGER { l = tok.ival; }
- | { l = 1; }
- ]
- position(&pos)?
- { *p = mknode(OP_CONT, mknode(OP_INTEGER, l), pos); }
- ;
- when_command(p_tree *p;)
- { p_tree whr = 0, cond = 0; }
- :
- WHEN
- where(&whr)?
- condition(&cond)?
- '{'
- command_line(p)
- [ ';' { *p = mknode(OP_LINK, *p, (p_tree) 0);
- p = &((*p)->t_args[1]);
- }
- command_line(p)
- ]*
- '}'
- { if (! whr && ! cond) {
- error("no position or condition");
- freenode(*p);
- *p = 0;
- }
- else *p = mknode(OP_WHEN, whr, cond, *p);
- }
- ;
- step_command(p_tree *p;)
- { long l; }
- :
- STEP
- [ INTEGER { l = tok.ival; }
- | { l = 1; }
- ] { *p = mknode(OP_STEP, l); }
- ;
- next_command(p_tree *p;)
- { long l; }
- :
- NEXT
- [ INTEGER { l = tok.ival; }
- | { l = 1; }
- ] { *p = mknode(OP_NEXT, l); }
- ;
- regs_command(p_tree *p;)
- { long l; }
- :
- REGS
- [ INTEGER { l = tok.ival; }
- | { l = 0; }
- ] { *p = mknode(OP_REGS, l); }
- ;
- delete_command(p_tree *p;)
- :
- DELETE
- INTEGER { *p = mknode(OP_DELETE, tok.ival); }
- ;
- print_command(p_tree *p;)
- :
- PRINT expression(p) { *p = mknode(OP_PRINT, *p);
- p = &((*p)->t_args[0]);
- }
- [ ',' { *p = mknode(OP_LINK, *p, (p_tree) 0);
- p = &((*p)->t_args[1]);
- }
- expression(p)
- ]*
- ;
- condition(p_tree *p;)
- :
- IF expression(p)
- ;
- where(p_tree *p;)
- :
- IN qualified_name(p) { *p = mknode(OP_IN, *p); }
- |
- position(p)
- ;
- expression(p_tree *p;)
- :
- qualified_name(p)
- ;
- position(p_tree *p;)
- { p_tree lin;
- char *str;
- }
- :
- AT
- [ STRING { str = tok.str; }
- ':'
- | { if (! currfile) str = 0;
- else str = currfile->sy_idf->id_text;
- }
- ]
- lin_num(&lin) { *p = mknode(OP_AT, lin->t_ival, str);
- freenode(lin);
- }
- ;
- args(p_tree *p;)
- { int first_time = 1; }
- :
- [ { if (! first_time) {
- *p = mknode(OP_LINK, *p, (p_tree) 0);
- p = &((*p)->t_args[1]);
- }
- first_time = 0;
- }
- arg(p)
- ]*
- ;
- arg(p_tree *p;)
- :
- name(p)
- |
- '>' name(p) { (*p)->t_oper = OP_OUTPUT; }
- |
- '<' name(p) { (*p)->t_oper = OP_INPUT; }
- ;
- lin_num(p_tree *p;)
- :
- INTEGER { *p = mknode(OP_INTEGER, tok.ival); }
- ;
- qualified_name(p_tree *p;)
- :
- name(p)
- [ '`' { *p = mknode(OP_SELECT, *p, (p_tree) 0); }
- name(&((*p)->t_args[1]))
- ]*
- ;
- name(p_tree *p;)
- :
- [ XFILE
- | LIST
- | RUN
- | RERUN
- | STOP
- | WHEN
- | AT
- | IN
- | IF
- | NAME
- | CONT
- | STEP
- | NEXT
- | REGS
- | WHERE
- | STATUS
- | PRINT
- | DELETE
- | DUMP
- | RESTORE
- | TRACE
- | ON
- ] { *p = mknode(OP_NAME, tok.idf, tok.str); }
- ;
- {
- int
- LLlex()
- {
- register int c;
- if (ASIDE) {
- tok = aside;
- ASIDE = 0;
- return TOK;
- }
- do {
- c = getc(db_in);
- } while (c != EOF && class(c) == STSKIP);
- if (c == EOF) return c;
- switch(class(c)) {
- case STSTR:
- TOK = get_string(c);
- break;
- case STIDF:
- TOK = get_name(c);
- break;
- case STDOT:
- c = getc(db_in);
- if (c == EOF || class(c) != STNUM) {
- ungetc(c,db_in);
- TOK = '.';
- break;
- }
- /* Fall through */
- case STNUM:
- TOK = get_number(c);
- break;
- case STNL:
- case STSIMP:
- TOK = c;
- break;
- default:
- error("illegal character '\\0%o'", c);
- return LLlex();
- }
- return TOK;
- }
- int
- get_name(c)
- register int c;
- {
- char buf[512+1];
- register char *p = &buf[0];
- register struct idf *id;
- do {
- if (p - buf < 512) *p++ = c;
- c = getc(db_in);
- } while ((extended_charset && in_ext(c)) || in_idf(c));
- ungetc(c, db_in);
- *p = 0;
- if (extended_charset) {
- tok.idf = 0;
- tok.str = Salloc(buf, (unsigned) (p - buf));
- return NAME;
- }
- id = str2idf(buf, 1);
- tok.idf = id;
- tok.str = id->id_text;
- return id->id_reserved ? id->id_reserved : NAME;
- }
- static int
- quoted(ch)
- int ch;
- {
- /* quoted() replaces an escaped character sequence by the
- character meant.
- */
- /* first char after backslash already in ch */
- if (!is_oct(ch)) { /* a quoted char */
- switch (ch) {
- case 'n':
- ch = '\n';
- break;
- case 't':
- ch = '\t';
- break;
- case 'b':
- ch = '\b';
- break;
- case 'r':
- ch = '\r';
- break;
- case 'f':
- ch = '\f';
- break;
- }
- }
- else { /* a quoted octal */
- register int oct = 0, cnt = 0;
- do {
- oct = oct*8 + (ch-'0');
- ch = getc(db_in);
- } while (is_oct(ch) && ++cnt < 3);
- ungetc(ch, db_in);
- ch = oct;
- }
- return ch&0377;
- }
- int get_string(c)
- int c;
- {
- register int ch;
- char buf[512];
- register int len = 0;
- while (ch = getc(db_in), ch != c) {
- if (ch == '\n') {
- error("newline in string");
- break;
- }
- if (ch == '\\') {
- ch = getc(db_in);
- ch = quoted(ch);
- }
- buf[len++] = ch;
- }
- buf[len++] = 0;
- tok.str = Salloc(buf, (unsigned) len);
- return STRING;
- }
- static int
- val_in_base(c, base)
- register int c;
- {
- return is_dig(c)
- ? c - '0'
- : base != 16
- ? -1
- : is_hex(c)
- ? (c - 'a' + 10) & 017
- : -1;
- }
- int
- get_number(c)
- register int c;
- {
- char buf[512+1];
- register int base = 10;
- register char *p = &buf[0];
- register long val = 0;
- register int val_c;
- if (c == '0') {
- /* check if next char is an 'x' or an 'X' */
- c = getc(db_in);
- if (c == 'x' || c == 'X') {
- base = 16;
- c = getc(db_in);
- }
- else base = 8;
- }
- while (val_c = val_in_base(c, base), val_c >= 0) {
- val = val * base + val_c;
- if (p - buf < 512) *p++ = c;
- c = getc(db_in);
- }
- if (base == 16 || !((c == '.' || c == 'e' || c == 'E'))) {
- ungetc(c, db_in);
- tok.ival = val;
- return INTEGER;
- }
- if (c == '.') {
- if (p - buf < 512) *p++ = c;
- c = getc(db_in);
- }
- while (is_dig(c)) {
- if (p - buf < 512) *p++ = c;
- c = getc(db_in);
- }
- if (c == 'e' || c == 'E') {
- if (p - buf < 512) *p++ = c;
- c = getc(db_in);
- if (c == '+' || c == '-') {
- if (p - buf < 512) *p++ = c;
- c = getc(db_in);
- }
- if (! is_dig(c)) {
- error("malformed floating constant");
- }
- while (is_dig(c)) {
- if (p - buf < 512) *p++ = c;
- c = getc(db_in);
- }
- }
- ungetc(c, db_in);
- *p++ = 0;
- if (p == &buf[512+1]) {
- error("floating point constant too long");
- }
- return REAL;
- }
- extern char * symbol2str();
- LLmessage(t)
- {
- if (t > 0) {
- if (! errorgiven) {
- error("%s missing before %s", symbol2str(t), symbol2str(TOK));
- }
- aside = tok;
- }
- else if (t == 0) {
- if (! errorgiven) {
- error("%s unexpected", symbol2str(TOK));
- }
- }
- else if (! errorgiven) {
- error("EOF expected");
- }
- errorgiven = 1;
- }
- static int
- catch_del()
- {
- signal(SIGINT, catch_del);
- signal_child(SIGEMT);
- longjmp(jmpbuf, 1);
- }
- static int
- init_del()
- {
- signal(SIGINT, catch_del);
- }
- static int
- skip_to_eol()
- {
- while (TOK != '\n' && TOK > 0) LLlex();
- wait_for_child("interrupted");
- }
- }
|