antlr - 在 ANTLR 中生成简单的 AST

标签 antlr antlr3 abstract-syntax-tree antlrworks

我正在尝试使用 ANTLR,并希望创建这样的函数:

MOVE x y z pitch roll

产生以下 AST:

 MOVE
   |---x
   |---y
   |---z
   |---pitch
   |---roll

到目前为止,我已经尝试过但没有成功,而且我一直在让 AST 将参数作为 sibling 而不是 child 。

到目前为止的代码:

C#:

class Program
{
    const string CRLF = "\r\n";

    static void Main(string[] args)
    {
        string filename = "Script.txt";

        var reader = new StreamReader(filename);
        var input = new ANTLRReaderStream(reader);
        var lexer = new ScorBotScriptLexer(input);
        var tokens = new CommonTokenStream(lexer);
        var parser = new ScorBotScriptParser(tokens);

        var result = parser.program();
        var tree = result.Tree as CommonTree;
        Print(tree, "");

        Console.Read();
    }

    static void Print(CommonTree tree, string indent)
    {
        Console.WriteLine(indent + tree.ToString());

        if (tree.Children != null)
        {
            indent += "\t";

            foreach (var child in tree.Children)
            {
                var childTree = child as CommonTree;

                if (childTree.Text != CRLF)
                {
                    Print(childTree, indent);
                }
            }    
        }            
    }

Ant 金服:

grammar ScorBotScript;

options
{
    language     = 'CSharp2';
    output       = AST;
    ASTLabelType = CommonTree;
    backtrack    = true;
    memoize      = true;
}

@parser::namespace { RSD.Scripting }
@lexer::namespace { RSD.Scripting }

program
    : (robotInstruction CRLF)*
    ;

robotInstruction
    : moveCoordinatesInstruction
    ;

/**
 * MOVE X Y Z PITCH ROLL
 */
moveCoordinatesInstruction
    : 'MOVE' x=INT y=INT z=INT pitch=INT roll=INT
    ;

INT : '-'? ( '0'..'9' )*
    ;

COMMENT
    :   '//' ~( CR | LF )* CR? LF { $channel = HIDDEN; }
    ;

WS
    :   ( ' ' | TAB | CR | LF ) { $channel = HIDDEN; }
    ;

ID  :   ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
    ;

STRING
    :  '"' ( ESC_SEQ | ~('\\'|'"') )* '"'
    ;

fragment
ESC_SEQ
    :   '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\')
    ;

fragment TAB 
    : '\t' 
    ;

fragment CR 
    : '\r' 
    ;

fragment LF 
    : '\n' 
    ;

CRLF
    : (CR ? LF) => CR ? LF
    | CR
    ;

parse
    : ID
    | INT
    | COMMENT
    | STRING
    | WS
    ;

最佳答案

我自己也是 ANTLR 的初学者,这也让我很困惑。

我想如果你想从你的语法中创建一个有结构的树,你可以使用 ^! 字符来增加你的语法。 This examples page显示如何。

来自链接页面:

By default ANTLR creates trees as "sibling lists".

The grammar must be annotated to with tree commands to produce a parser that creates trees in the correct shape (that is, operators at the root, which operands as children). A somewhat more complicated expression parser can be seen here and downloaded in tar form here. Note that grammar terminals which should be at the root of a sub-tree are annotated with ^.

关于antlr - 在 ANTLR 中生成简单的 AST,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4144067/

相关文章:

antlr - 如何在antlr中找到 token 的长度?

java - Antlr 解析的输入的最大大小

java - ANTLR - 语法和树语法之间的 token 枚举不匹配

c# - 基于ANTLR v3的成熟编译器

c++ - 如何在C++中获得Antlr 4规则名称?

java - if then else 条件判断

ruby - 从 Ruby block 中提取 AST

c - 如何使用 Clang 的 AST?

java - 如何使用 AST 转换编译混合 java groovy 项目?