0

用語が間違っていたらすみません。

次のような単純化された文法があるとします。

// parser
expr : COMPARATIVE;

// lexer
WS : ( '\t' | ' ' | '\r' | '\n'| '\u000C' )+; 
COMPARATOR 
        : 'vs'
    | 'versus'
        ;
ITEM 
        : 'boy'
        | 'girl'
        ;
COMPARATIVE :ITEM WS* COMPARATOR WS* ITEM;

したがって、これはもちろん'boy vs girl'or'girl vs boy'などと一致します。しかし、私の質問は、レクサーを作成するときです。

CharStream stream = new ANTLRInputStream("boy vs girl");
SearchLexer lex = new SearchLexer(stream);
CommonTokenStream tokens = new CommonTokenStream(lex);
tokens.fill();
for(Token token : tokens) {
    System.out.print(token.getType() + " [" + token.getText() + "] ");
}

これは次のようなものを出力します: 9 [boy vs girl]、つまり、クエリにうまく一致しますが、この現在のトークンのサブトークンを取得するようなことができるようにしたいと考えています。

私の直感では、ツリーを使用する必要があることがわかりましたが、実際には、私の例では Antlr4 でこれを行う方法がわかりません。ありがとう

4

1 に答える 1

1

現在、COMPARATIVEはレクサー ルールです。つまり、ルールに一致するすべてのテキストから 1 つのトークンを作成しようとします。代わりにパーサー ルールを作成する必要がありますcomparative

comparative : ITEM WS* COMPARATOR WS* ITEM;

COMPARATIVEは単一のトークンと見なされなくなるため、代わりに 、 、および の個別のトークンを取得ITEMWSますCOMPARATOR

2 つの補足事項:

  1. 空白が重要でない場合は、次のようにパーサー ルールから非表示にすることができます。

    WS : ('\t' | ' ' | '\r' | '\n'| '\u000C')+ -> channel(HIDDEN);
    

    comparative次に、パーサー ルールを次のように簡略化できます。

    comparative : ITEM COMPARATOR ITEM;
    
  2. ANTLR 4 では、新しい構文を使用して文字セットを簡素化できます。

    WS : [ \t\r\n\u000C]+ -> channel(HIDDEN);
    
于 2013-04-03T00:19:14.853 に答える