用Lex和Yacc解析(简单计算器)

时间:2016-03-23 13:49:16

标签: parsing yacc lex

我不熟悉Lex& Yacc编程和语法入门。我在网上浏览这个程序,并一直试图理解它。以下是一个简单计算器的Lex和Yacc代码片段:

Lex规则

%% 
[a-z]       {
                 yylval = *yytext - 'a';
                 return VARIABLE;
             }
[0-9]+      {
                 yylval = atoi(yytext);
                 return INTEGER;
             }
[-+()=/*\n] { return *yytext; }

[ \t]      ;
.               yyerror("invalid character");
%% 

YACC语法

%%  
program:
         program statement '\n'
         |
         ;

statement:
         expr                      { printf("%d\n", $1); }
         | VARIABLE '=' expr       { sym[$1] = $3; }
         ;  

expr:
         INTEGER
         | VARIABLE                { $$ = sym[$1]; }
         | expr '+' expr           { $$ = $1 + $3; }
         | expr '-' expr           { $$ = $1 - $3; }
         | expr '*' expr           { $$ = $1 * $3; }
         | expr '/' expr           { $$ = $1 / $3; }
         | '(' expr ')'            { $$ = $2; }
         ;
%%

任何人都可以帮我逐步理解输入表达式x = 3 + 4将如何处理/解析?

根据我的理解,在处理输入时,' x'将返回 VARIABLE ,而354将由Lex返回为 INTEGER 。但是,在Yacc中,根据语法,由于VARIABLE可以推导为expr,表达式将变为:expr = expr '+' expr

那么如何将其缩小为VARIABLE '=' expr { sym[$1] = $3; }

感谢任何帮助。

由于

2 个答案:

答案 0 :(得分:2)

x被转移; =被转移; 3,+,4被转移;然后3+4匹配添加生产,减少到expr,然后允许减少分配生产。您需要记住 yacc 是一个自下而上的解析器。

答案 1 :(得分:0)

在这里,我尝试逐行解释您的 lex 规则 部分。在下一篇文章中,我将尝试对您的 YACC 语法部分进行解释。

    //----------LEX Rule Section----------  pattern   <->   {co-responding action}
    // yytext :
    // What actualy yytext does is: it acts like a pointer which points the location of current charchter reading on  
    // as i said, this yytext is pointer for lex/flex file . So ,to access  the value of yytext . We need * before it.
    // yylaval:
    // it pass the semantic value of a token from the lexer(lex/flex file or .l file) to the parser(yacc/bison file or .y file)
    // Or you can say this yylval returns value associated token
    // yyerror()
    // when yyparse() is called it automatically invoke yyerror() when any syntax error arise
%% 

[a-z]       {/* Consider a case where user is is giving input as 'f-a' or 'b+c' . As this is calculator programme So we are handling this case by converting these input as ascii value   */
                 yylval = *yytext - 'a'; /* Current value of yytext minus ascii value 'a' is stored into yylval */
                 return VARIABLE;  /* here VARIABLE specified non-terminal for .y file */
             }
[0-9]+      {
                 yylval = atoi(yytext); /* atoi() is a lirary function of stdlib.h . it converts the string argument to an integer value*/ 
                 return INTEGER; /* here also INTEGER specified non-terminal for .y file */
             }

[-+()=*/]   { return *yytext; } /* inside [] bracket, elements are considered as charchter set,if any element matched then fire the action section

[ \t]      {;} /* if any space or tab encounters then here action section is to do nothing */
.          { yyerror("invalid character"); } /* actually . means all charchters except new line */
                                             /* But here we introduced . at the end of rule section,So this . means all other charchters except above specified pattern and except new line */ 
%%