Antlr4 从错误中恢复并继续解析直到 EOF

Antlr4 recover from error and continue parsing until EOF

我正在使用 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 {'"。

我需要在代码级别忽略此错误或通过语法忽略行。

在上面的代码中,如果我没有任何错误,我可以获得命名空间名称、class名称、方法名称、方法签名和语句行。 当我在 "union {" 附近遇到错误时,我可以访问命名空间名称、class 名称、Main() 方法名称,但无法访问 printMe() 方法声明。

我的要求是,当出现错误时,语法解析不应该终止。它应该从下一行继续到 EOF。

我怎样才能做到这一点?

您将不得不重写 ANTLR4 错误恢复。 DefaultErrorStrategy 将报告 NoViableAlternativeException 然后恢复。它不会中断解析。因此,如果您的程序因第一个错误而中断:

  • 也许您使用另一个 ANTLRErrorStrategy。然后调整它,让它像DefaultErrorStrategy
  • 一样恢复
  • 或者您的 ANTLRErrorListener 中断了程序,那么您将不得不调整它以跳过失败的方式。

如果您希望错误恢复确实从下一行开始,则必须调整方法 ErrorStrategy.recoverXXX。默认情况下,错误恢复会尝试 delete/insert 个魔法令牌,以达到干净状态。