【问题标题】:Parsing with Lex and Yacc (Simple Calculator)使用 Lex 和 Yacc(简单计算器)进行解析
【发布时间】:2021-06-04 05:03:13
【问题描述】:

我是 Lex 和 Yacc 编程的新手,刚刚开始学习语法。我在网上看到了这个程序,并一直试图理解它。以下是用于简单计算器的 Lex 和 Yacc 代码-sn-ps:

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 将返回为 INTEGER强 > 由莱克斯。但是,在 Yacc 中,根据语法,由于可以将 VARIABLE 推导出为 expr,因此表达式将变为:expr = expr '+' expr

那么这将如何减少得到VARIABLE '=' expr { sym[$1] = $3; }

感谢任何帮助。

谢谢

【问题讨论】:

标签: parsing yacc lex


【解决方案1】:

x 被移位; = 被转移; 3,+,4 被转移;然后3+4 匹配加法产生式,减少到expr,然后允许减少分配产生式。你需要记住 yacc 是一个自底向上的解析器。

【讨论】:

  • expr: INTEGER 规则也有两个缩减(在移动 34 之后立即),它们只是值的简单副本。
  • 好的,知道了...还有一个问题 - yylval 和 yytext 有什么区别?
  • @EJP:还有这个生产:expr = VARIALBLE。所以在解析时,表达式 x = 3 + 4 不会变成 expr = expr + expr 吗?如果是,那么它将如何与 Production VARIABLE = expr 匹配?因为 VARIABLE 已经被缩减为 expr ?
  • yytext 是 lex 扫描器用来识别令牌的缓冲区。 yylval 是 lex 扫描器发送给 yacc 解析器的属性值,用于返回它的令牌。
【解决方案2】:

在这里,我试图逐行解释您的 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 */ 
%% 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多