1

要するに、1 回のパスで ANTLR 文法内からモデル階層を適切に構築する方法と、現在の C# コード生成でそれを行う適切な方法を知りたいと思っています。ドキュメントで説明されているように、戻り変数へのアクセスは現在機能していないようです。

ドキュメントからこの例を参照してください

field
    : d=decl ';' {System.out.println("type "+$d.type+", vars="+$d.vars);}
    ;
decl returns [String type, List vars]
    : t=type ids+=ID (',' ids+=ID)* {$type = $t.text; $vars = $ids;}
    ;

私の実装は C# ですが、C# のターゲット ドキュメント(2008 年頃?) には、文法内の標準アクション パターンからの逸脱については言及されていません。このため、ANTLRWorks 1.4 (この記事の執筆時点では最新の 1.4.2 ではありません) を使用しています。基本的にネストされたinnerStatsで1つの深いツリー階層を設定する私の実装:

alias returns [IStatement alias]
    // Alias(string identifier, List<Statement> value, StatementType statementType, MetaData metaData)
    @init { List<IStatement> innerList = new List<IStatement>(); }
    :   ^(ALIAS ID ( id=innerStat{if($id != null) {innerList.Add($id.myInnerStat);}} )+ ) {$alias = new Alias($ID.ToString(), innerList , StatementType.Alias, null) as IStatement; }
    ;

innerStat returns [IStatement myInnerStat]
    :   s=simpleAlias { myInnerStat = $s; }
    |   s=simpleBind { myInnerStat = $s; }
    |   s=command { myInnerStat = $s; }
    |   increment { myInnerStat = null; }
    |   s=exec { myInnerStat = $s; }
    ;

simpleAlias returns [IStatement myAlias]
    // Alias(string identifier, List<Statement> value, StatementType statementType, MetaData metaData)
    @init{ myAlias= null; string id1 = null; string id2 = null; }
    @after{ myAlias = (new Alias(id1, id2, StatementType.Alias, null)) as IStatement; }
    :   ^(ALIAS ID) { id1 = $ID.ToString(); }
    |   ^(ALIAS i1=ID i2=ID) { id1 = $i1.ToString(); id2 = $i2.ToString(); }
    ;

これにより、次のエラーが返されます。

error(117): D:/Files/.../SourceEval.g:39:29: missing attribute access on rule scope: id
error(117): D:/Files/.../SourceEval.g:43:18: missing attribute access on rule scope: s
error(117): D:/Files/.../SourceEval.g:44:17: missing attribute access on rule scope: s
error(117): D:/Files/.../SourceEval.g:45:14: missing attribute access on rule scope: s
error(117): D:/Files/.../SourceEval.g:47:11: missing attribute access on rule scope: s

現在、この問題を回避する唯一の方法は、C# モデル内にメソッドを作成し、Model.Aliases.Last().AddChild(IStatement)カプセル化を破る innerStat 内から呼び出すことです。助けてくれてありがとう。

編集: 修正されたコードは次の場所にあります: https://github.com/keithharvey/Script-Parser/blob/master/Installer/Model/DAL/SourceExpr.g

4

1 に答える 1

1

例が常にルールの属性を参照していることに注意してください。

$d.type
$d.vars
$t.text

を除いて、しかし、それはそれをする$idsので、それは規則ではありません。+=List

あなたのコードには、ルール属性の5つの違法な使用法(またはそれらの欠如)があります:

1

$id != null属性をまったく使用しなかったため無効です$id.myInnerStat != null。代わりに:を試してください。

2

s=exec { myInnerStat = $s; }属性をまったく使用しなかったため、間違っています。の属性にアクセスする必要がありますexec(そのルールを投稿しなかったため、何がわかりません)。

3、4、5

$ID.ToString()$i1.ToString()および$i2.ToString()間違っているのToString()は、の有効な属性ではありませんID$ID.text代わりに、などを試してください。

于 2011-06-16T08:33:02.843 に答える