2010-12-16 80 views
2

这个微小的yacc程序是如何工作的?yacc是如何工作的,你可以逐节解释它吗?

我知道到目前为止什么:

%{...%}是定义 %% ... %%是规则的,但如何解释规则? 和%%之后的东西是函数定义。 %}%%之间的%token INTEGER是什么?

%{ 
#include <stdlib.h> 
int yylex(void); 
void yyerror(char *); 
%} 
%token INTEGER 
%left '+' '-' 
%left '*' '/' 
%% 
program: 
program expr '\n' { printf("%d\n", $2); } 
| 
; 
expr: 
INTEGER { $$ = $1; } 
| expr '*' expr { $$ = $1 * $3; } 
| expr '/' expr { $$ = $1/$3; } 
| expr '+' expr { $$ = $1 + $3; } 
| expr '-' expr { $$ = $1 - $3; } 
; 
%% 
void yyerror(char *s) { 
printf("%s\n", s); 
} 
int main(void) { 
yyparse(); 
return 0; 
} 

UPDATE

我不明白:

program: 
program expr '\n' { printf("%d\n", $2); } 
| 
; 

回答

1

的EXPR:一个装置,一个expr是下列选项,由分隔的一个|下面。如果它可以被看作是一个INTEGER标记,那么它就是第一个。如果它可以被看作是一个expr,然后是'*'字符后跟一个expr,那么它会采用第二个选项,依此类推。 $$是默认的返回值,$ 1是第一个标记,第二个是$ 2。

所以如果是解析5 + 6,它会将其视为expr'+'expr,因此它将采用第4个定义。它返回11作为expr,所以它匹配11作为INTEGER标记并将11作为返回值。

如果我们解析一个程序标记后跟5 + 6,它会做同样的事情来获得程序11,然后采取程序expr规则,并调用打印到屏幕上的c代码。

左表示运算符为左关联。如在a + b + c =(a + b)+ c中。同一行上的操作员具有相同的总裁,而下面的操作员具有较低的总裁。

我承认在一段时间内没有使用yacc,所以随时告诉我我完全错了。

UPDATE:

YACC生成C代码,这样你就可以直接把自己的代码到它。所以当它解析时,如果它看到一个“程序表达式”,那么它可以直接将{}中的代码输入到生成的代码中。

1

总共有编译器即五个阶段:

  1. 词法分析
  2. 语法分析
  3. 语义分析(中间代码生成-可选)
  4. 代码优化
  5. 代码生成

lex和YACC(另一个编译器编译器)都是生成程序的Unix实用程序.lexer负责匹配给定程序中的单词,当匹配被找到时,它将值存储在yylex中,并以令牌的形式返回给词法分析器。 yacc基本上是一个解析器,它接受令牌并从中构建一棵树来检查程序的语法。令牌由词法分析器构建,并在yacc规范文件中声明。 所以y.tab.h文件包含在lex程序中。

上述程序包含一个由词法分析器返回的令牌INTEGER。 yacc程序应该包含一个开始状态...“程序”是开始状态,每个程序应该包含至少一个开始状态... yacc规则的格式是规则{action} 。在上面的程序“program expr'\ n'表示程序可以包含表达式,然后是换行符。即5 + 4'输入键'表示我们写了expr'+'expr的表达式;这里expr在这种情况下可以是5和4,所以我们通过写入expr来包含该规则:INTEGER ....或者任何其他角色,表达的LHS由$$和RHS表示为$ 1,$ 2,$ 3 ...等等。表达式:expr'+'expr {$$ = $ 1 + $ 3;} .... ..

+0

这看起来像是一个很好的答案,但如果格式更好,它会更清晰。我已经清理了我现在可以使用的部分,而无需更改您写得太多的内容,但是您也可以参阅http://stackoverflow.com/editing-help。 – Flexo 2011-11-08 13:02:18

相关问题