我不熟悉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 ,而3
,5
和4
将由Lex返回为 INTEGER 。但是,在Yacc中,根据语法,由于VARIABLE可以推导为expr,表达式将变为:expr = expr '+' expr
那么如何将其缩小为VARIABLE '=' expr { sym[$1] = $3; }
?
感谢任何帮助。
由于
答案 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 */
%%