Antlr4cs:相同的语法与Java工具不同的结果

本文关键字:工具 结果 Java 语法 Antlr4cs | 更新日期: 2023-09-27 18:35:14

我已经按照这里的说明进行操作:https://github.com/sharwell/antlr4cs/wiki 和这里:http://www.antlr.org/wiki/display/ANTLR4/Getting+Started+with+ANTLR+v4

我已经从开头的例子中改变了我的语法,但它适用于Java工具(antlr4.bat和grun.bat),但不适用于由sharwell wiki配置的控制台应用程序。

Java(在只有 Hello.g4 文件的文件夹中):

antlr4 Hello.g4
javac *.java
grun Hello prog -gui
I then type "hello world" then Return then "^Z" then Return
The gui pops up an matches my grammar correctly

C#(唯一的区别是 Java 版本中不使用 @parser 和 @lexer 指令)

你好.g4:

grammar MetaMeta;
@parser::members
{
protected const int EOF = Eof;
}
@lexer::members
{
protected const int EOF = Eof;
protected const int HIDDEN = Hidden;
}
prog    :   stmt NL* EOF;
stmt    :   hello eos;
hello   :   HELLO ID;
eos     :   ';' | NL;
HELLO   :   'hello';
ID      :   [a-z]+;
NL      :   ''r'? ''n';
WS      :   [ 't]+ -> skip;

课程.cs:

    private static void Main(string[] args)
    {
        (new Program()).Run();
    }
    public void Run()
    {
        var text = "hello world'n";
        try
        {
            Console.WriteLine("START");
            RunParser(text);
            Console.Write("DONE. Hit RETURN to exit: ");
        }
        catch (Exception ex)
        {
            Console.WriteLine("ERROR: " + ex);
            Console.Write("Hit RETURN to exit: ");
        }
        Console.ReadLine();
    }
    private void RunParser(string text)
    {
        var input = new AntlrInputStream(text);
        var lexer = new MetaMetaLexer(input);
        var tokens = new CommonTokenStream(lexer);
        var parser = new MetaMetaParser(tokens);
        var context = parser.prog();
        var visitor = new MyVisitor();
        visitor.VisitProg(context);
    }

运行程序时,我得到以下内容:

START
HelloVisitor VisitProg
 Visit Symbol=<EOF>
DONE. Hit RETURN to exit:

我的访问者与 cs wiki 上的代码示例相同。 感谢您的任何帮助。 ;)斯科特

Antlr4cs:相同的语法与Java工具不同的结果

如果您在此处包含访问者代码,您将更快地收到答案。

您使用的访问者不会覆盖AbstractParseTreeVisitor<Result>.VisitTerminal(ITerminalNode) 。因此,每次到达终端节点时都会使用此方法的默认实现,它只返回 DefaultResult()(默认情况下只是 default(Result) )。

修改后的访客代码如下:

public class MyVisitor : AbstractParseTreeVisitor<object>
{
    public override object VisitTerminal(ITerminalNode node)
    {
        var text = node.Symbol.Text;
        if (text == "'n")
            text = @"'n";
        Console.WriteLine(" Visit Symbol={0}", text);
        return base.VisitTerminal(node);
    }
}

修改后的调用代码如下:

    private void RunParser(string text)
    {
        var input = new AntlrInputStream(text);
        var lexer = new MetaMetaLexer(input);
        var tokens = new CommonTokenStream(lexer);
        var parser = new MetaMetaParser(tokens);
        var context = parser.prog();
        var visitor = new MyVisitor();
        visitor.Visit(context); //changed to just Visit
    }

为了完整起见,我添加了这个,但将上面的正确答案授予了山姆。

谢谢斯科特