我正在使用Antlr 4.5在Java中编写c#语法。当我在处理带有预处理器指令的c#源代码时。示例代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Hansa
{
class Program
{
public static void Main()
{
int b = 5;
#if true
int c = 0;
#if false
union {
internal struct {
uint pmclass;
ushort pmenum;
};
ushort bseg;
byte[] Sym;
internal struct {
uint index;
string name;
} btype;
} pbase;
#endif
printMe(c);
#endif
printMe(b);
Console.ReadLine();
}
public static void printMe(int val)
{
Console.WriteLine(val);
}
}
}
在上面的代码示例中,位于"#if false"和下一个"#endif"之间的代码会生成一个错误"no viable alternative at input 'union {'"
我需要忽略代码级别的这个错误,或者通过语法忽略行。
在上面的代码中,如果我没有任何错误,我可以得到名称空间名称,类名称,方法名称,方法签名和语句行。当我在"union{"附近得到错误时,我能够到达命名空间名称,类名称,Main()方法名称,但我无法到达printMe()方法声明。
我的要求是,当发生错误时,不应该终止语法解析。从下一行开始,一直到EOF。
您必须重写ANTLR4错误恢复。DefaultErrorStrategy
将报告NoViableAlternativeException
,然后恢复。它不会中断解析。因此,如果程序在第一个错误时中断:
- 也许你用了另一个
ANTLRErrorStrategy
。然后调整它,它恢复像DefaultErrorStrategy
- 或者你的
ANTLRErrorListener
中断了程序,那么你将不得不以一种跳过失败的方式调整这个。
如果您希望错误恢复确实在下一行开始,则必须调整方法ErrorStrategy.recoverXXX
。默认情况下,错误恢复尝试删除/插入魔术令牌,以达到干净的状态。