АНТЛР: Какой самый быстрый способ получить дерево грамматики? - PullRequest
0 голосов
/ 08 апреля 2011

Какой самый быстрый (меньший код) способ получить грамматическое дерево?

Я пытаюсь получить грамматическое дерево.Я сгенерировал код 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

, я получаю красивую картину дерева грамматики.

Теперь мне интересно, есть ли какой-нибудь простой способ получить древовидную структуру моей "программы" из 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]
    }
}

1 Ответ

1 голос
/ 08 апреля 2011

Вы должны будете "сказать" ANTLR, чтобы построить AST, а не просто плоский поток токенов (простое дерево разбора).

См. это SO Q & A , которая показывает, какчтобы сделать это в C #.

Кроме того, вы не должны использовать:

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

, то есть: пусть правило лексера соответствует пустой строке, это может (или даже будет?) привести вас впроблема (это всегда соответствует!).Вы хотите, чтобы он совпадал хотя бы с одним символом:

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