我正在尝试进行基本的编译器解析并解释一个简单的编程语言。我已经创建了我的上下文无关语法,并且已经尝试在YACC中实现它,但是我一直在使用#6; fules从未减少过#39;。这是我在yacc文件中的作品
%token BEGIN END INT INT_CONST STRING STRING_LIT TERM ID PRINT
%%
start : program
;
program: ID 'is' compound_statement
;
compound_statement: BEGIN statement_loop END; {;}
;
statement_loop: statement statement_loop
| statement
;
statement: ID '=' expr ';'
| ID'=' STRING_LIT ';'
| PRINT value_loop ';'
;
value_loop: value '.' value_loop
| value
;
value: STRING_LIT
| expr
;
expr: term_loop
| '-' term_loop
;
term_loop: term
| term '+' term_loop
| term '-' term_loop
;
term: factor_loop
;
factor_loop: factor_loop
| factor '*' factor_loop
| factor '/' factor_loop
;
declaration: INT id_loop
| STRING id_loop
;
id_loop: ID
| id_loop ','
;
factor: INT_CONST
| ID
'(' expr ')'
;
答案 0 :(得分:0)
factor_loop
没有非递归生产,所以它不能产生任何东西。您可能意味着第一次制作为factor_loop: factor
。
由于factor_loop
无法生成任何内容,因此依赖factor_loop
的所有作品也毫无用处。
该语法存在许多其他问题,因此可能存在其他错误消息。我没有看到任何可能导致减少 - 减少冲突的事情,这让我想知道你提供的是完整的文字语法文件。
一些问题:
在program
中,'is'
不是有效的单字符令牌。
END
compound_statement
之后有一个迷路分号。
declaration
未在任何地方使用。
id_loop
生成ID
后跟任意数量的逗号。因此,a,,,,
是有效的id_loop
,而不是a, b, c
。
如果第|
行第三行,我确定你错过factor
。
有太多正确的递归。在某些情况下,这只会产生过多的解析器堆栈使用,但对于算术运算符来说尤其严重,因为它会产生右关联,而且它们不是。
特别是,它将1 - 2 - 3
解析为1 - (2 - 3)
而不是正确的(1 - 2) - 3
一元减号的优先级太高了。您将最终解析-2 + 6
,就好像它已写为-(2 + 6)
一样,因此结果将是-8而不是4。