野牛C++缺少分号的多个错误恢复
Bison C++ multiple error recovery with missing semi colon
我正在开发自己的编译器,我在错误恢复设计方面遇到了问题在 Java 语法的恐慌模式下。
我想过多种解决方案,但真正的问题是:
我如何使用野牛 c++ 做到这一点?
我做到了:
套餐 2
导入 java.lang.*;
错误必须消耗到第一个分号,并且这使用规则正确运行
package_rule:包错误";"
但是如果我写了这段代码:
套餐 2
导入 java.lang.*
类 y { void method() { int m }
}
我需要像标准编译器一样从解析器中报告错误:
标识符应位于包装行。 缺少";"在导入说明行中报告包的";"。 在 int m 行上键入";"。
我的意思是我需要在包错误后使用令牌,直到第一个分号或在最后一行找到类或接口声明时停止,然后再声明它们! 并报告在行后发现的任何其他错误:
int m//缺少 ';'
请帮助我,在我看来有多种解决方案,但是如何使用 Bison C++ for Java 语法做到这一点?
你不会介意用C++ OOP的方式解决这个问题,而不是用野牛的方式,对吧?
假设您定义了这些类型的 AST 节点
struct BaseExpression {
virtual std::string toIdentifier() = 0;
// other member. remember to declare a virtual destructor
};
struct IntLiteral : BaseExpression {
std::string toIdentifier() {
error::toAnIdentifier();
return "";
}
};
struct Identifier: BaseExpression {
std::string ident;
explicit Identifier(std::string id) : ident(id) {}
std::string toIdentifer() {
return ident;
}
};
定义这样的规则
%union {
BaseExpression* expr_type;
}
%type <expr_type> simple_expr
package_expr: simple_expr
{
$1->toIdentifer(); // thus integers or float numbers would generate errors
// do sth with that identifer
}
;
package_expr: package_rule '.' simple_expr
{
$3->toIdentifer(); // same trick
// do sth with that identifer
}
;
simple_expr
在哪里
simple_expr: int_literal { return new IntLiteral; }
| ...
| identifier { return new Identifier(yytext); }
;
好吧,您的基本问题是您希望它如何尝试从语法错误中恢复。 当你有一个输入序列,如
package x import
你希望它假设那里应该有一个分号,还是希望它假设在分号之前有其他东西卡住了,它应该扔掉东西,直到它到达分号?
后者就是你所拥有的 - 规则package: PACKAGE error ';'
正是这样做的 - 每当它看到关键字PACKAGE
但它后面的内容与package
规则的其余部分不匹配时,它应该丢弃输入,直到它看到一个';'
并尝试从那里继续。
如果你想要前者,你可以使用像package: PACKAGE name error
这样的规则——如果它看到PACKAGE
看起来像一个有效的包名称但没有分号的东西,把它当作那里有一个分号,然后尝试继续。
让它能够同时完成上述两件事是非常困难的。 最接近的是让语法看起来像这样:
package: PACKAGE name ';' /* normal package decl */
| PACKAGE name /* missing semicolon -- treat this as a semantic error */
| PACKAGE error ';' /* no name -- skip up to the next semicolon to recover */
但是,这种事情可能会给您带来难以解决的语法冲突。
- 警告处理为错误这里有什么问题
- "error: no matching function for call to"构造函数错误
- boost::进程间消息队列引发错误
- C++,OpenCV,尝试显示图像时"OpenCV(4.3.0) Error: Assertion failed (size.width>0 && size.height>0)"此错误
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- QT在错误的班级中寻找空位
- vector.resize()中的分配错误
- 代码在main()中运行,但在函数中出现错误
- 释放错误后堆使用
- (C++)分析树以计算返回错误值的简单算术表达式
- Project Euler问题4的错误解决方案
- 从 Qt 中的错误中恢复
- 是否可以使用GetLastError检查错误代码是否已恢复
- 异常处理和从非致命错误中恢复
- 从无法到达的矢量错误中恢复
- 从分段错误中恢复的最佳实践
- 发生错误后,cuFFT无法恢复
- 期望可恢复的函数实际上在原始线程中恢复是错误的吗
- 如何从COM错误中正常恢复
- 野牛C++缺少分号的多个错误恢复