我正在编写一个包含flex和bison的解析器,到目前为止还有这些for flex的标记:
[ \t\n] ;
(x[0-9]+) {
yylval.var = strdup(yytext);
return VARIABLE;
}
~(x[0-9]+) {
yylval.var = strdup(yytext);
return NEG_VARIABLE;
}
[a-zA-Z0-9]+ {
yylval.name = strdup(yytext);
return NAME;
}
~[a-zA-Z0-9]+ {
yylval.name = strdup(yytext);
return NEG_NAME;
}
[\{\},\(\)] { return yytext[0];}
. ;
这些野牛的解析规则是:
fol:
clauses {cout << "Done with file"<<endl;}
;
clauses:
clauses clause
| clause
;
clause:
startc terms endc
;
startc:
'{' {cout << "Bison found start of clause" << endl;}
;
endc:
'}' {cout << "Bison found end of clause" << endl;}
;
function:
NAME startfun endfun {cout << "Bison found a function " << $1 << endl;}
|NEG_NAME startfun endfun {cout << "Bison found a negative function " << $1 << endl;}
;
startfun:
'(' {cout << "Bison found start of params" << endl;}
;
endfun:
terms ')' {cout << "Bison found a function end" << endl;}
;
terms:
terms ',' term
| term
;
term:
VARIABLE {cout << "Bison found a variable "<< $1 << endl;}
| NEG_VARIABLE {cout << "Bison found a negative variable " << $1 << endl;}
| NAME {cout << "Bison found a constant " << $1 << endl;}
|function
;
现在一切都很好,除了当它解析一个函数时,它首先解析参数 和parens然后给我最后的功能名称。我可以解决这个问题,但是由于我将函数存储为不相交的集合,因此我的生活更加困难,我需要保留一个参数列表,直到我可以获取函数的名称来创建根,然后将它们联合起来直接创建它。
有人能告诉我如何让Bison在参数前给我一个函数名吗?我已经尝试了一个多小时而没有运气。
答案 0 :(得分:2)
“在参数前给我功能名称”是什么意思?目前,在看到endfun
并减少功能规则之前,不会打印功能名称,这是在各种参数规则之后。通常的技术是让术语规则生成一个事物列表,然后可以在函数规则中使用:
terms: terms ',' term { $$ = append_list($1, $3); }
| term { $$ = create_singleton_list($1); }
;
term: VARIABLE { $$ = new VariableTerm($1); }
...
或者,如果您只想打印出来的东西,只要看到一个功能名称,就可以减少规则:
function: funcname startfun endfun {cout << "Bison ending a function " << $1 << endl;}
;
funcname: NAME { cout << "Starting a function " << ($$ = $1) << endl; }
| NEGNAME { cout << "Starting a negative function " << ($$ = $1) << endl; }
;