ANTLR - Написание древовидной грамматики для AST - PullRequest
3 голосов
/ 11 февраля 2010

У меня есть AST, выведенный для некоторого кода Lua моим файлом грамматики, который в настоящее время выполняет синтаксический анализ и лексирование для меня. Я хочу добавить к этому древовидную грамматику, но так как я использую C #, я не уверен, как это сделать. Каков основной процесс генерации древовидного грамматического кода, когда у вас уже написаны парсер и лексер?

ОБНОВЛЕНИЕ: у меня есть следующий файл грамматики:

tree grammar LuaGrammar;

options {
  backtrack=true;
  language=CSharp2;
  //output=AST;
  tokenVocab=Lua;
  filter=true;
  ASTLabelType=CommonTree;
}
@lexer::namespace{/*my namespace*/}
@parser::namespace{/*my namespace*/}

dummyRule
    :   ^('=' x=. y=.) {};

находится в том же каталоге, что и мой основной файл грамматики, который генерирует нормально. Однако при попытке скомпилировать это я получаю следующие ошибки:

[02:54:06] error(143): C:\Users\RCIX\Desktop\AguaLua\Project\trunk\AguaLua\AguaLua\ANTLR Data\LuaGrammar.g:12:18: unknown or invalid action scope for tree grammar: lexer
[02:54:06] error(143): C:\Users\RCIX\Desktop\AguaLua\Project\trunk\AguaLua\AguaLua\ANTLR Data\LuaGrammar.g:13:19: unknown or invalid action scope for tree grammar: parser

Я на правильном пути или полностью выключен?

Ответы [ 2 ]

2 голосов
/ 11 февраля 2010

Хорошо, возвращаясь к моему обычному примеру грамматики калькулятора:)

Так вы бы объявили свой класс Tree Walker

class CalcTreeShaker extends TreeParser;

expr returns [float r]
{
float a,b;
r=0;
}
:   #(PLUS a=expr b=expr)   {r = a+b;}
|   #(STAR a=expr b=expr)   {r = a*b;}
|   i:INT           {r = Convert.ToSingle(i.getText());}
;

Здесь у нас есть правило дерева под названием expr. Ходоки деревьев очень похожи на грамматики синтаксического анализатора.

Большая разница в том, что хотя грамматика синтаксического анализатора должна точно соответствовать грамматике дерева, она должна соответствовать только части дерева.

В правиле expr мы видим, что оно соответствует любому дереву с токенами PLUS или STAR или INT.

Мы можем видеть, что мы сопоставляем деревья, потому что мы используем синтаксис Antlr Tree #(...).

Дерево PLUS и STAR также соответствует 2 правилам expr. Каждому правилу expr присваивается имя, поэтому мы можем использовать его для оценки выражения. Подобно грамматикам синтаксического анализатора, мы можем поместить код C # в блоки defiend на {...}.

Также обратите внимание, что в этом примере мы показываем, как вернуть значение из правила TreeWalker, мы используем синтаксис return [...].

Чтобы вызвать дерево, вы создаете его, а затем называете его правилом верхнего уровня. Я скопирую это из примера Antlr:)

// Get the ast from your parser.
CommonAST t = (CommonAST)parser.getAST();

// Create the Tree Shaker
CalcTreeWalker walker = new CalcTreeWalker();
CalcParser.initializeASTFactory(walker.getASTFactory());

// pass the ast to the walker and call the top level rule.
float r = walker.expr(t);
1 голос
/ 12 февраля 2010

Я не сталкивался с этой ошибкой, но есть две вещи, которые я бы попробовал.

1) удалить строки пространства имен @lexer и @parser.

2) Если они необходимы, перемещайте их до раздела «Жетоны» {...} вашей грамматики, то есть непосредственно перед правилами.

...