2

文字列変数宣言の文法は次のように書きました。文字列は一重引用符で囲まれたものと同じように定義されますが、 $文字を使用してエスケープすることにより、文字列値に一重引用符を追加する方法が必要です。

grammar test;

options       
{   
    language = Java;
}


tokens
{   
    VAR = 'VAR';
    END_VAR = 'END_VAR';
}


var_declaration: VAR string_type_declaration END_VAR EOF;

string_type_declaration: identifier ':=' string;

identifier: ID;

string: STRING_VALUE;

STRING_VALUE: '\'' ('$\''|.)* '\'';

ID:  LETTER+;

WSFULL:(' ') {$channel=HIDDEN;};

fragment LETTER: (('a'..'z') | ('A'..'Z'));

var_declaration ルールに対して次のコードを実行しようとすると、この文法は機能しません。

VAR A :='$12.2' END_VAR

MismatchedTokenException が発生します。

しかし、このコードは string_type_declaration ルールに対してはうまく機能します:

A :='$12.2' 
4

1 に答える 1

5

STRING_VALUE適切にトークン化されていません。ループ内( ... )*では、$はその後に一重引用符が必要ですが、入力の文字列 には の'$12.2'後に引用符がありません$。一重引用符はオプションにする必要があります('$' '\''? | .)*。しかし、ループ内の代替である ,.も一重引用符に一致します。一重引用符以外のものと一致させた方がよい and $:

STRING_VALUE
 : '\'' ( '$' '\''? | ~('$' | '\'') )* '\''
 ;

結果として、次の解析ツリーが生成されます。

ここに画像の説明を入力

于 2012-04-28T10:22:50.580 に答える