0

値に空白以外のものを含めることができるペアのリストを解析しようとしてName=Valueいます (つまり、値に等号を含めることができます)。
名前は、通常の識別文字に制限されています。

問題は、「値」トークンがすべてに一致することです。たとえば、入力の場合:

dude=sweet

パーサーは入力全体を 'Value' トークンと照合します (そして をスローしますMismatchedTokenException)。

bisonでは、状態をトークンに割り当てる可能性がありました (または、これは非終端記号のためだけでしたか?) ため、その状態への明示的な移行後にのみマッチングの「適格」になります。

編集考えてみると、これはバイソンでも機能しません-トークンの分割はすでに行われています(flex)。REJECTただし、トークンへの方法があったと思います。フレックストライに次善のマッチを強制します。

これが私のANTLR文法です。

grammar command_string;

start   
    :    commandParam* EOF
    ;
commandParam 
    :   IDENTIFIER '=' CONTINUOUS_VALUE 
    ;
IDENTIFIER 
    :   ('-'|'_'|'a'..'z'|'A'..'Z'|'0'..'9')+ 
    ;
CONTINUOUS_VALUE
    :   ~( ALL_WS )+
    ;
WS
    :   (ALL_WS) +      { $channel = HIDDEN; }
    ;
fragment ALL_WS     
    :   ' ' | '\t' | '\r' | '\n' 
    ;
4

1 に答える 1

1

CONTINUOUS_VALUE と IDENTIFIER の間に重複があります (IDENTIFIER の文字は CONTINUOUS_VALUE のサブセットです。これを解決するには、おそらくいくつかの方法があります。1 つの方法は、CONTINUOUS_VALUE を「=」で開始し、 text. CSharp では、次のようになります。

CONTINUOUS_VALUE
    :   '=' ~( ALL_WS )+ { Text = Text.Substring(1, Text.Length - 1); }
    ;

次に、commandParam ルールから「=」を取り出します。

2 番目の方法は、IDENTIFIER および CONTINUOUS_VALUE パーサー ルール (少なくとも最初の文字を小文字にする) を作成することです。次に、どちらが一致するかを判断するためのコンテキストを取得します。それらをフラグメントにしてcommandParamで参照することもできるかもしれませんが、すでにALL_WSフラグメントがあるため、フラグメントをネストできるかどうかはわかりません。

また、NameValue ペアの間にある種のセパレーターは必要ありませんか?

于 2009-08-31T03:26:05.010 に答える