yacc和lex学习概括

来源:互联网 发布:淘宝网苏泊尔电压力锅 编辑:程序博客网 时间:2024/05/16 01:15
1、yacc的yyparse()调用lex的yylex()取得token,将token压入堆栈;

2、yacc查看栈顶是否有可归约串,如没有,继续取得token入栈:这是移进(shift);
如果栈顶有可归约串,则归约为一个非终结符(在.y文件里定义的),并将该非终结符
入栈,然后继续(2),查看是否有可归约串,直到栈顶没有可归约串:这是归约(reduce);

3、yacc对可归约串进行归约时,同时执行.y文件里对应产生式的动作。
 如产生式 Expression:      | Expression PLUS Expression    { $$=$1+$3; }

4、一个非终结符(如上面的Expression),它的产生式是非终结符最重要的性质定义,yacc
就是根据产生式进行"移进-归约"而运作的

5、一个非终结符同时可以关联一个值(sematic value),这个值的类型可以是int、char、
char*或任何其他结构和指针。值的类型在.yy中定义:
%union {
       char cval;
       char *sval;
       int  nval;
       double fval;
}
yacc产生的代码将这个union用typedef成YYSTYPE,同时定义一个全局变量yylval。在.lex文
件中可以用yylval.cval或yylval.sval等来设置对应的值。在.y文件里用
%token <nval> TOK 或
%type  <nval> UNDETEM 来定义token或非终结符的类型后,该token的值$$或$n就被定义为
YYSTYPE::nval类型,使用$$、$n就可以直接访问到int或char *等类型了。

6、在.y文件的%left和%right可以定义左结合、右结合和优先级,如
%left   PLUS    MINUS
%left   TIMES   DIVIDE
%right  POWER
定义了结合的方向,同时POWER的优先级比TIMES、DIVIDE,TIMES、DIVIDE比PLUS、MINUS高。