【问题标题】:ANTLR: What is the fastest way to get grammar tree?ANTLR:获取语法树的最快方法是什么?
【发布时间】:2011-04-08 13:51:23
【问题描述】:

获取语法树的最快(更小的代码)方法是什么?

我正在尝试获取语法树。我已经根据我的简单语法生成了 C# 代码:

grammar MyPascal;
options
{
    language=CSharp3;
    output=AST;
}

operator: (block | ID);
block   : BEGIN operator* END;
BEGIN   :'begin';
END     :'end';
ID      :('a'..'z')+;
WS      :( ' '
        | '\t'
        | '\r'
        | '\n'
        ) {$channel=HIDDEN;};

当我使用 ANTLR 时,它适用于简单的输入文本,例如:

input.txt:
begin
  abs
  qwe
  begin
    begin
    end
  end
end

我得到了很好的语法树图片。

现在我想知道是否有任何简单的方法可以在不编写 1000 行代码的情况下从 C# 获取我的“程序”的树结构。

我在这里尝试获取语法树:

class Program
{
    static void Main(string[] args)
    {
        MyPascalLexer lex = new MyPascalLexer(new ANTLRFileStream(@"M:\input.txt"));
        CommonTokenStream tokens = new CommonTokenStream(lex);
        MyPascalParser g = new MyMyPascalParser(tokens);
        MyPascalParser.myprogram_return X = g.myprogram();                                       
        Console.WriteLine(X.Tree);  // Writes: nill
        Console.WriteLine(X.Start); // Writes: [@0,0:4='begin',<4>,1:0]
        Console.WriteLine(X.Stop);  // Writes: [@35,57:57='end',<19>,12:2]
    }
}

【问题讨论】:

    标签: c# antlr


    【解决方案1】:

    你必须“告诉” ANTLR 来构建一个 AST,而不是仅仅一个扁平的标记流(简单的解析树)。

    请参阅this SO Q&A,它展示了如何在 C# 中执行此操作。

    另外,你不应该使用:

    ID : ('a'..'z')*;
    

    即:让词法分析器规则匹配一个空字符串,这可能(甚至会?)给你带来麻烦(它总是匹配!)。您需要让它匹配至少一个字符:

    ID : ('a'..'z')+;
    

    【讨论】:

    • 你是对的。在询问紧凑尺寸的问题之前,我已经剪掉了一些。我现在已经修复了这些错误。
    • :) 我在这个链接中找到了我的问题的答案。所以我接受你的回答。作为示例,我添加了 2 行: 1:使用 Antlr.Runtime.Tree; 2:CommonTree 树 = (CommonTree)Q.Tree;它有效:)
    • @Astronavigator,不客气,很高兴听到您找到了问题的解决方案。
    猜你喜欢
    • 2017-10-25
    • 1970-01-01
    • 1970-01-01
    • 2014-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多