我正在尝试从If-Else语句中的错误中恢复。 在我的语法中,If总是跟着Else。
statement: OBRACES statements CBRACES
| IF OPAR exp CPAR statement ELSE statement
| IF OPAR exp CPAR statement error '\n' { yyerrok; yyclearin;}
;
发现的错误位于最后一行的注释中:
public boolean Equal(Element other){
if (!this.Compare(aux01,Age))
ret_val = false ;
//else
//nt = 0 ;
}
错误:语法错误,意外的CBRACES,期待ELSE - > } @第29行
它没有从该错误中恢复而忽略了之后发生的错误。
也许我不太清楚这个错误是如何工作的,但我只能在每个网站上找到2个关于错误恢复的例子:“错误'\ n'”和“'('错误')'”
任何人都知道如何从这个错误中恢复(当一个if后面没有else时)。
由于
答案 0 :(得分:2)
你没有提供足够的上下文来确切知道,但我的猜测是lexer / tokenizer,它向你的解析器提供令牌,跳过空格 - 包括'\ n'。所以解析器永远不会看到换行符和b / c永远不会减少
IF OPAR exp CPAR statement error '\n'
生产及其行动
{ yyerrok; yyclearin;}
永远不会执行,因此错误无法恢复。
答案 1 :(得分:2)
可能(虽然很难说没有看到更多的语法),但在找不到else
的情况下你不需要跳过任何标记。
最可能的情况是该程序只缺少一个else
子句(可能是因为它的作者习惯于else
是可选的其他编程语言),并且解析可以简单地继续有一个空else
子句。所以你应该可以使用:
IF OPAR exp CPAR statement error { yyerrok; }
(注意:我删除了yyclearin
,因为您几乎肯定不想这样做。如果OP中出现错误,结果将是忽略' }'令牌,稍后在解析中导致无关的错误。)
您可能应该利用此错误生成中的操作来生成明确的错误消息(“如果语句必须具有else子句”),尽管默认消息也相当清楚。
当然,无论使用何种令牌作为错误上下文,都必须由扫描仪生成。这通常会排除错误恢复技术,例如“跳到行尾”,除了新行具有语法重要性的语言。
答案 2 :(得分:0)
我发现了问题。无论如何,谢谢你的帮助。
我把错误放在大括号内,现在正在工作。
statement: OBRACES statements CBRACES
| OBRACES error CBRACES { yyerrok; yyclearin;}
| IF OPAR exp CPAR statement ELSE statement
;