ANTLR - Написание древовидной грамматики для AST

У меня есть 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 ответа

Решение

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

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

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

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

Вот как бы вы объявили свой класс 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# в блоки, определяемые {...},

Также обратите внимание, что в этом примере мы показываем, как вернуть значение из правила 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);
Другие вопросы по тегам