2

バックグラウンド

私は数日間ANTLRWorks(V 1.4.3)を使用していて、単純なブールパーサーを作成しようとしています。以下のレクサー/パーサーの組み合わせ文法は、ブール式のオペランドとして引用符で囲まれた空白のテキストのサポートを含む、ほとんどの要件に適しています。


問題

文法が引用符を必要とせずに空白のオペランドで機能するようにしたいと思います。


たとえば、式-

「左右」AND中央

引用符を削除した後でも、同じ解析ツリーを持つ必要があります-

左右中央。

私はバックトラック、述語などについて学んでいますが、解決策を見つけることができないようです。


コード

以下は私がこれまでに得た文法です。愚かな間違いについてのフィードバックは大歓迎です:)。

レクサー/パーサー文法

grammar boolean_expr;

options {
    TokenLabelType=CommonToken;
    output=AST;
    ASTLabelType=CommonTree;
}

@modifier{public}
@ctorModifier{public}

@lexer::namespace{Org.CSharp.Parsers}
@parser::namespace{Org.CSharp.Parsers}

public
evaluator 
    : expr EOF 
    ;

public
expr 
    : orexpr 
    ;

public  
orexpr 
    : andexpr (OR^ andexpr)* 
    ;

public
andexpr 
    : notexpr (AND^ notexpr)* 
    ;

public
notexpr 
    : (NOT^)? atom 
    ;

public
atom 
    : word | LPAREN! expr RPAREN! 
    ;

public
word  
    :  QUOTED_TEXT | TEXT 
    ;

/*
 * Lexer Rules
 */

LPAREN 
    : '(' 
    ;

RPAREN 
    : ')' 
    ;

AND 
    : 'AND'
    ;

OR 
    : 'OR'
    ;

NOT
    : 'NOT'
    ;

WS 
    :  ( ' ' | '\t' | '\r' | '\n')  {$channel=HIDDEN;}  
    ;

QUOTED_TEXT  
    : '"' (LETTER | DIGIT | ' ' | ',' | '-')+ '"'
    ;

TEXT
    : (LETTER | DIGIT)+ 
    ;

/*
Fragment lexer rules can be used by other lexer rules, but do not return tokens by themselves
*/
fragment DIGIT  
    :   ('0'..'9') 
    ; 

fragment LOWER  
    :   ('a'..'z') 
    ; 

fragment UPPER  
    :   ('A'..'Z') 
    ; 

fragment LETTER 
    :   LOWER | UPPER 
    ; 
4

1 に答える 1

1

ルールを1回以上一致TEXTさせるだけです。トークンと複数回一致する場合は、これらのトークンのカスタムルートノードも作成する必要があります(以下の文法で呼び出される架空のトークンを追加しました)。atomTEXT+TEXTTEXTWORD

grammar boolean_expr;

options {
    output=AST;
}

tokens {
  WORD;
}

evaluator 
    : expr EOF 
    ;

...

word  
    : QUOTED_TEXT 
    | TEXT+       -> ^(WORD TEXT+)
    ;

...

これで、入力"left right AND center"は次のように解析されます。

ここに画像の説明を入力してください

于 2012-07-03T07:49:09.517 に答える