1

バランスの取れた括弧を一致させようとしています。一致PARAMSした場合はツリーが作成され、そうでない場合は LPARAM および RPARAM トークンが単純にアトムとしてツリーに追加されます...

tokens
{
    LIST;    
    PARAMS;
}

start   : list -> ^(LIST list);

list    : (expr|atom)+;

expr : LPARAM list? RPARAM -> ^(PARAMS list?);

atom :  INT | LPARAM | RPARAM;

INT :   '0'..'9'+;
LPARAM  :   '(';
RPARAM  :   ')';

現時点では、ルール expr では、そのルールの終了トークンではなく、PARAMS常に末尾がアトムとして認識されるため、ツリーを作成することはありません。RPARAM

したがって、現時点では、必要なグループ化ではなく、トークンのフラット リストとしてのようなものがツリーに1 2 3 (4) 5追加されます。LIST

以前、トークンをアトムとしてツリーに追加する処理を行ったことがありますが、ここで行っているように、別のルールを開始することはできませんでしLPARAMた。

ここである種の構文/意味述語が必要ですか?

4

1 に答える 1

3

これは、いくつかの制約がある単純なアプローチです。これらは、コメントで言及された予想される動作に準拠していると思います。

  • LPARAM子リスト内に不一致が表示されることはありません
  • RPARAM子リスト内に不一致が表示されることはありません

文法:

start   : root+ EOF -> ^(LIST root+ );

root    : expr
        | LPARAM
        | RPARAM
        ;
        
expr    : list
        | atom
        ;           
        
list    : LPARAM expr+ RPARAM -> ^(LIST expr+)
        ;

atom    : INT
        ;

一致しないとのルールrootが一致します。ルールを守り、自分のことだけを気にします。LPARAMRPARAMlistatom

ルールは と の前にリストするroot必要があるため、このソリューションは比較的脆弱です。それでも、問題を解決するにはこれで十分かもしれません。exprLPARAMRPARAM

テスト ケース 1 : リストなし

入力:1 2 3

出力:

1 2 3

テスト ケース 2 : 1 つのリスト

入力:1 (2) 3

出力:

1 (2) 3

テスト ケース 3: 2 つのリスト

入力:(1) 2 (3)

出力:

(1) 2 (3)

テスト ケース 4 : リストなし、左の不一致

入力:((1 2 3

出力:

((1 2 3

テスト ケース 5 : 2 つのリスト、不一致の左

入力:((1 (2) (3)

出力:

((1 (2) (3)

テスト ケース 6 : リストなし、権利の不一致

入力:1 2 3))

出力:

1 2 3))

テスト ケース 7 : 2 つのリスト、権限の不一致

入力:(1) (2) 3))

出力:

(1) (2) 3))

テスト ケース 8 : 2 つのリスト、不一致の左が混在

入力:((1 (2) ( (3)

出力: ((1 (2) ( (3)

テスト ケース 9 : 2 つのリスト、不一致の権限が混在

入力:(1) ) (2) 3))

出力:

(1) ) (2) 3))


[]との()ペアを操作するもう少し複雑な文法を次に示します。ペアを追加すると、ソリューションは指数関数的に悪化すると思いますが、楽しいです! また、文法駆動型の AST 構築でできることの限界に達している可能性もあります。

start   : root+ EOF -> ^(LIST root+ )
        ;
        
root    : expr
        | LPARAM
        | RPARAM
        | LSQB
        | RSQB
        ;       
expr    : plist
        | slist
        | atom
        ;           
        
plist   : LPARAM pexpr* RPARAM -> ^(LIST pexpr*)
        ;
        
pexpr   : slist
        | atom
        | LSQB
        | RSQB
        ;       
        
slist   : LSQB sexpr* RSQB -> ^(LIST sexpr*)
        ;
        
sexpr   : plist
        | atom
        | LPARAM
        | RPARAM
        ;               
        
atom    : INT;

INT     : ('0'..'9')+;
LPARAM  : '(';
RPARAM  : ')';
LSQB    : '[';
RSQB    : ']';
于 2012-12-20T23:14:44.027 に答える