3

私の文法ファイルによっていくつかの Lua コードに対して出力された AST があります。これは現在、解析と字句解析を行っています。これにツリー文法を追加したいのですが、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

私は正しい軌道に乗っていますか、それとも完全に外れていますか?

4

2 に答える 2

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ます。ツリー ウォーカーは、パーサー文法に非常に似ています。

大きな違いは、パーサー文法は正確に一致する必要があるのに対し、ツリー文法はツリーの一部のみ一致する必要があることです。

ルールでは、orexprのトークンを持つすべてのツリーに一致することがわかります。PLUSSTARINT

Antlr の Tree syntax を使用しているため、ツリーが一致していることがわかります#(...)

PLUSandSTARツリーも 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);
于 2010-02-11T16:05:17.190 に答える
1

このエラーは発生していませんが、試してみたいことが 2 つあります。

1) @lexer および @parser 名前空間の行を削除します。

2) 必要な場合は、文法のトークン {...} セクションの後、つまりルールの直前まで移動します。

于 2010-02-12T16:02:31.610 に答える