0

私は次の文法を持っています:

SPACE : (' '|'\t'|'\n'|'\r')+ {$channel = HIDDEN;};
NAME_TAG : 'name';
IS_TAG : 'is';

START : 'START';
END : ('END START') => 'END START'  ;

WORD    : 'A'..'Z'+;

rule :  START NAME_TAG IS_TAG WORD END;

「START name is END END START」のような言語を解析したい。ここでの問題は END トークンです。これは、'END' (Word + SPACE) が誤って解釈されるためです。ここでの正しいアプローチは、構文述語 (END トークン) を使用することだと思っていましたが、間違っている可能性があります。

4

1 に答える 1

1

WORDスペースで区切られた2 つ (またはそれ以上) のトークンは作成しません。'END'およびEND-token としてトークン化してから、次のようにします。

rule     : START NAME_TAG IS_TAG word END START;
word     : WORD | END; // expand this rule, as you see fit
NAME_TAG : 'name';
IS_TAG   : 'is';
START    : 'START';
END      : 'END';
WORD     : 'A'..'Z'+;
SPACE    : (' '|'\t'|'\n'|'\r')+ {$channel = HIDDEN;};

これは"START name is END END START"、次の解析ツリーに解析されます。

ここに画像の説明を入力

編集

あなたが間違っていたのは、述語が失敗した場合にレクサー規則に回復の可能性を与えなかったことです。述語の適切な使用法を次に示します。

rule     :  START NAME_TAG IS_TAG WORD END;

SPACE    : (' '|'\t'|'\n'|'\r')+ {$channel = HIDDEN;};
NAME_TAG : 'name';
IS_TAG   : 'is';
START    : 'START';
WORD     : ('END START')=> 'END START' {$type=END;}
         | 'A'..'Z'+
         ;

fragment END : ;
于 2012-04-05T20:56:52.837 に答える