123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616 |
- /* LLgen generated code from source tokens.g */
- #include "Lpars.h"
- #define LL_LEXI scanner
- #define LLNOFIRSTS
- #if __STDC__ || __cplusplus
- #define LL_ANSI_C 1
- #endif
- #define LL_LEXI scanner
- /* $Id$ */
- #ifdef LL_DEBUG
- #include <assert.h>
- #include <stdio.h>
- #define LL_assert(x) assert(x)
- #else
- #define LL_assert(x) /* nothing */
- #endif
- extern int LLsymb;
- #define LL_SAFE(x) /* Nothing */
- #define LL_SSCANDONE(x) if (LLsymb != x) LLsafeerror(x)
- #define LL_SCANDONE(x) if (LLsymb != x) LLerror(x)
- #define LL_NOSCANDONE(x) LLscan(x)
- #ifdef LL_FASTER
- #define LLscan(x) if ((LLsymb = LL_LEXI()) != x) LLerror(x)
- #endif
- extern unsigned int LLscnt[];
- extern unsigned int LLtcnt[];
- extern int LLcsymb;
- #if LL_NON_CORR
- extern int LLstartsymb;
- #endif
- #define LLsdecr(d) {LL_assert(LLscnt[d] > 0); LLscnt[d]--;}
- #define LLtdecr(d) {LL_assert(LLtcnt[d] > 0); LLtcnt[d]--;}
- #define LLsincr(d) LLscnt[d]++
- #define LLtincr(d) LLtcnt[d]++
- #if LL_ANSI_C
- extern int LL_LEXI(void);
- extern void LLread(void);
- extern int LLskip(void);
- extern int LLnext(int);
- extern void LLerror(int);
- extern void LLsafeerror(int);
- extern void LLnewlevel(unsigned int *);
- extern void LLoldlevel(unsigned int *);
- #ifndef LL_FASTER
- extern void LLscan(int);
- #endif
- #ifndef LLNOFIRSTS
- extern int LLfirst(int, int);
- #endif
- #if LL_NON_CORR
- extern void LLnc_recover(void);
- #endif
- #else /* not LL_ANSI_C */
- extern LLread();
- extern int LLskip();
- extern int LLnext();
- extern LLerror();
- extern LLsafeerror();
- extern LLnewlevel();
- extern LLoldlevel();
- #ifndef LL_FASTER
- extern LLscan();
- #endif
- #ifndef LLNOFIRSTS
- extern int LLfirst();
- #endif
- #if LL_NON_CORR
- extern LLnc_recover();
- #endif
- #endif /* not LL_ANSI_C */
- # line 20 "tokens.g"
- #include <stdio.h>
- #include <string.h>
- # include "types.h"
- # include "io.h"
- # include "extern.h"
- # include "assert.h"
- # include "cclass.h"
- #include "LLgen.h"
- static int nparams;
- # line 63 "tokens.g"
- /*
- * Structure for a keyword
- */
- typedef struct keyword {
- string w_word;
- int w_value;
- } t_keyw, *p_keyw;
- /*
- * The list of keywords, the most often used keywords come first.
- * Linear search is used, as there are not many keywords
- */
- static t_keyw resword[] = {
- { "token", C_TOKEN },
- { "avoid", C_AVOID },
- { "prefer", C_PREFER },
- { "persistent", C_PERSISTENT },
- { "default", C_DEFAULT },
- { "if", C_IF },
- { "while", C_WHILE },
- { "first", C_FIRST },
- { "start", C_START },
- { "lexical", C_LEXICAL },
- { "onerror", C_ONERROR },
- { "prefix", C_PREFIX },
- #ifdef NON_CORRECTING
- { "substart", C_SUBSTART },
- { "erroneous", C_ERRONEOUS },
- { "illegal", C_ILLEGAL },
- #endif
- { 0, 0 }
- };
- static t_token savedtok; /* to save lextoken in case of an insertion */
- # ifdef LINE_DIRECTIVE
- static int nostartline; /* = 0 if at the start of a line */
- # endif
- STATIC void copyact(char ch1, char ch2, int flag, int level) {
- /*
- * Copy an action to file f. Opening bracket is ch1, closing bracket
- * is ch2.
- * If flag & 1, copy opening and closing parameters too.
- * If flag & 2, don't allow ','.
- */
- static int text_seen = 0;
- register FILE *f;
- register ch; /* Current char */
- register match; /* used to read strings */
- int saved = linecount;
- /* save linecount */
- int sav_strip = strip_grammar;
- f = fact;
- if (ch1 == '{' || flag != 1) strip_grammar = 0;
- if (!level) {
- text_seen = 0;
- nparams = 0; /* count comma's */
- putc('\0',f);
- fprintf(f,"# line %d \"%s\"\n", linecount,f_input);
- }
- if (level || (flag & 1)) putc(ch1,f);
- for (;;) {
- ch = input();
- if (ch == ch2) {
- if (!level) {
- if (text_seen) nparams++;
- }
- if (level || (flag & 1)) putc(ch,f);
- if (strip_grammar != sav_strip) {
- if (ch1 == '{' || flag != 1) putchar(ch);
- }
- strip_grammar = sav_strip;
- return;
- }
- switch(ch) {
- case ')':
- case '}':
- case ']':
- error(linecount,"Parentheses mismatch", NULL, NULL);
- break;
- case '(':
- text_seen = 1;
- copyact('(',')',flag,level+1);
- continue;
- case '{':
- text_seen = 1;
- copyact('{','}',flag,level+1);
- continue;
- case '[':
- text_seen = 1;
- copyact('[',']',flag,level+1);
- continue;
- case '/':
- ch = input();
- unput(ch);
- if (ch == '*') {
- putc('/', f);
- skipcomment(1);
- continue;
- }
- ch = '/';
- text_seen = 1;
- break;
- case ';':
- case ',':
- if (! level && text_seen) {
- text_seen = 0;
- nparams++;
- if (ch == ',' && (flag & 2)) {
- warning(linecount, "Parameters may not be separated with a ','", NULL, NULL);
- ch = ';';
- }
- }
- break;
- case '\'':
- case '"' :
- /*
- * watch out for brackets in strings, they do not
- * count !
- */
- text_seen = 1;
- match = ch;
- putc(ch,f);
- while((ch = input())) {
- if (ch == match) break;
- if (ch == '\\') {
- putc(ch,f);
- ch = input();
- }
- if (ch == '\n') {
- error(linecount,"Newline in string", NULL, NULL);
- unput(match);
- }
- putc(ch,f);
- }
- if (ch == match) break;
- /* Fall through */
- case EOF :
- if (!level) error(saved,"Action does not terminate", NULL, NULL);
- strip_grammar = sav_strip;
- return;
- default:
- if (c_class[ch] != ISSPA) text_seen = 1;
- }
- putc(ch,f);
- }
- }
- int scanner() {
- /*
- * Lexical analyser, what else
- */
- register int ch; /* Current char */
- register char *p = ltext;
- int reserved = 0; /* reserved word? */
- char *max = <ext[LTEXTSZ - 1];
- static int nextexpr;
- int expect_expr = nextexpr;
- long off;
- nextexpr = 0;
- if (savedtok.t_tokno) {
- /* A token has been inserted.
- * Now deliver the last lextoken again
- */
- lextoken = savedtok;
- savedtok.t_tokno = 0;
- return lextoken.t_tokno;
- }
- for (;;) {
- ch = input();
- if (ch == EOF) return ch;
- # ifdef LINE_DIRECTIVE
- if (ch == '#' && !nostartline) {
- linedirective();
- continue;
- }
- # endif
- switch(c_class[ch]) {
- case ISACT :
- if (ch == '{') {
- copyact('{', '}', in_production, 0);
- return C_ACTION;
- }
- assert(ch == '(');
- if (expect_expr) {
- copyact('(', ')', 1, 0);
- return C_EXPR;
- }
- off = ftell(fact);
- copyact('(', ')', in_production != 0 ? 0 : 2, 0);
- if (nparams == 0) fseek(fact, off, 0);
- lextoken.t_num = nparams;
- return C_PARAMS;
- case ISLIT :
- for (;;) {
- ch = input();
- if (ch == '\n' || ch == EOF) {
- error(linecount,"Missing '", NULL, NULL);
- break;
- }
- if (ch == '\'') break;
- if (ch == '\\') {
- *p++ = ch;
- ch = input();
- }
- *p++ = ch;
- if (p > max) p--;
- }
- *p = '\0';
- lextoken.t_string = ltext;
- return C_LITERAL;
- case ISCOM :
- skipcomment(0);
- /* Fall through */
- case ISSPA :
- continue;
- case ISDIG : {
- register i = 0;
- do {
- i = 10 * i + (ch - '0');
- ch= input();
- } while (c_class[ch] == ISDIG);
- lextoken.t_num = i;
- unput(ch);
- return C_NUMBER; }
- default:
- return ch;
- case ISKEY :
- reserved = 1;
- ch = input();
- /* Fall through */
- case ISLET :
- do {
- if (reserved && ch >= 'A' && ch <= 'Z') {
- ch += 'a' - 'A';
- }
- *p++ = ch;
- if (p > max) p--;
- ch = input();
- } while (c_class[ch] == ISDIG || c_class[ch] == ISLET);
- unput(ch);
- *p = '\0';
- if (reserved) { /*
- * Now search for the keyword
- */
- register p_keyw w;
- w = resword;
- while (w->w_word) {
- if (! strcmp(ltext,w->w_word)) {
- /*
- * Return token number.
- */
- if (w->w_value == C_IF ||
- w->w_value == C_WHILE) {
- nextexpr = 1;
- }
- return w->w_value;
- }
- w++;
- }
- error(linecount,"Illegal reserved word", NULL, NULL);
- }
- lextoken.t_string = ltext;
- return C_IDENT;
- }
- }
- }
- static int backupc; /* for unput() */
- static int nonline; /* = 1 if last char read was a newline */
- int input() {
- /*
- * Low level input routine, used by all other input routines
- */
- int c;
- if ((c = backupc)) {
- /* Last char was "unput()". Deliver it again
- */
- backupc = 0;
- return c;
- }
- if ((c = getc(finput)) == EOF) {
- nonline = 0;
- return c;
- }
- # ifdef LINE_DIRECTIVE
- nostartline = 1;
- # endif
- if (!nonline) {
- linecount++;
- # ifdef LINE_DIRECTIVE
- nostartline = 0;
- # endif
- nonline = 1;
- }
- if (c == '\n') nonline = 0;
- if (strip_grammar) putchar(c);
- return c;
- }
- void unput(c) {
- /*
- * "unread" c
- */
- backupc = c;
- }
- void skipcomment(flag) {
- /*
- * Skip comment. If flag != 0, the comment is inside a fragment
- * of C-code, so keep it.
- */
- register int ch;
- int saved; /* line count on which comment starts */
- saved = linecount;
- if (input() != '*') error(linecount,"Illegal comment", NULL, NULL);
- if (flag) putc('*', fact);
- do {
- ch = input();
- if (flag) putc(ch, fact);
- while (ch == '*') {
- ch = input();
- if (flag) putc(ch, fact);
- if (ch == '/') return;
- }
- } while (ch != EOF);
- error(saved,"Comment does not terminate", NULL, NULL);
- }
- # ifdef LINE_DIRECTIVE
- STATIC void linedirective() {
- /*
- * Read a line directive
- */
- register int ch;
- register int i;
- string s_error = "Illegal line directive";
- string store();
- register string c;
- do { /*
- * Skip to next digit
- * Do not skip newlines
- */
- ch = input();
- } while (ch != '\n' && c_class[ch] != ISDIG);
- if (ch == '\n') {
- error(linecount,s_error, NULL, NULL);
- return;
- }
- i = 0;
- do {
- i = i*10 + (ch - '0');
- ch = input();
- } while (c_class[ch] == ISDIG);
- while (ch != '\n' && ch != '"') ch = input();
- if (ch == '"') {
- c = ltext;
- do {
- *c++ = ch = input();
- } while (ch != '"' && ch != '\n');
- if (ch == '\n') {
- error(linecount,s_error, NULL, NULL);
- return;
- }
- *--c = '\0';
- do {
- ch = input();
- } while (ch != '\n');
- /*
- * Remember the file name
- */
- if (strcmp(f_input,ltext)) f_input = store(ltext);
- }
- linecount = i;
- }
- # endif
- STATIC string vallookup(s) {
- /*
- * Look up the keyword that has token number s
- */
- register p_keyw p = resword;
- while (p->w_value) {
- if (p->w_value == s) return p->w_word;
- p++;
- }
- return 0;
- }
- STATIC string cpy(int s,string p, int inserted) {
- /*
- * Create a piece of error message for token s and put it at p.
- * inserted = 0 if the token s was deleted (in which case we have
- * attributes), else it was inserted
- */
- register string t = 0;
- switch(s) {
- case C_IDENT :
- if (!inserted) t = lextoken.t_string;
- else t = "identifier";
- break;
- case C_NUMBER :
- t = "number";
- break;
- case C_LITERAL :
- if (!inserted) {
- *p++ = '\'';
- t = lextoken.t_string;
- break;
- }
- t = "literal";
- break;
- case C_ACTION:
- t = "C action";
- break;
- case C_PARAMS:
- t = "C parameter section";
- break;
- case C_EXPR:
- t = "C expression";
- break;
- case EOFILE :
- t = "end-of-file";
- break;
- }
- if (!t && (t = vallookup(s))) {
- *p++ = '%';
- }
- if (t) { /*
- * We have a string for the token. Copy it
- */
- while (*t) *p++ = *t++;
- if (s == C_LITERAL && !inserted) {
- *p++ = '\'';
- }
- return p;
- }
- /*
- * The token is a literal
- */
- *p++ = '\'';
- if (s >= 040 && s <= 0176) *p++ = s;
- else {
- *p++ = '\\';
- switch(s) {
- case '\b' : *p++ = 'b'; break;
- case '\f' : *p++ = 'f'; break;
- case '\n' : *p++ = 'n'; break;
- case '\r' : *p++ = 'r'; break;
- case '\t' : *p++ = 't'; break;
- default : *p++='0'+((s&0377)>>6); *p++='0'+((s>>3)&07);
- *p++='0'+(s&07);
- }
- }
- *p++ = '\'';
- return p;
- }
- void LLmessage(int d) {
- /*
- * d is either 0, in which case the current token has been deleted,
- * or non-zero, in which case it represents a token that is inserted
- * before the current token
- */
- register string s,t;
- char buf[128];
- nerrors++;
- s = buf;
- if (d < 0) {
- strcpy(buf, "end-of-file expected");
- }
- else if (d == 0) {
- #ifdef LLNONCORR
- t = " unexpected";
- #else
- t = " deleted";
- #endif
- s = cpy(LLsymb,s,0);
- do *s++ = *t; while (*t++);
- } else {
- s = cpy(d,s,1);
- t = " inserted in front of ";
- do *s++ = *t++; while (*t);
- s = cpy(LLsymb,s,0);
- *s = '\0';
- }
- if (d > 0) { /*
- * Save the current token and make up some
- * attributes for the inserted token
- */
- savedtok = lextoken;
- savedtok.t_tokno = LLsymb;
- if (d == C_IDENT) lextoken.t_string = "dummy_identifier";
- else if (d == C_LITERAL) lextoken.t_string = "dummy_literal";
- else if (d == C_NUMBER) lextoken.t_num = 1;
- }
- #ifdef LLNONCORR
- else
- #endif
- error(linecount, "%s", buf, NULL);
- /* Don't change this line to
- * error(linecount, buf).
- * The string in "buf" might contain '%' ...
- */
- #ifdef LLNONCORR
- in_production = 1;
- /* To prevent warnings from copyact */
- #endif
- }
|