From: Terence Parr <> Date: Fri, 6 Oct 1995 00:39:54 +0000 (-0500) Subject: auto commit for import X-Git-Url: https://pd.if.org/git/?p=pccts;a=commitdiff_plain;h=b5b3c41d4e99ca613b441d68458aa3cd873aa417 auto commit for import --- diff --git a/antlr/antlr.g b/antlr/antlr.g new file mode 100755 index 0000000..7716b00 --- /dev/null +++ b/antlr/antlr.g @@ -0,0 +1,1729 @@ +/* + * antlr.g -- PCCTS Version 1.xx ANTLR + * + * $Id: antlr.g,v 1.7 95/10/05 11:57:12 parrt Exp $ + * $Revision: 1.7 $ + * + * Parse an antlr input grammar and build a syntax-diagram. + * + * Written in itself (needs at least 1.06 to work) + * + * SOFTWARE RIGHTS + * + * We reserve no LEGAL rights to the Purdue Compiler Construction Tool + * Set (PCCTS) -- PCCTS is in the public domain. An individual or + * company may do whatever they wish with source code distributed with + * PCCTS or the code generated by PCCTS, including the incorporation of + * PCCTS, or its output, into commerical software. + * + * We encourage users to develop software with PCCTS. However, we do ask + * that credit is given to us for developing PCCTS. By "credit", + * we mean that if you incorporate our source code into one of your + * programs (commercial product, research project, or otherwise) that you + * acknowledge this fact somewhere in the documentation, research report, + * etc... If you like PCCTS and have developed a nice tool with the + * output, please mention that you developed it using PCCTS. In + * addition, we ask that this header remain intact in our source code. + * As long as these guidelines are kept, we expect to continue enhancing + * this system and expect to make other tools available as they are + * completed. + * + * ANTLR 1.33 + * Terence Parr + * Parr Research Corporation + * with Purdue University and AHPCRC, University of Minnesota + * 1989-1995 + */ +#header << + #ifdef __cplusplus + #ifndef __STDC__ + #define __STDC__ + #endif + #endif + #include "set.h" + #include + #include "syn.h" + #include "hash.h" + #include "generic.h" + #define zzcr_attr(attr,tok,t) + >> + +<< +#ifdef __STDC__ +static void chkToken(char *, char *, char *, int); +#else +static void chkToken(); +#endif + +static int class_nest_level = 0; +extern int inAlt; +extern set attribsRefdFromAction; +extern int UsedOldStyleAttrib; +extern int UsedNewStyleLabel; +>> + +#lexaction << +/* maintained, but not used for now */ +set AST_nodes_refd_in_actions = set_init; +int inAlt = 0; +set attribsRefdFromAction; +int UsedOldStyleAttrib = 0; +int UsedNewStyleLabel = 0; +#ifdef __USE_PROTOS +char *inline_set(char *); +#else +char *inline_set(); +#endif +>> + +#lexclass STRINGS +#token QuotedTerm "\"" << zzmode(START); >> +#token "[\n\r]" << + zzline++; + warn("eoln found in string"); + zzskip(); + >> +#token "\\[\n\r]" << zzline++; zzmore(); >> +#token "\\~[]" << zzmore(); >> +#token "~[\n\r\"\\]+" << zzmore(); >> + +#lexclass ACTION_STRINGS +#token "\"" << zzmode(ACTIONS); zzmore(); >> +#token "[\n\r]" << + zzline++; + warn("eoln found in string (in user action)"); + zzskip(); + >> +#token "\\[\n\r]" << zzline++; zzmore(); >> +#token "\\~[]" << zzmore(); >> +#token "~[\n\r\"\\]+" << zzmore(); >> + +#lexclass ACTION_CHARS +#token "'" << zzmode(ACTIONS); zzmore(); >> +#token "[\n\r]" << + zzline++; + warn("eoln found in char literal (in user action)"); + zzskip(); + >> +#token "\\~[]" << zzmore(); >> +#token "~[\n\r'\\]+" << zzmore(); >> + +#lexclass ACTION_COMMENTS +#token "\*/" << zzmode(ACTIONS); zzmore(); >> +#token "\*" << zzmore(); >> +#token "[\n\r]" << zzline++; zzmore(); DAWDLE; >> +#token "~[\n\r\*]+" << zzmore(); >> + +#lexclass TOK_DEF_COMMENTS +#token "\*/" << zzmode(PARSE_ENUM_FILE); +zzmore(); >> +#token "\*" << zzmore(); >> +#token "[\n\r]" << zzline++; zzmore(); DAWDLE; >> +#token "~[\n\r\*]+" << zzmore(); >> + +#lexclass TOK_DEF_CPP_COMMENTS +#token "[\n\r]" << zzline++; zzmode(PARSE_ENUM_FILE); zzskip(); DAWDLE; >> +#token "~[\n\r]+" << zzskip(); >> + +#lexclass ACTION_CPP_COMMENTS +#token "[\n\r]" << zzline++; zzmode(ACTIONS); zzmore(); DAWDLE; >> +#token "~[\n\r]+" << zzmore(); >> + +#lexclass CPP_COMMENTS +#token "[\n\r]" << zzline++; zzmode(START); zzskip(); DAWDLE; >> +#token "~[\n\r]+" << zzskip(); >> + +#lexclass COMMENTS +#token "\*/" << zzmode(START); zzskip(); >> +#token "\*" << zzskip(); >> +#token "[\n\r]" << zzline++; zzskip(); DAWDLE; >> +#token "~[\n\r\*]+" << zzskip(); >> + +/* + * This lexical class accepts actions of type [..] and <<..>> + * + * It translates the following special items for C: + * + * $j --> "zzaArg(current zztasp, j)" + * $i.j --> "zzaArg(zztaspi, j)" + * $i.nondigit> "zzaArg(current zztasp, i).nondigit" + * $$ --> "zzaRet" + * $alnum --> "alnum" (used to ref parameters) + * $rule --> "zzaRet" + * $retval --> "_retv.retval" if > 1 return values else "_retv" + * $[token, text] --> "zzconstr_attr(token, text)" + * $[] --> "zzempty_attr()" + * + * It translates the following special items for C++: + * (attributes are now stored with 'Token' and $i's are only + * pointers to the Tokens. Rules don't have attributes now.) + * + * $j --> "_tbj" where b is the block level + * $i.j --> "_tij" + * $j->nondigit> "_tbj->nondigit" + * $$ --> "$$" + * $alnum --> "alnum" (used to ref parameters) + * $rule --> "$rule" + * $retval --> "_retv.retval" if > 1 return values else "_retv" + * $[token, text] --> invalid + * $[] --> invalid + * + * And, for trees: + * + * #0 --> "(*_root)" + * #i --> "zzastArg(i)" + * #[args] --> "zzmk_ast(zzastnew(), args)" + * #[] --> "zzastnew()" + * #( root, child1, ..., childn ) + * --> "zztmake(root, child1, ...., childn, NULL)" + * #() --> "NULL" + * + * For C++, ... + * + * #0 --> "(*_root)" + * #i --> "_astbi" where b is the block level + * #alnum --> "alnum_ast" (used to ref #label) + * #[args] --> "new AST(args)" + * #[] --> "new AST" + * #( root, child1, ..., childn ) + * --> "AST::tmake(root, child1, ...., childn, NULL)" + * #() --> "NULL" + * + * To escape, + * + * \] --> ] + * \) --> ) + * \$ --> $ + * \# --> # + * + * A stack is used to nest action terminators because they can be nested + * like crazy: << #[$[..],..] >> + */ +#lexclass ACTIONS +#token Action "\>\>" << /* these do not nest */ + zzmode(START); + NLATEXT[0] = ' '; + NLATEXT[1] = ' '; + zzbegexpr[0] = ' '; + zzbegexpr[1] = ' '; + if ( zzbufovf ) { + err( eMsgd("action buffer overflow; size %d",ZZLEXBUFSIZE)); + } + >> +#token Pred "\>\>?" << /* these do not nest */ + zzmode(START); + NLATEXT[0] = ' '; + NLATEXT[1] = ' '; + zzbegexpr[0] = '\0'; + if ( zzbufovf ) { + err( eMsgd("predicate buffer overflow; size %d",ZZLEXBUFSIZE)); + } + >> +#token PassAction "\]" << if ( topint() == ']' ) { + popint(); + if ( istackempty() ) /* terminate action */ + { + zzmode(START); + NLATEXT[0] = ' '; + zzbegexpr[0] = ' '; + if ( zzbufovf ) { + err( eMsgd("parameter buffer overflow; size %d",ZZLEXBUFSIZE)); + } + } + else { + /* terminate $[..] and #[..] */ + if ( GenCC ) zzreplstr("))"); + else zzreplstr(")"); + zzmore(); + } + } + else if ( topint() == '|' ) { /* end of simple [...] */ + popint(); + zzmore(); + } + else zzmore(); + >> +#token "consumeUntil\( [\ \t]* \{~[\}]+\} [\ \t]* \)" + << + zzmore(); + zzreplstr(inline_set(zzbegexpr+ + strlen("consumeUntil("))); + >> +#token "consumeUntil\( ~[\)]+ \)" + << zzmore(); >> +#token "[\n\r]" << zzline++; zzmore(); DAWDLE; >> +#token "\>" << zzmore(); >> +#token "$" << zzmore(); >> +#token "$$" << if ( !GenCC ) {zzreplstr("zzaRet"); zzmore();} + else err("$$ use invalid in C++ mode"); >> + +#token "$\[\]" << if ( !GenCC ) {zzreplstr("zzempty_attr"); zzmore();} + else err("$[] use invalid in C++ mode"); >> +#token "$\[" << + pushint(']'); + if ( !GenCC ) zzreplstr("zzconstr_attr("); + else err("$[..] use invalid in C++ mode"); + zzmore(); + >> +#token "$[0-9]+" <<{ + static char buf[100]; + if ( strlen(zzbegexpr)>(size_t)85 ) + fatal("$i attrib ref too big"); + set_orel(atoi(zzbegexpr+1), &attribsRefdFromAction); + if ( !GenCC ) sprintf(buf,"zzaArg(zztasp%d,%s)", + BlkLevel-1,zzbegexpr+1); + else sprintf(buf,"_t%d%s", + BlkLevel-1,zzbegexpr+1); + zzreplstr(buf); + zzmore(); + UsedOldStyleAttrib = 1; + if ( UsedNewStyleLabel ) + err("cannot mix old-style $i with new-style labels"); + } + >> +#token "$[0-9]+." <<{ + static char buf[100]; + if ( strlen(zzbegexpr)>(size_t)85 ) + fatal("$i.field attrib ref too big"); + zzbegexpr[strlen(zzbegexpr)-1] = ' '; + set_orel(atoi(zzbegexpr+1), &attribsRefdFromAction); + if ( !GenCC ) sprintf(buf,"zzaArg(zztasp%d,%s).", + BlkLevel-1,zzbegexpr+1); + else sprintf(buf,"_t%d%s.", + BlkLevel-1,zzbegexpr+1); + zzreplstr(buf); + zzmore(); + UsedOldStyleAttrib = 1; + if ( UsedNewStyleLabel ) + err("cannot mix old-style $i with new-style labels"); + } + >> +#token "$[0-9]+.[0-9]+" <<{ + static char buf[100]; + static char i[20], j[20]; + char *p,*q; + if (strlen(zzbegexpr)>(size_t)85) fatal("$i.j attrib ref too big"); + for (p=zzbegexpr+1,q= &i[0]; *p!='.'; p++) { + if ( q == &i[20] ) + fatalFL("i of $i.j attrib ref too big", + FileStr[CurFile], zzline ); + *q++ = *p; + } + *q = '\0'; + for (p++, q= &j[0]; *p!='\0'; p++) { + if ( q == &j[20] ) + fatalFL("j of $i.j attrib ref too big", + FileStr[CurFile], zzline ); + *q++ = *p; + } + *q = '\0'; + if ( !GenCC ) sprintf(buf,"zzaArg(zztasp%s,%s)",i,j); + else sprintf(buf,"_t%s%s",i,j); + zzreplstr(buf); + zzmore(); + UsedOldStyleAttrib = 1; + if ( UsedNewStyleLabel ) + err("cannot mix old-style $i with new-style labels"); + } + >> +#token "$[_a-zA-Z][_a-zA-Z0-9]*" + <<{ static char buf[300]; LabelEntry *el; + zzbegexpr[0] = ' '; + if ( CurRule != NULL && + strcmp(CurRule, &zzbegexpr[1])==0 ) { + if ( !GenCC ) zzreplstr("zzaRet"); + } + else if ( CurRetDef != NULL && + strmember(CurRetDef, &zzbegexpr[1])) { + if ( HasComma( CurRetDef ) ) { + require (strlen(zzbegexpr)<=(size_t)285, + "$retval attrib ref too big"); + sprintf(buf,"_retv.%s",&zzbegexpr[1]); + zzreplstr(buf); + } + else zzreplstr("_retv"); + } + else if ( CurParmDef != NULL && + strmember(CurParmDef, &zzbegexpr[1])) { + ; + } + else if ( Elabel==NULL ) { + { err("$-variables in actions outside of rules are not allowed"); } + } else if ( (el=(LabelEntry *)hash_get(Elabel, &zzbegexpr[1]))!=NULL ) { + if ( GenCC && (el->elem==NULL || el->elem->ntype==nRuleRef) ) + { err(eMsg1("There are no token ptrs for rule references: '$%s'",&zzbegexpr[1])); } + } + else + warn(eMsg1("$%s not parameter, return value, or element label",&zzbegexpr[1])); + } + zzmore(); + >> +#token "#0" << zzreplstr("(*_root)"); zzmore(); chkGTFlag(); >> +#token "#\[\]" << if ( GenCC ) {zzreplstr("(new AST)");} + else {zzreplstr("zzastnew()");} zzmore(); + chkGTFlag(); + >> +#token "#\(\)" << zzreplstr("NULL"); zzmore(); chkGTFlag(); >> +#token "#[0-9]+" <<{ + static char buf[100]; + if ( strlen(zzbegexpr)>(size_t)85 ) + fatal("#i AST ref too big"); + if ( GenCC ) sprintf(buf,"_ast%d%s",BlkLevel-1,zzbegexpr+1); + else sprintf(buf,"zzastArg(%s)",zzbegexpr+1); + zzreplstr(buf); + zzmore(); + set_orel(atoi(zzbegexpr+1), &AST_nodes_refd_in_actions); + chkGTFlag(); + } + >> +#token "#[_a-zA-Z][_a-zA-Z0-9]*" + << + if ( !(strcmp(zzbegexpr, "#ifdef")==0 || + strcmp(zzbegexpr, "#if")==0 || + strcmp(zzbegexpr, "#else")==0 || + strcmp(zzbegexpr, "#endif")==0 || + strcmp(zzbegexpr, "#ifndef")==0 || + strcmp(zzbegexpr, "#define")==0 || + strcmp(zzbegexpr, "#pragma")==0 || + strcmp(zzbegexpr, "#undef")==0 || + strcmp(zzbegexpr, "#import")==0 || + strcmp(zzbegexpr, "#line")==0 || + strcmp(zzbegexpr, "#include")==0 || + strcmp(zzbegexpr, "#error")==0) ) + { + static char buf[100]; + sprintf(buf, "%s_ast", zzbegexpr+1); + zzreplstr(buf); + chkGTFlag(); + } + zzmore(); + >> +#token "#\[" << + pushint(']'); + if ( GenCC ) zzreplstr("(new AST("); + else zzreplstr("zzmk_ast(zzastnew(),"); + zzmore(); + chkGTFlag(); + >> +#token "#\(" << + pushint('}'); + if ( GenCC ) zzreplstr("ASTBase::tmake("); + else zzreplstr("zztmake("); + zzmore(); + chkGTFlag(); + >> +#token "#" << zzmore(); >> +#token "\)" << + if ( istackempty() ) + zzmore(); + else if ( topint()==')' ) { + popint(); + } + else if ( topint()=='}' ) { + popint(); + /* terminate #(..) */ + zzreplstr(", NULL)"); + } + zzmore(); + >> +#token "\[" << + pushint('|'); /* look for '|' to terminate simple [...] */ + zzmore(); + >> +#token "\(" << + pushint(')'); + zzmore(); + >> + +#token "\\\]" << zzreplstr("]"); zzmore(); >> +#token "\\\)" << zzreplstr(")"); zzmore(); >> +#token "\\>" << zzreplstr(">"); zzmore(); >> + + +#token "'" << zzmode(ACTION_CHARS); zzmore();>> +#token "\"" << zzmode(ACTION_STRINGS); zzmore();>> +#token "\\$" << zzreplstr("$"); zzmore(); >> +#token "\\#" << zzreplstr("#"); zzmore(); >> +#token "\\[\n\r]" << zzline++; zzmore(); >> +#token "\\~[\]\)>$#]" << zzmore(); >> /* escaped char, always ignore */ +#token "/" << zzmore(); >> +#token "/\*" << zzmode(ACTION_COMMENTS); zzmore(); >> +#token "\*/" << warn("Missing /*; found dangling */ in action"); zzmore(); >> +#token "//" << zzmode(ACTION_CPP_COMMENTS); zzmore(); >> +#token "~[\n\r\)\(\\$#\>\]\[\"'/]+" << zzmore(); >> + +#lexclass START +#token "[\t\ ]+" << zzskip(); >> /* Ignore White */ +#token "[\n\r]" << zzline++; zzskip(); >> /* Track Line # */ +#token "\[" << zzmode(ACTIONS); zzmore(); + istackreset(); + pushint(']'); >> +#token "\<\<" << action_file=CurFile; action_line=zzline; + zzmode(ACTIONS); zzmore(); + istackreset(); + pushint('>'); >> +#token "\"" << zzmode(STRINGS); zzmore(); >> +#token "/\*" << zzmode(COMMENTS); zzskip(); >> +#token "\*/" << warn("Missing /*; found dangling */"); zzskip(); >> +#token "//" << zzmode(CPP_COMMENTS); zzskip(); >> +#token "\>\>" << warn("Missing <<; found dangling \\>\\>"); zzskip(); >> +#token WildCard "." +#token "\@" <> +#token Eof "@" + << /* L o o k F o r A n o t h e r F i l e */ + { + FILE *new_input; + new_input = NextFile(); + if ( new_input == NULL ) { NLA=Eof; return; } + fclose( input ); + input = new_input; + zzrdstream( input ); + zzskip(); /* Skip the Eof (@) char i.e continue */ + } + >> + +#token LABEL + +#errclass "grammar-element" { element } +#errclass "meta-symbol" { "\}" "!" ";" "\|" "\~" "^" "\)" } + +/* + * Get a grammar -- Build a list of rules like: + * + * o-->Rule1--o + * | + * o-->Rule2--o + * | + * ... + * | + * o-->RuleN--o + */ +grammar : <> + ( "#header" Action + << + if ( HdrAction==NULL ) { + HdrAction = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); + require(HdrAction!=NULL, "rule grammar: cannot allocate header action"); + strcpy(HdrAction, LATEXT(1)); + } + else warn("additional #header statement ignored"); + >> + | "#parser" QuotedTerm + << + if ( GenCC ) { + warn("#parser meta-op incompatible with -CC; ignored"); + } + else { + if ( strcmp(ParserName,"zzparser")==0 ) { + ParserName=StripQuotes(mystrdup(LATEXT(1))); + if ( RulePrefix[0]!='\0' ) + { + warn("#parser meta-op incompatible with '-gp prefix'; '-gp' ignored"); + RulePrefix[0]='\0'; + } + } + else warn("additional #parser statement ignored"); + } + >> + | "#tokdefs" QuotedTerm + <<{ + char *fname; + zzantlr_state st; FILE *f; struct zzdlg_state dst; + UserTokenDefsFile = mystrdup(LATEXT(1)); + zzsave_antlr_state(&st); + zzsave_dlg_state(&dst); + fname = mystrdup(LATEXT(1)); + f = fopen(StripQuotes(fname), "r"); + if ( f==NULL ) {warn(eMsg1("cannot open token defs file '%s'", fname+1));} + else { + ANTLRm(enum_file(fname+1), f, PARSE_ENUM_FILE); + UserDefdTokens = 1; + } + zzrestore_antlr_state(&st); + zzrestore_dlg_state(&dst); + }>> + )* + ( Action + <<{ + UserAction *ua = newUserAction(LATEXT(1)); + ua->file = action_file; ua->line = action_line; + if ( class_nest_level>0 ) list_add(&class_before_actions, ua); + else list_add(&BeforeActions, ua); + }>> + | laction + | aLexclass + | token + | error + | tclass + | default_exception_handler + | class_def + | "\}" + << + if ( class_nest_level==0 ) + warn("missing class definition for trailing '}'"); + class_nest_level--; + >> + )* + rule <> + ( rule <> + | aLexclass + | token + | error + | tclass + | class_def + | "\}" + << + if ( class_nest_level==0 ) + warn("missing class definition for trailing '}'"); + class_nest_level--; + >> + )* + ( Action + <<{ + UserAction *ua = newUserAction(LATEXT(1)); + ua->file = action_file; ua->line = action_line; + if ( class_nest_level>0 ) list_add(&class_after_actions, ua); + else list_add(&AfterActions, ua); + }>> + | laction + | error + | tclass + | class_def + | "\}" + << + if ( class_nest_level==0 ) + warn("missing class definition for trailing '}'"); + class_nest_level--; + >> + )* + Eof + ; + <> + +class_def + : <> + "class" + ( NonTerminal <> + | TokenTerm <> + ) + << + if ( CurrentClassName[0]!='\0' && strcmp(CurrentClassName,name)!=0 + && GenCC ) { + err("only one grammar class allowed in this release"); + go = 0; + } + else strcpy(CurrentClassName, name); + >> + <> + "\{" + << + no_classes_found = 0; + if ( class_nest_level>=1 ) {warn("cannot have nested classes");} + else class_nest_level++; + >> + ; + <> + +/* + * Build -o-->o-R-o-->o- where -o-R-o- is the block from rule 'block'. + * Construct the RuleBlk front and EndRule node on the end of the + * block. This is used to add FOLLOW pointers to the rule end. Add the + * new rule name to the Rname hash table and sets its rulenum. + * Store the parameter definitions if any are found. + * + * Note that locks are required on the RuleBlk and EndRule nodes to thwart + * infinite recursion. + * + * Return the left graph pointer == NULL to indicate error/dupl rule def. + */ +rule : << + ListNode *ex_groups = NULL; + ExceptionGroup *eg; + RuleEntry *q; Junction *p; Graph r; int f, l; ECnode *e; + set toksrefd, rulesrefd; + char *pdecl=NULL, *ret=NULL, *a; CurRetDef = CurParmDef = NULL; + CurExGroups = NULL; + CurElementLabels = NULL; + /* We want a new element label hash table for each rule */ + if ( Elabel!=NULL ) killHashTable(Elabel); + Elabel = newHashTable(); + attribsRefdFromAction = empty; + >> + NonTerminal + <str; + } + CurRuleNode = q; + f = CurFile; l = zzline; + NumRules++; + >> + { "!" <noAST = TRUE;>> } + { <<;>> + {"\<"} + PassAction + << pdecl = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); + require(pdecl!=NULL, "rule rule: cannot allocate param decl"); + strcpy(pdecl, LATEXT(1)); + CurParmDef = pdecl; + >> + } + { "\>" + PassAction + << ret = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); + require(ret!=NULL, "rule rule: cannot allocate ret type"); + strcpy(ret, LATEXT(1)); + CurRetDef = ret; + >> + } + { QuotedTerm <egroup=mystrdup(LATEXT(1));>> } + << + if ( GenEClasseForRules && q!=NULL ) { + e = newECnode; + require(e!=NULL, "cannot allocate error class node"); + if ( q->egroup == NULL ) {a = q->str; a[0] = (char)toupper(a[0]);} + else a = q->egroup; + if ( Tnum( a ) == 0 ) + { + e->tok = addTname( a ); + list_add(&eclasses, (char *)e); + if ( q->egroup == NULL ) a[0] = (char)tolower(a[0]); + /* refers to itself */ + list_add(&(e->elist), mystrdup(q->str)); + } + else { + warn(eMsg1("default errclass for '%s' would conflict with token/errclass/tokclass",a)); + if ( q->egroup == NULL ) a[0] = (char)tolower(a[0]); + free((char *)e); + } + } + >> + <> + ":" <> + block[&toksrefd, &rulesrefd] + <blockid = CurBlockID; + CurRuleBlk->jtype = RuleBlk; + if ( q!=NULL ) CurRuleBlk->rname = q->str; + CurRuleBlk->file = f; + CurRuleBlk->line = l; + CurRuleBlk->pdecl = pdecl; + CurRuleBlk->ret = ret; + CurRuleBlk->lock = makelocks(); + CurRuleBlk->pred_lock = makelocks(); + CurRuleBlk->tokrefs = toksrefd; + CurRuleBlk->rulerefs = rulesrefd; + p = newJunction(); /* add EndRule Node */ + ((Junction *)r.right)->p1 = (Node *)p; + r.right = (Node *) p; + p->jtype = EndRule; + p->lock = makelocks(); + p->pred_lock = makelocks(); + CurRuleBlk->end = p; + if ( q!=NULL ) q->rulenum = NumRules; + $7 = r; + >> + <<--BlkLevel;>> + ";" <> + { Action + << a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); + require(a!=NULL, "rule rule: cannot allocate error action"); + strcpy(a, LATEXT(1)); + CurRuleBlk->erraction = a; + >> + } + ( exception_group > [eg] + <label=='\0' ) q->has_rule_exception = 1; + } + >> + )* + <> + <> + <exceptions = CurExGroups;>> + <el_labels = CurElementLabels;>> + ; + <> + +/* +pragma : "#pragma" "dup\-labeled\-tokens" + <> + ; +*/ + +laction : <> + "#lexaction" + Action + << + a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); + require(a!=NULL, "rule laction: cannot allocate action"); + strcpy(a, LATEXT(1)); + list_add(&LexActions, a); + >> + ; + <> + +aLexclass: "#lexclass" TokenTerm <> + ; + <> + +error : <> + "#errclass" + (<<;>> TokenTerm <> + | QuotedTerm <> + ) + <lexclass = CurrentLexClass; + if ( Tnum( (t=StripQuotes(t)) ) == 0 ) + { + if ( hash_get(Texpr, t) != NULL ) + warn(eMsg1("errclass name conflicts with regular expression '%s'",t)); + e->tok = addTname( t ); + set_orel(e->tok, &imag_tokens); + require((p=(TermEntry *)hash_get(Tname, t)) != NULL, + "hash table mechanism is broken"); + p->classname = 1; /* entry is errclass name, not token */ + list_add(&eclasses, (char *)e); + } + else + { + warn(eMsg1("redefinition of errclass or conflict w/token or tokclass '%s'; ignored",t)); + free( (char *)e ); + go=0; + } + >> + "\{" + ( NonTerminal <> + | TokenTerm <> + | QuotedTerm <> + ) + <elist), t);>> + ( + ( NonTerminal <> + | TokenTerm <> + | QuotedTerm <> + ) + <elist), t);>> + )* + "\}" + ; + <> + +tclass : <> + "#tokclass" TokenTerm <> + <lexclass = CurrentLexClass; + if ( Tnum( t ) == 0 ) + { + e->tok = addTname( t ); + set_orel(e->tok, &imag_tokens); + set_orel(e->tok, &tokclasses); + require((p=(TermEntry *)hash_get(Tname, t)) != NULL, + "hash table mechanism is broken"); + p->classname = 1; /* entry is class name, not token */ + p->tclass = e; /* save ptr to this tclass def */ + list_add(&tclasses, (char *)e); + } + else + { + warn(eMsg1("redefinition of tokclass or conflict w/token '%s'; ignored",t)); + free( (char *)e ); + go=0; + } + >> + "\{" + ( + ( TokenTerm + <> + | QuotedTerm + <> + ) + <tlist), t);>> + )* + "\}" + ; + <> + +token : <> + "#token" + { TokenTerm <> + { "=" "[0-9]+" /* define the token type number */ + <> + } + } + { QuotedTerm <> } + { Action + << + a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); + require(a!=NULL, "rule token: cannot allocate action"); + strcpy(a, LATEXT(1)); + >> + } + <> + ; + <> + +block[set *toksrefd, set *rulesrefd] + : << + Graph g, b; + set saveblah; + int saveinalt = inAlt; + ExceptionGroup *eg; + *$toksrefd = empty; + *$rulesrefd = empty; + set_clr(AST_nodes_refd_in_actions); + CurBlockID++; + CurAltNum = 1; + saveblah = attribsRefdFromAction; + attribsRefdFromAction = empty; + >> + alt[toksrefd,rulesrefd] <> + << + if ( ((Junction *)g.left)->p1->ntype == nAction ) + { + if ( !((ActionNode *)(((Junction *)g.left)->p1))->is_predicate ) + { + ((ActionNode *)(((Junction *)g.left)->p1))->init_action = TRUE; + } + } + ((Junction *)g.left)->blockid = CurBlockID; + >> + + ( exception_group > [eg] + << + if ( eg!=NULL ) { + eg->altID = makeAltID(CurBlockID,CurAltNum); + CurAltStart->exception_label = eg->altID; + list_add(&CurExGroups, (void *)eg); + } + >> + )* + <> + + ( "\|" <> + alt[toksrefd,rulesrefd] <> + << + ((Junction *)g.left)->blockid = CurBlockID; + >> + + ( exception_group > [eg] + << + if ( eg!=NULL ) { + eg->altID = makeAltID(CurBlockID,CurAltNum); + CurAltStart->exception_label = eg->altID; + list_add(&CurExGroups, (void *)eg); + } + >> + )* + + <> + + )* + <<$0 = b;>> + <> + ; + <> + +alt[set *toksrefd, set *rulesrefd] + : <> + { "\@" /* handle MismatchedToken signals with default handler */ + <> + } + ( <> + { <> "\~" <> } + element[not, first_on_line, use_def_MT_handler] > [node] + <ntype!=nAction ) first_on_line = 0;>> + << + if ( $2.left!=NULL ) { + g = Cat(g, $2); + n++; + if ( node!=NULL ) { + if ( node->ntype!=nAction ) e_num++; + /* record record number of all rule and token refs */ + if ( node->ntype==nToken ) { + TokNode *tk = (TokNode *)((Junction *)$2.left)->p1; + tk->elnum = e_num; + set_orel(e_num, &elems); + } + else if ( node->ntype==nRuleRef ) { + RuleRefNode *rn = (RuleRefNode *)((Junction *)$2.left)->p1; + rn->elnum = e_num; + set_orel(e_num, $rulesrefd); + } + } + } + >> + )* + <0 ) + err("one or more $i in action(s) refer to non-token elements"); + set_free(dif); + } + set_free(elems); + set_free(attribsRefdFromAction); + inAlt = 0; + >> + ; + <> + +element_label > [LabelEntry *label] + : <> + LABEL <> + << + UsedNewStyleLabel = 1; + if ( UsedOldStyleAttrib ) err("cannot mix with new-style labels with old-style $i"); + t = (TermEntry *) hash_get(Tname, lab); + if ( t==NULL ) t = (TermEntry *) hash_get(Texpr, lab); + if ( t==NULL ) r = (RuleEntry *) hash_get(Rname, lab); + if ( t!=NULL ) { + err(eMsg1("label definition clashes with token/tokclass definition: '%s'", lab)); + $label = NULL; + } + else if ( r!=NULL ) { + err(eMsg1("label definition clashes with rule definition: '%s'", lab)); + $label = NULL; + } + else { + /* we don't clash with anybody else */ + l = (LabelEntry *) hash_get(Elabel, lab); + if ( l==NULL ) { /* ok to add new element label */ + l = (LabelEntry *)hash_add(Elabel, + lab, + (Entry *)newLabelEntry(lab)); + /* add to list of element labels for this rule */ + list_add(&CurElementLabels, (void *)lab); + $label = l; + } + else { + err(eMsg1("label definitions must be unique per rule: '%s'", lab)); + $label = NULL; + } + } + >> + ":" + ; + +element[int not, int first_on_line, int use_def_MT_handler] > [Node *node] + : << + Attrib blk; + Predicate *pred = NULL; + int local_use_def_MT_handler=0; + ActionNode *act; + RuleRefNode *rr; + set toksrefd, rulesrefd; + TermEntry *term; + TokNode *p=NULL; RuleRefNode *q; int approx=0; + LabelEntry *label=NULL; + $node = NULL; + >> + {element_label>[label]} + ( TokenTerm + << + term = (TermEntry *) hash_get(Tname, LATEXT(1)); + if ( term==NULL && UserDefdTokens ) { + err("implicit token definition not allowed with #tokdefs"); + $$.left = $$.right = NULL; + } + else { + $$ = buildToken(LATEXT(1)); + p=((TokNode *)((Junction *)$$.left)->p1); + term = (TermEntry *) hash_get(Tname, LATEXT(1)); + require( term!= NULL, "hash table mechanism is broken"); + p->tclass = term->tclass; + p->complement = $not; + if ( label!=NULL ) { + p->el_label = label->str; + label->elem = (Node *)p; + } + } + >> + { ".." + ( QuotedTerm + <> + | TokenTerm + <> + ) + } + << + if ( p!=NULL && (p->upper_range!=0 || p->tclass || $not) ) + list_add(&MetaTokenNodes, (void *)p); + >> + ( "^" <astnode=ASTroot;>> + | <astnode=ASTchild;>> + | "!" <astnode=ASTexclude;>> + ) + { "\@" <> } + << + if ( p!=NULL && $first_on_line ) { + CurAltStart = (Junction *)$$.left; + p->altstart = CurAltStart; + } + if ( p!=NULL ) + p->use_def_MT_handler = $use_def_MT_handler || local_use_def_MT_handler; + $node = (Node *)p; + >> + | QuotedTerm + << + term = (TermEntry *) hash_get(Texpr, LATEXT(1)); + if ( term==NULL && UserDefdTokens ) { + err("implicit token definition not allowed with #tokdefs"); + $$.left = $$.right = NULL; + } + else { + $$ = buildToken(LATEXT(1)); p=((TokNode *)((Junction *)$$.left)->p1); + p->complement = $not; + if ( label!=NULL ) { + p->el_label = label->str; + label->elem = (Node *)p; + } + } + >> + { ".." + ( QuotedTerm + <> + | TokenTerm + <> + ) + } + ( "^" <astnode=ASTroot;>> + | <astnode=ASTchild;>> + | "!" <astnode=ASTexclude;>> + ) + { "\@" <> } + << + if ( p!=NULL && (p->upper_range!=0 || p->tclass || $not) ) + list_add(&MetaTokenNodes, (void *)p); + >> + << + if ( $first_on_line ) { + CurAltStart = (Junction *)$$.left; + p->altstart = CurAltStart; + } + if ( p!=NULL ) + p->use_def_MT_handler = $use_def_MT_handler || local_use_def_MT_handler; + $node = (Node *)p; + >> + + | <> + "." + <<$$ = buildWildCard(LATEXT(1)); p=((TokNode *)((Junction *)$$.left)->p1);>> + ( "^" <astnode=ASTroot;>> + | <astnode=ASTchild;>> + | "!" <astnode=ASTexclude;>> + ) + <> + << + if ( $first_on_line ) { + CurAltStart = (Junction *)$$.left; + p->altstart = CurAltStart; + if ( label!=NULL ) { + p->el_label = label->str; + label->elem = (Node *)p; + } + } + $node = (Node *)p; + >> + + | <> + NonTerminal + <<$$ = buildRuleRef(LATEXT(1));>> + { "!" <p1; + q->astnode=ASTexclude;>> + } + { {"\<"} + PassAction <p1, LATEXT(1));>> + } + <p1;>> + { <> + "\>" + PassAction + << + a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); + require(a!=NULL, "rule element: cannot allocate assignment"); + strcpy(a, LATEXT(1)); + rr->assign = a; + >> + } + << + if ( label!=NULL ) { + rr->el_label = label->str; + label->elem = (Node *)rr; + } + if ( $first_on_line ) { + CurAltStart = (Junction *)$$.left; + ((RuleRefNode *)((Junction *)$$.left)->p1)->altstart = CurAltStart; + } + $node = (Node *)rr; + >> + ) + + | <> + Action <<$0 = buildAction(LATEXT(1),action_file,action_line, 0);>> + <> + <<$node = (Node *) ((Junction *)$0.left)->p1;>> + + | <> + Pred <<$0 = buildAction(LATEXT(1),action_file,action_line, 1);>> + <p1;>> + { <> + PassAction + << + a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); + require(a!=NULL, "rule element: cannot allocate predicate fail action"); + strcpy(a, LATEXT(1)); + act->pred_fail = a; + >> + } + <> + <<$node = (Node *)act;>> + + | <> + <> + { "#pragma" + ( "approx" <> + | "LL(1)" <> + | "LL(2)" <> + ) + } + ( "\(" block[&toksrefd,&rulesrefd] "\)" + <> + ( "\*" <<$$ = makeLoop($$,approx);>> + | "\+" <<$$ = makePlus($$,approx);>> + | "?" + ( "=>" Pred /* generalized predicate */ + /* first make into a predicate */ + <<$$ = buildAction(LATEXT(1),action_file,action_line,1);>> + <p1;>> + { <> + PassAction + << + a = (char *)calloc(strlen(LATEXT(1))+1, sizeof(char)); + require(a!=NULL, "rule element: cannot allocate predicate fail action"); + strcpy(a, LATEXT(1)); + act->pred_fail = a; + >> + } + <> + <<$node = (Node *)act;>> + + /* for now, just snag context */ + << + pred = computePredicateFromContextGuard(blk); + if ( pred==NULL ) + err("invalid or missing context guard"); + else { + pred->expr = act->action; + pred->source = act; + act->guardpred = pred; + } + >> + | <<$$ = makeBlk($$,approx); + FoundGuessBlk = 1; + ((Junction *) ((Junction *)$$.left)->p1)->guess=1; + if ( !$first_on_line ) { + err("(...)? predicate must be first element of production"); + } + >> + ) + | <<$$ = makeBlk($$,approx);>> + ) + << + if ( pred==NULL ) { + ((Junction *)((Junction *)$$.left)->p1)->blockid = CurBlockID; + ((Junction *)((Junction *)$$.left)->p1)->tokrefs = toksrefd; + ((Junction *)((Junction *)$$.left)->p1)->rulerefs = rulesrefd; + if ( $first_on_line ) + CurAltStart = (Junction *)((Junction *)((Junction *)$$.left)->p1); + $node = (Node *) ((Junction *)$$.left)->p1; + } + >> + + | "\{" block[&toksrefd,&rulesrefd] + <<$$ = makeOpt($2,approx); --BlkLevel;>> + "\}" + << + ((Junction *)((Junction *)$$.left)->p1)->blockid = CurBlockID; + ((Junction *)((Junction *)$$.left)->p1)->tokrefs = toksrefd; + ((Junction *)((Junction *)$$.left)->p1)->rulerefs = rulesrefd; + >> + <p1); + >> + <<$node = (Node *) ((Junction *)$$.left)->p1;>> + + ) + +/* Error catching alternatives */ + | "\*" <> + | "\+" <> + | "\>" <' can only appear after a nonterminal"); CannotContinue=TRUE;>> + | PassAction < [...]'"); + CannotContinue=TRUE;>> + ; + <> + +default_exception_handler + : exception_group > [DefaultExGroup] + ; + +exception_group > [ExceptionGroup *eg] + : <> + "exception" <<$eg = (ExceptionGroup *)calloc(1, sizeof(ExceptionGroup));>> + { <> + PassAction /* did they attach a label? */ + << + p = LATEXT(1)+1; + p[strlen(p)-1] = '\0'; /* kill trailing space */ + label = (LabelEntry *) hash_get(Elabel, LATEXT(1)+1); + if ( label==NULL ) + { + err(eMsg1("unknown label in exception handler: '%s'", LATEXT(1)+1)); + } + >> + } + ( exception_handler > [h] + <handlers), (void *)h);>> + )* + { "default" ":" Action + <<{ + ExceptionHandler *eh = (ExceptionHandler *) + calloc(1, sizeof(ExceptionHandler)); + char *a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); + require(eh!=NULL, "exception: cannot allocate handler"); + require(a!=NULL, "exception: cannot allocate action"); + strcpy(a, LATEXT(1)); + eh->action = a; + eh->signalname = (char *) calloc(strlen("default")+1, sizeof(char)); + require(eh->signalname!=NULL, "exception: cannot allocate sig name"); + strcpy(eh->signalname, "default"); + list_add(&($eg->handlers), (void *)eh); + }>> + } + << + if ( label!=NULL ) { + /* Record ex group in sym tab for this label */ + if ( label->ex_group!=NULL ) { + err(eMsg1("duplicate exception handler for label '%s'",label->str)); + } + else { + label->ex_group = $eg; + /* Label the exception group itself */ + $eg->label = label->str; + /* Make the labelled element pt to the exception also */ + switch ( label->elem->ntype ) { + case nRuleRef : + { + RuleRefNode *r = (RuleRefNode *)label->elem; + r->ex_group = $eg; + break; + } + case nToken : + { + TokNode *t = (TokNode *)label->elem; + t->ex_group = $eg; + break; + } + } + } + /* You may want to remove this exc from the rule list + * and handle at the labeled element site. + */ + $eg = NULL; + } + >> + ; + <> + +exception_handler > [ExceptionHandler *eh] + : <> + "catch" + << + $eh = (ExceptionHandler *)calloc(1, sizeof(ExceptionHandler)); + require($eh!=NULL, "exception: cannot allocate handler"); + >> + ( NonTerminal + << + $eh->signalname = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); + require($eh->signalname!=NULL, "exception: cannot allocate sig name"); + strcpy($eh->signalname, LATEXT(1)); + >> + | TokenTerm + << + $eh->signalname = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); + require($eh->signalname!=NULL, "exception: cannot allocate sig name"); + strcpy($eh->signalname, LATEXT(1)); + >> + ) + ":" + { <<$eh->action = NULL;>> + Action + << + $eh->action = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); + require($eh->action!=NULL, "exception: cannot allocate action"); + strcpy($eh->action, LATEXT(1)); + >> + } + ; + <> + +#token NonTerminal "[a-z] [A-Za-z0-9_]*" + << + while ( zzchar==' ' || zzchar=='\t' ) { + zzadvance(); + } + if ( zzchar == ':' && inAlt ) NLA = LABEL; + >> +#token TokenTerm "[A-Z] [A-Za-z0-9_]*" + << + while ( zzchar==' ' || zzchar=='\t' ) { + zzadvance(); + } + if ( zzchar == ':' && inAlt ) NLA = LABEL; + >> +#token "#[A-Za-z0-9_]*" <> + +#lexclass PARSE_ENUM_FILE + +#token "[\t\ ]+" << zzskip(); >> /* Ignore White */ +#token "[\n\r]" << zzline++; zzskip(); >> /* Track Line # */ +#token "//" << zzmode(TOK_DEF_CPP_COMMENTS); zzmore(); >> +#token "/\*" << zzmode(TOK_DEF_COMMENTS); zzskip(); >> +#token "#ifdef" << zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); >> +#token "#if" << zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); >> +#token "#ifndef" << ; >> +#token "#else" << zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); >> +#token "#endif" << zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); >> +#token "#undef" << zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); >> +#token "#import" << zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); >> +#token "@" << ; >> + +enum_file[char *fname] + : { "#ifndef" ID + { "#define" ID /* ignore if it smells like a gate */ + /* First #define after the first #ifndef (if any) is ignored */ + } + } + ( ( enum_def[$fname] )+ + | defines[$fname] + ) + | + ; + +defines[char *fname] + : <> + ( + "#define" ID + <> + INT + << + v = atoi(LATEXT(1)); +/* fprintf(stderr, "#token %s=%d\n", t, v);*/ + TokenNum = v; + if ( v>maxt ) maxt=v; + if ( Tnum( t ) == 0 ) addForcedTname( t, v ); + else { + warnFL(eMsg1("redefinition of token %s; ignored",t),$fname,zzline); + } + >> + )+ + <> + ; + +enum_def[char *fname] + : <> + "enum" ID + "\{" + ID + <> + ( "=" INT <> + | <> + ) + << +/* fprintf(stderr, "#token %s=%d\n", t, v);*/ + TokenNum = v; + if ( Tnum( t ) == 0 ) addForcedTname( t, v ); + else { + warnFL(eMsg1("redefinition of token %s; ignored",t),$fname,zzline); + } + >> + ( "," + { ID + <> + ( "=" INT <> + | <> + ) + << +/* fprintf(stderr, "#token %s=%d\n", t, v);*/ + TokenNum = v; + if ( Tnum( t ) == 0 ) addForcedTname( t, v ); + else { + warnFL(eMsg1("redefinition of token %s; ignored",t),$fname,zzline); + } + >> + } + )* + "\}" + ";" + <> + ; + +#token INT "[0-9]+" +#token ID "[a-zA-Z_][_a-zA-Z0-9]*" + +#lexclass START + +<< +/* semantics of #token */ +static void +#ifdef __STDC__ +chkToken(char *t, char *e, char *a, int tnum) +#else +chkToken(t,e,a,tnum) +char *t, *e, *a; +int tnum; +#endif +{ + TermEntry *p; + + /* check to see that they don't try to redefine a token as a token class */ + if ( t!=NULL ) { + p = (TermEntry *) hash_get(Tname, t); + if ( p!=NULL && p->classname ) { + err(eMsg1("redefinition of #tokclass '%s' to #token not allowed; ignored",t)); + if ( a!=NULL ) free((char *)a); + return; + } + } + + if ( t==NULL && e==NULL ) { /* none found */ + err("#token requires at least token name or rexpr"); + } + else if ( t!=NULL && e!=NULL ) { /* both found */ + if ( UserDefdTokens ) { /* if #tokdefs, must not define new */ + p = (TermEntry *) hash_get(Tname, t); + if ( p==NULL ) { + err(eMsg1("#token definition '%s' not allowed with #tokdefs; ignored",t)); + return; + } + } + Tklink(t, e); + if ( a!=NULL ) { + if ( hasAction(e) ) { + err(eMsg1("redefinition of action for %s; ignored",e)); + } + else setHasAction(e, a); + } + } + else if ( t!=NULL ) { /* only one found */ + if ( UserDefdTokens ) { + err(eMsg1("#token definition '%s' not allowed with #tokdefs; ignored",t)); + return; + } + if ( Tnum( t ) == 0 ) addTname( t ); + else { + err(eMsg1("redefinition of token %s; ignored",t)); + } + if ( a!=NULL ) { + err(eMsg1("action cannot be attached to a token name (%s); ignored",t)); + free((char *)a); + } + } + else if ( e!=NULL ) { + if ( Tnum( e ) == 0 ) addTexpr( e ); + else { + if ( hasAction(e) ) { + err(eMsg1("redefinition of action for expr %s; ignored",e)); + } + else if ( a==NULL ) { + err(eMsg1("redefinition of expr %s; ignored",e)); + } + } + if ( a!=NULL ) setHasAction(e, a); + } + + /* if a token type number was specified, then add the token ID and 'tnum' + * pair to the ForcedTokens list. (only applies if an id was given) + */ + if ( t!=NULL && tnum>0 ) + { + if ( set_el(tnum, reserved_positions) ) + { + err(eMsgd("a token has already been forced to token number %d; ignored", tnum)); + } + else + { + list_add(&ForcedTokens, newForcedToken(t,tnum)); + set_orel(tnum, &reserved_positions); + } + } +} +>> + +<< +static int +#ifdef __USE_PROTOS +match_token(char *s, char **nxt) +#else +match_token(s,nxt) +char *s; +char **nxt; +#endif +{ + if ( !(*s>='A' && *s<='Z') ) return 0; + s++; + while ( (*s>='a' && *s<='z') || + (*s>='A' && *s<='Z') || + (*s>='0' && *s<='9') || + *s=='_' ) + { + s++; + } + if ( *s!=' ' && *s!='}' ) return 0; + *nxt = s; + return 1; +} + +static int +#ifdef __USE_PROTOS +match_rexpr(char *s, char **nxt) +#else +match_rexpr(s,nxt) +char *s; +char **nxt; +#endif +{ + if ( *s!='"' ) return 0; + s++; + while ( *s!='"' ) + { + if ( *s=='\n' ) + warn("eoln found in regular expression"); + if ( *s=='\\' ) s++; + s++; + } + *nxt = s+1; + return 1; +} + +/* + * Walk a string "{ A .. Z }" where A..Z is a space separated list + * of token references (either labels or reg exprs). Return a + * string "inlineX_set" for some unique integer X. Basically, + * we pretend as if we had seen "#tokclass inlineX { A .. Z }" + * on the input stream outside of an action. + */ +char * +#ifdef __USE_PROTOS +inline_set(char *s) +#else +inline_set(s) +char *s; +#endif +{ + char *nxt; + fprintf(stderr, "found consumeUntil( {...} )\n"); + while ( *s==' ' || *s=='\t' || *s=='\n' || *s=='\r' ) {s++;} + if ( *s!='{' ) + { + err("malformed consumeUntil( {...} ); missing '{'"); + return "bad_set"; + } + s++; + while ( *s==' ' || *s=='\t' || *s=='\n' || *s=='\r' ) {s++;} + while ( *s!='}' ) + { + if ( match_token(s,&nxt) ) fprintf(stderr, "found token %s\n", s); + else if ( match_rexpr(s,&nxt) ) fprintf(stderr, "found rexpr %s\n", s); + else { + err("invalid element in consumeUntil( {...} )"); + return "bad_set"; + } + s = nxt; + while ( *s==' ' || *s=='\t' || *s=='\n' || *s=='\r' ) {s++;} + } + return "inlineX_set"; +} +>> + +<< +/* ANTLR-specific syntax error message generator + * (define USER_ZZSYN when compiling so don't get 2 definitions) + */ +void +#ifdef __STDC__ +zzsyn(char *text, int tok, char *egroup, SetWordType *eset, int etok, +int k, char *bad_text) +#else +zzsyn(text, tok, egroup, eset, etok, k, bad_text) +char *text, *egroup, *bad_text; +int tok; +int etok; +int k; +SetWordType *eset; +#endif +{ + fprintf(stderr, ErrHdr, FileStr[CurFile]!=NULL?FileStr[CurFile]:"stdin", zzline); + fprintf(stderr, " syntax error at \"%s\"", (tok==zzEOF_TOKEN)?"EOF":text); + if ( !etok && !eset ) {fprintf(stderr, "\n"); return;} + if ( k==1 ) fprintf(stderr, " missing"); + else + { + fprintf(stderr, "; \"%s\" not", bad_text); + if ( zzset_deg(eset)>1 ) fprintf(stderr, " in"); + } + if ( zzset_deg(eset)>0 ) zzedecode(eset); + else fprintf(stderr, " %s", zztokens[etok]); + if ( strlen(egroup) > (size_t)0 ) fprintf(stderr, " in %s", egroup); + fprintf(stderr, "\n"); +} +>>