Bison 规则永远不会减少,明白为什么吗
我正在学习与YACC合作,我真的无法理解一些错误。我想知道当我试图用.y文件生成解析器时,为什么会出现这个错误。这是my.y文件,它表示Pascal语言的上下文无关语法:Bison 规则永远不会减少,明白为什么吗,bison,yacc,Bison,Yacc,我正在学习与YACC合作,我真的无法理解一些错误。我想知道当我试图用.y文件生成解析器时,为什么会出现这个错误。这是my.y文件,它表示Pascal语言的上下文无关语法: %% Program : program ident ';' declaration_opc compound_stmt '.' ; declaration_opc : var declaration_list | ; declaration_list : declaration ';' dec
%%
Program : program ident ';' declaration_opc compound_stmt '.'
;
declaration_opc : var declaration_list
|
;
declaration_list : declaration ';' declaration_list
| declaration ';'
;
declaration : id_list ':' type
;
id_list : ident
| ident ',' id_list
;
type : integer
| BOOLEAN
;
proc_dec : proc_header forward ';'
| proc_header declaration_list compound_stmt
| func_header forward ';'
| func_header declaration_list compound_stmt
;
proc_header : procedure ident parametros ';'
;
func_header : function ident parametros : type
;
parametros : '(' param_list ')'
|
;
param_list : arg
| arg ';' param_list
;
arg : id_list ':' type
| var id_list ':' type
;
compound_stmt : begin statement_list end
;
statement_list : statement ';' statement_list
| statement
;
statement : ident attrib expression
| IF expression then statement
| IF expression then statement ELSE statement
| WHILE expression DO statement
| compound_stmt
| readln ident
| writeln print_list
|
;
print_list : literal print_list2
| expression print_list2
;
print_list2 : ',' print_list
|
;
expression : add_expression relop add_expression
| add_expression
;
relop : lessequal
| '<'
| '>'
| moreequal
| '='
| notequal
;
add_expression : add_expression addop term
;
addop : '+'
| '-'
| or
;
term : term mulop unary_exp
| unary_exp
;
mulop : '*'
| div
| mod
| and
;
unary_exp : not unary_exp
| factor
;
factor : '(' expression ')'
| ident
| num
| TRUE
| FALSE
;
%%
有什么可能的解决办法?我发现其他人也有同样的错误,但我没能找到对我的问题有用的东西。如果需要更多信息,我将提供。我还读到“Rules never reduced”错误意味着我的语法中的一些规则从未被使用过,但我无法从我的规则中看出这一点 文件不完整,因为有许多从未定义过的标记(例如
布尔值
)。如果它是完整的,我们可以给出一个更好的答案
一般来说,未简化的规则(就yacc所能确定的范围而言)不会通过任何一系列步骤连接到启动状态。所以它们是你应该重新设计或移除的碎片
以下是一些以前讨论过的地方:
proc_dec
永远不会出现在任何其他规则的右侧,因此从您的开始符号(程序
)永远无法到达该规则。Yacc只是告诉您,这个规则(以及它使用的所有规则,而不是其他任何规则)是不可访问的
通常,您希望使用
-v
选项让yacc生成一个y.output
文件,其中包含有关语法的详细信息。此文件将具体告诉您所有冲突和未使用的规则——它们是什么以及它们是如何产生的——而这些消息只是为您提供问题的摘要。在本例中,您有两个基本的问题来源。一个是你根本没有在你的程序语法中包含过程。您可能会通过以下方式解决此问题:
Program : program ident ';' declaration_opc procedures compound_stmt '.'
;
procedures: proc_dec
| procedures ';' proc_dec
;
add_expression : add_expression addop term
| term addop term
;
[我已经有一段时间没有编写任何Pascal了——我不记得是否需要分号来分隔过程,但如果不需要,就可以删除它。]
第二个问题是add\u表达式的语法总是无限递归的:
add_expression : add_expression addop term
;
您没有在左侧包含任何停止递归的内容。您可能需要以下内容:
Program : program ident ';' declaration_opc procedures compound_stmt '.'
;
procedures: proc_dec
| procedures ';' proc_dec
;
add_expression : add_expression addop term
| term addop term
;
对于像a+b-c
这样的表达式,它将匹配第一个选项为:(a+b)add_expression-addop字符m,第二个选项将用于仅匹配a+b
部分为:aterm+addop bterm。我已经编辑了您的标题。请参阅“”,其中的共识是“不,他们不应该”。使用yacc-v foo.y
,它将生成一个名为y.output
的文件。在该文件的结尾将是一个“从不减少的规则”列表。就目前而言,这是正确的,但仍然没有涵盖六个“从不减少的”规则…,谢谢,我不敢相信我看不到,没有减少的19个规则与proc_dec和参数有关,所以我肯定不是从开始符号开始调用它们。