#ifndef _cparser_H_ #define _cparser_H_ /* parser.ch: headers for parser class */ /* Copyright Carnegie Mellon University 1992, 1994 - All rights reserved $Disclaimer: $ */ #ifndef NULL #define NULL 0 #endif /* a semantic action routine is the C code in braces, {...}, in grammar rules. Actions may terminate with the special macros defined here. parser_CLEARIN and parser_ERROROK have meaning primarily in rules whose right hand sides begin with the special token 'error' The other macros are useful only on rare occasions. */ #define parser_ACCEPT { return 1;} /* parse succeeds immediately */ #define parser_ABORT { return 2;} /* parse fails immediately */ #define parser_ERROR { return 3;} /* initiate syntax error. The parser will NOT generate a message in this case */ #define parser_CLEARIN {return 4;} /* discard the currently pending token */ #define parser_ERROROK {return 5;} /* leave error state */ #define parser_CLINEROK {return 6;} /* discard token; leave error state */ #define parser_CLINERR {return 7;} /* discard token; enter error state */ /* The following are values that may be returned by parser_Parse. They may also be passed as the severity argument to the Error method. After issuing a parser_FATAL error, the action routine must still conclude with parser_ABORT to terminate. After issuing a parser_SYNTAX error, the action routine should usually conclude with parser_ERROR to initiate syntax error recovery. */ #define parser_OK 0 /* parsed successfully */ #define parser_WARNING 21 /* processing continues */ #define parser_SERIOUS 22 /* compile ceases, but continue error check */ #define parser_SYNTAX 23 /* like parser_SERIOUS, but was syntax error */ #define parser_FATAL 24 /* cannot even continue error checking */ /* the value parser_FREEMSG is or'ed with the severity value to indicate that the error processor is responsible for freeing the message The message will be freed by the default error handler; otherwise, the error handler must arrange to do so */ #define parser_FREEMSG (1<<15) typedef int (*parser_lexerfptr)(/* void *lexrock, void *yylval */); typedef void (*parser_enumresfptr)(/* void *rock, char *word, int tokennumber */); typedef void (*parser_killfptr)(/* class parser *self, void *vsp */); typedef void (*parser_errfptr)(/* class parser *p, int severity, char *sevname, char *msg */); typedef int (*parser_semfptr)(/* int i, void *pyyval, void *yyvsp, class parser *parser */); /* parser_tables store values generated by the parser generator */ struct parser_tables { short num_tokens; /* number of terminal symbols */ short num_nt; /* number of nonterminals */ short max_user_token; /* max of old-style token numbers */ short num_rules; /* number of rules in the grammar */ short num_states; /* number of states in parser */ short final_state; /* state number of the termination state */ short eltsz; /* sizeof(YYSTYPE) */ short defflag; /* value in actx and nextx indicating to use defred and defgoto, respectively */ short table_max; /* index of highest entry in table and valid */ char **names; /* names[i] is text of i'th token or non-terminal tokens occupy the first num_tokens locations non-terminals occupy the subsequent num_nt locations tokens may be: identifiers - all letters an identifier represents either a reserved word or a token class (by convention, a class name begins 'set'. An initial 'tok' in an identifier is ignored as in tokNULL for the reserved word NULL) character literals - 'x' string literals - "xxx" $ or $illegal. - internal to parser The lexical analyzer must report tokens by their index in 'names'. And must report EOF as token 0. */ char *translate; /* newstyle token number for each oldstyle token number. The translation is: given below under TranslateTokenNumber */ /* the grammar */ short *lhs; /* lhs[r] is symbol on left of rule r */ short *rhsx; /* rhsx[r] is index into rhs for rule r */ short *rhssz; /* rhssz[r] counts symbols on the right of rule r */ short *rhs; /* right sides of all rules */ /* parser control */ short *table; /* various stuff, see below */ short *valid; /* bounds check for table, see below */ short *defred; /* defred[s] is default reduction in state s */ short *actx; /* in state s for lookahead token i if actx[s] == defflag, use defred[s] as rule to reduce by if valid[actx[s]+i] == i action from table[actx[s] + i]: +n: shift: stack state n & token value; enter state n -n: reduce by rule n 0: reduce by rule defred[s] else reduce by rule defred[s] ** error ** if defred[s] is zero */ short *defnext; /* defnext[i] is the default successor state after reducing a rule with lhs == ntokens+i */ short *nextx; /* after removing rhs items from stack and reducing to a rule with lhs non-terminal having value i+ntokens, the subsequent top state is s if nextx[i] == defflag then use defnext[i] as new state else if (valid[s+nextx[i]]) == s then new state is table[s+nextx[i]] otherwise, new state is defnext[i] */ parser_semfptr actions; }; extern int parser_Parse(/* struct parser *self, parser_lexerfptr lexer, void *lexerrock */); /* causes the parser to run to completion using the tables and lexan stream previously defined to it. Returns one of the severity values above, indicating the highest severity error encountered */ extern void parser_Error(/* struct parser *self, xint severity, char *msg */); /* call this to report an error */ extern void parser_ErrorGuts(/* struct parser *self, int severity, char *severityname, char *msg */); /* override this to provide error processing */ extern struct parser *parser_GetCurrentparser(); /* during parser_Parse, this returns the current parser object This can be used to call the Error method */ extern void parser_EnumerateReservedWords(/* struct parser *self, parser_enumresfptr handler, void *rock */); /* the handler is called for each alphabetic reserved word: handler(rock, char *word, int tokennumber) but it is not called for names beginning with "set" and for names beginning with "tok", only the rest of the name is passed uppercase letters are converted to lower, and vice versa */ extern int parser_TokenNumberFromName(/* struct parser *self, char *name */); /* returns the token number corresponding to the string; typical strings: "function", "setID", "tokNULL", "'a'", "\":=\"" if the name is not found, returns 0 */ extern int parser_SetDebug(/* int value */); /* sets the debug flag to the given value; must be 0 or 1. Returns prior value */ extern int parser_ParseNumber(/* char *buf, long *plen, long *intval, double *dvlval */); /* parses a number from buf and sets *plen to length found sets *intval to integer value and if syntax is for a real, sets *dblval to real value returns 1 if syntactically an integer, 2 for a double, and 0 for a syntax error */ extern int parser_TransEscape(/* char *buf, int *plen */); /* buf holds a character sequence (at least three chars) that occurred after a backslash in a string. The translation is returned as an int. The number of characters used is returned in *plen. (plen may be NULL) The translations are a superset of C: escape seq : translation --------------- : ------------ \\ \' \" \b \t : as in C \n \v \f \r : as in C \ddd : octal digits, as in C \? : DEL or \177 \e : ESC or ctl-[ or \033 \^@ : NUL or \000 \^a ... \^z : ctl-a ... ctl-z or \001 ... \032 \^[ \^\ \^] : \033 \034 \035 \^^ \^_ : \036 \037 */ extern struct parser *parser_New(); /* creates a new parser */ extern void parser_Destroy(/* struct parser *self */); #define parser_SetRock(self, r) (self->rock = (r)) #define parser_GetRock(self) (self->rock) #define parser_SetErrorFunc(self, err) (self->errorfunc=(err)) #define parser_GetErrorState(self) (self->errorstate) /* to change errorstate, an action concludes with parser_ERROR or parser_ERROROK */ #define parser_SetKillVal(self, kv) (self->killval = (kv)) #define parser_GetKillVal(self) (self->killval) #define parser_SetMaxSeverity(self, s) (self->maxSeverity = (s)) #define parser_GetMaxSeverity(self) (self->maxSeverity) #define parser_SetNErrors(self, n) (self->nerrors = (n)) #define parser_GetNErrors(self) (self->nerrors) #define parser_GetTokenNames(self) (self->tables->names) #define parser_GetNTokens(self) (self->tables->num_tokens) #define parser_SetTables(self,t) (self)->tables = (t) #define parser_TranslateTokenNumber(self,x) ((x)==(-1) ? 0 : ((unsigned)(x) <= self->tables->max_user_token ? self->tables->translate[x] : self->tables->num_tokens + self->tables->num_nt)) struct parser { /* data members */ struct parser_tables *tables; /* tables from Bison */ void *rock; /* passed to action() */ parser_errfptr errorfunc; /* error function */ parser_killfptr killval; /* if non-NULL, self function is called for each value element skipped over on the stack during error processing or at early termination. The call is (self->killval)(self, pointer-from-value-stack) */ int errorstate; /* 0 if ok, >0 if processing a syntax error */ int nerrors; /* number of errors encountered */ int maxSeverity; /* greatest severity error encountered */ }; #endif /* _cparser_H_ */