📄 gen.c
字号:
char *s;
#endif
{
char *p;
for (p=s; *p != '\0' ; p++) {
if (*p != ';' && *p !=' ') return 0;
};
return 1;
}
/* MR1 */
/* MR1 End of Routine to stringize code for failed predicates msgs */
/* MR1 */
/* Generate an action. Don't if action is NULL which means that it was already
* handled as an init action.
*/
void
#ifdef __USE_PROTOS
genAction( ActionNode *p )
#else
genAction( p )
ActionNode *p;
#endif
{
require(p!=NULL, "genAction: invalid node and/or rule");
require(p->ntype==nAction, "genAction: not action");
if ( !p->done ) /* MR10 */ /* MR11 */
{
if ( p->is_predicate)
{
if ( p->guardpred != NULL )
{
Predicate *guardDup=predicate_dup(p->guardpred); /* MR10 */
gen("if (!");
guardDup=genPredTreeMain(guardDup, (Node *)p);
predicate_free(guardDup);
}
/* MR10 */ else if (p->ampersandPred != NULL) {
/* MR10 */ gen("if (!");
/* MR10 */ p->ampersandPred=genPredTreeMain(p->ampersandPred, (Node *)p);
/* MR10 */ }
else
{
gen("if (!(");
/* make sure that '#line n' is on front of line */
if ( GenLineInfo && p->file != -1 ) _gen("\n");
dumpPredAction(p,p->action, output, 0, p->file, p->line, 0);
_gen(")");
}
/* MR23 Change failed predicate macro to have three arguments:
macro arg 1: The stringized predicate itself
macro arg 2: 0 => no user-defined error action
1 => user-defined error action
macro arg 3: The user-defined error action
This gives the user more control of the error action.
*/
tabs++;
gen3(") {zzfailed_pred(\"%s\",%s, { %s } );}\n", /* MR23 */
stringize(p->action), /* MR23 */
(p->pred_fail == NULL ? /* MR23/MR27 */
"0 /* report */" : "1 /* user action */"), /* MR23/MR27 */
(p->pred_fail == NULL ? /* MR23 */
"0; /* no user action */" : p->pred_fail)); /* MR23 */
tabs--;
}
else /* not a predicate */
{
if (! isNullAction(p->action) && !p->noHoist) {
if ( FoundGuessBlk ) {
if ( GenCC ) {
gen("if ( !guessing ) {\n");
} else {
gen("zzNON_GUESS_MODE {\n");
};
};
dumpActionPlus(p, p->action, output, tabs, p->file, p->line, 1); /* MR21 */
if ( FoundGuessBlk ) gen("}\n");
};
}
}
TRANS(p->next)
}
/*
* if invoking rule has !noAST pass zzSTR to rule ref and zzlink it in
* else pass addr of temp root ptr (&_ast) (don't zzlink it in).
*
* if ! modifies rule-ref, then never link it in and never pass zzSTR.
* Always pass address of temp root ptr.
*/
void
#ifdef __USE_PROTOS
genRuleRef( RuleRefNode *p )
#else
genRuleRef( p )
RuleRefNode *p;
#endif
{
Junction *q;
char *handler_id = "";
RuleEntry *r, *r2;
char *parm = "", *exsig = "";
int genRuleRef_emittedGuessGuard=0; /* MR10 */
require(p!=NULL, "genRuleRef: invalid node and/or rule");
require(p->ntype==nRuleRef, "genRuleRef: not rule reference");
if ( p->altstart!=NULL && p->altstart->exception_label!=NULL )
handler_id = p->altstart->exception_label;
r = (RuleEntry *) hash_get(Rname, p->text);
if ( r == NULL )
{
warnFL( eMsg1("rule %s not defined",
p->text), FileStr[p->file], p->line );
return;
}
/* MR8 5-Aug-97 Reported by S.Bochnak@microtool.com.pl */
/* Don't do assign when no return values declared */
/* Move definition of q up and use it to guard p->assign */
q = RulePtr[r->rulenum]; /* find definition of ref'd rule */ /* MR8 */
r2 = (RuleEntry *) hash_get(Rname, p->rname);
if ( r2 == NULL ) {warnNoFL("Rule hash table is screwed up beyond belief"); return;}
OutLineInfo(output,p->line,FileStr[p->file]);
if ( GenCC && GenAST ) {
gen("_ast = NULL;\n");
}
if ( FoundGuessBlk && p->assign!=NULL && q->ret != NULL ) { /* MR8 */
if ( GenCC ) {
gen("if ( !guessing ) {\n");
} else {
gen("zzNON_GUESS_MODE {\n");
};
tabs++; /* MR11 */
genRuleRef_emittedGuessGuard=1; /* MR11 */
};
if ( FoundException ) exsig = "&_signal";
tab();
if ( GenAST )
{
if ( GenCC ) {
/**** if ( r2->noAST || p->astnode==ASTexclude )
****/
{
/**** _gen("_ast = NULL;\n");
****/
parm = "&_ast";
}
/*** we always want to set just a pointer now, then set correct
pointer after
else {
_gen("_astp =
(_tail==NULL)?(&_sibling):(&(_tail->_right));\n");
parm = "_astp";
}
****/
}
else {
if ( r2->noAST || p->astnode==ASTexclude )
{
_gen("_ast = NULL; ");
parm = "&_ast";
}
else parm = "zzSTR";
}
if ( p->assign!=NULL && q->ret!=NULL ) /* MR8 */
{
if ( !hasMultipleOperands(p->assign) ) {_gen1("%s = ",p->assign);} /* MR23 */
else _gen1("{ struct _rv%d _trv; _trv = ", r->rulenum);
}
if ( FoundException ) {
_gen5("%s%s(%s,&_signal%s%s); ",
RulePrefix,
p->text,
parm,
(p->parms!=NULL)?",":"",
(p->parms!=NULL)?p->parms:"");
if ( p->ex_group!=NULL ) {
_gen("\n");
gen("if (_signal) {\n");
tabs++;
dumpException(p->ex_group, 0);
tabs--;
gen("}");
}
else {
_gen1("if (_signal) goto %s_handler;", handler_id);
}
}
else {
_gen5("%s%s(%s%s%s);",
RulePrefix,
p->text,
parm,
(p->parms!=NULL)?",":"",
(p->parms!=NULL)?p->parms:"");
}
if ( GenCC && (r2->noAST || p->astnode==ASTexclude) )
{
/* rule has a ! or element does */
/* still need to assign to #i so we can play with it */
_gen("\n");
gen2("_ast%d%d = (AST *)_ast;", BlkLevel-1, p->elnum);
}
else if ( !r2->noAST && p->astnode == ASTinclude )
{
/* rule doesn't have a ! and neither does element */
/* MR10 */ if (FoundGuessBlk && !genRuleRef_emittedGuessGuard) {
/* MR10 */ _gen("\n");
/* MR10 */ if (GenCC) gen ("if (!guessing) { /* MR10 */")
/* MR10 */ else gen ("if (!zzguessing) { /* MR10 */\n");
/* MR10 */ tabs++;
/* MR10 */ };
if ( GenCC ) {
_gen("\n");
gen("if ( _tail==NULL ) _sibling = _ast; else _tail->setRight(_ast);\n");
gen2("_ast%d%d = (AST *)_ast;\n", BlkLevel-1, p->elnum);
tab();
}
else _gen(" ");
if ( GenCC ) {
_gen("ASTBase::"); }
else _gen("zz");
_gen("link(_root, &_sibling, &_tail);");
/* MR10 */ if (FoundGuessBlk && !genRuleRef_emittedGuessGuard) { /* MR10 */
/* MR10 */ _gen("\n");
/* MR10 */ tabs--;
/* MR10 */ if (GenCC) gen ("}; /* MR10 */")
/* MR10 */ else gen ("}; /* MR10 */");
/* MR10 */ };
}
}
else
{
if ( p->assign!=NULL && q->ret!=NULL ) /* MR8 */
{
if ( !hasMultipleOperands(p->assign) ) {_gen1("%s = ",p->assign);} /* MR23 */
else _gen1("{ struct _rv%d _trv; _trv = ", r->rulenum);
}
if ( FoundException ) {
_gen4("%s%s(&_signal%s%s); ",
RulePrefix,
p->text,
(p->parms!=NULL)?",":"",
(p->parms!=NULL)?p->parms:"");
if ( p->ex_group!=NULL ) {
_gen("\n");
gen("if (_signal) {\n");
tabs++;
dumpException(p->ex_group, 0);
tabs--;
gen("}");
}
else {
_gen1("if (_signal) goto %s_handler;", handler_id);
}
}
else {
_gen3("%s%s(%s);",
RulePrefix,
p->text,
(p->parms!=NULL)?p->parms:"");
}
if ( p->assign!=NULL && q->ret!=NULL ) _gen("\n"); /* MR8 */
}
if ( p->assign!=NULL && q->ret!=NULL) { /* MR8 */
if ( hasMultipleOperands(p->assign) ) /* MR23 */
{
_gen("\n");
dumpRetValAssign(p->assign, q->ret, p); /* MR30 */
_gen("}");
}
}
_gen("\n");
/* Handle element labels now */
if ( p->el_label!=NULL )
{
if ( GenAST )
{
if ( GenCC ) {
gen3("%s_ast = _ast%d%d;\n", p->el_label, BlkLevel-1, p->elnum);
}
else {gen1("%s_ast = zzastCur;\n", p->el_label);}
}
else if (!GenCC ) {
gen1("%s = zzaCur;\n", p->el_label);
}
}
if ( FoundGuessBlk && p->assign!=NULL && q->ret!=NULL ) { /* MR8 */
/* in guessing mode, don't branch to handler upon error */
tabs--; /* MR11 */
gen("} else {\n");
tabs++; /* MR11 */
if ( FoundException ) {
gen6("%s%s(%s%s&_signal%s%s);\n",
RulePrefix,
p->text,
parm,
(*parm!='\0')?",":"",
(p->parms!=NULL)?",":"",
(p->parms!=NULL)?p->parms:"");
}
else {
gen5("%s%s(%s%s%s);\n",
RulePrefix,
p->text,
parm,
(p->parms!=NULL && *parm!='\0')?",":"",
(p->parms!=NULL)?p->parms:"");
}
tabs--; /* MR11 */
gen("}\n");
}
TRANS(p->next)
}
/*
* Generate code to match a token.
*
* Getting the next token is tricky. We want to ensure that any action
* following a token is executed before the next GetToken();
*/
void
#ifdef __USE_PROTOS
genToken( TokNode *p )
#else
genToken( p )
TokNode *p;
#endif
{
RuleEntry *r;
char *handler_id = "";
ActionNode *a;
char *set_name;
char *set_nameErrSet;
int complement;
int ast_label_in_action = 0; /* MR27 */
int pushedCmodeAST = 0; /* MR27 */
require(p!=NULL, "genToken: invalid node and/or rule");
require(p->ntype==nToken, "genToken: not token");
if ( p->altstart!=NULL && p->altstart->exception_label!=NULL )
handler_id = p->altstart->exception_label;
r = (RuleEntry *) hash_get(Rname, p->rname);
if ( r == NULL ) {warnNoFL("Rule hash table is screwed up beyond belief"); return;}
/*
* MR27 Has the element label been referenced as an AST (with the # operator) ?
* If so, then we'll want to build the AST even though the user has used
* the ! operator.
*/
/* MR27 */ if (GenAST && p->el_label != NULL) {
/* MR27 */ ast_label_in_action = list_search_cstring(r->ast_labels_in_actions,
/* MR27 */ p->el_label);
/* MR27 */ }
OutLineInfo(output,p->line,FileStr[p->file]);
if ( !set_nil(p->tset) ) /* implies '.', ~Tok, or tokenclass */
{
unsigned e;
unsigned eErrSet = 0;
set b;
set bErrSet; /* MR23 */
b = set_dup(p->tset);
bErrSet = set_dup(p->tset); /* MR23 */
complement = p->complement; /* MR23 */
if ( p->tclass!=NULL && complement == 0 /* MR23 */) { /* token class not complemented*/
static char buf[MaxRuleName+20]; /* MR23 */
static char bufErrSet[MaxRuleName+20]; /* MR23 */
if ( p->tclass->dumped ) {
e = p->tclass->setnum;
eErrSet = p->tclass->setnumErrSet;
}
else {
e = DefErrSet(&b, 0, TokenString(p->token));
eErrSet = DefErrSetWithSuffix(0, &bErrSet, 1, TokenString(p->token), "_errset");
p->tclass->dumped = 1; /* indicate set has been created */
p->tclass->setnum = e;
p->tclass->setnumErrSet = eErrSet; /* MR23 */
}
sprintf(buf, "%s_set", TokenString(p->token));
sprintf(bufErrSet, "%s_errset", TokenString(p->token)); /* MR23 */
set_name = buf;
set_nameErrSet = bufErrSet; /* MR23 */
}
/* MR23 - Forgot about the case of ~TOKCLASS. */
else if ( p->tclass!=NULL && complement != 0 /* MR23 */)
{
static char buf[MaxRuleName+20]; /* MR23 */
static char bufErrSet[MaxRuleName+20]; /* MR23 */
if ( p->tclass->dumpedComplement ) {
e = p->tclass->setnumComplement;
eErrSet = p->tclass->setnumErrSetComplement;
}
else {
e = DefErrSetWithSuffix(0, &b, 0, TokenString(p->token), "_setbar");
eErrSet = DefErrSetWithSuffix(0, &bErrSet, 1, TokenString(p->token), "_errsetbar");
p->tclass->dumpedComplement = 1; /* indicate set has been created */
p->tclass->setnumComplement = e;
p->tclass->setnumErrSetComplement = eErrSet; /* MR23 */
}
sprintf(buf, "%s_setbar", TokenString(p->token));
sprintf(bufErrSet, "%s_errsetbar", TokenString(p->token)); /* MR23 */
set_name = buf;
set_nameErrSet = bufErrSet; /* MR23 */
}
else { /* wild card */
static char buf[sizeof("zzerr")+10];
static char bufErrSet[sizeof("zzerr")+10];
int n = DefErrSet( &b, 0, NULL );
int nErrSet = DefErrSetWithSuffix(0, &bErrSet, 1, NULL, "_set");
if ( GenCC ) sprintf(buf, "err%d", n);
else sprintf(buf, "zzerr%d", n);
if ( GenCC ) sprintf(bufErrSet, "err%d", nErrSet);
else sprintf(bufErrSet, "zzerr%d", nErrSet);
set_name = buf;
set_nameErrSet = bufErrSet;
}
if ( !FoundException ) {
/* MR23 */ gen2("zzsetmatch(%s, %s);", set_name, set_nameErrSet);
}
else if ( p->ex_group==NULL ) {
if ( p->use_def_MT_handler )
gen3("zzsetmatch_wdfltsig(%s,(ANTLRTokenType)%d,%s);",
set_name,
p->token,
tokenFollowSet(p))
else
gen2("zzsetmatch_wsig(%s, %s_handler);",
set_name,
handler_id);
}
else
{
gen1("if ( !_setmatch_wsig(%s) ) {\n", set_name);
tabs++;
/* MR6 */ if (FoundGuessBlk) {
/* MR6 */ if ( GenCC ) {gen("if ( guessing ) goto fail;\n");}
/* MR6 */ else gen("if ( zzguessing ) goto fail;\n");
/* MR6 */ };
gen("_signal=MismatchedToken;\n");
dumpException(p->ex_group, 0);
tabs--;
gen("}\n");
}
set_free(b);
set_free(bErrSet);
}
else if ( TokenString(p->token)!=NULL )
{
if ( FoundException ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -