3

それらを機能させる方法がわからないANTLRルールがいくつかあります

最初のルールは次のとおりです。

STRING_LITERAL
    :  '"' ( EscapeSequence | ~('\\'|'"') )* '"'
    ;

2 番目のルールは次のとおりです。

element 
 :  name '='  math_formula  ;
math_formula
        :        '"' expression '"';

式は通常の C のような式です

構文の例

 "count" = "array[3]"

count は文字列、array[3] は式です。

私の問題は、レクサーが常に「count」と「array[3]」の両方を文字列として返し、パーサーが式を認識できないことです。

私はJavaターゲットを使用しています。

編集:「変数名」を「カウント」に変更しました。

EDIT2:以下の2回目の試みについて説明しました:

「= "」で式の開始を検出できますが、レクサーで式の終了を検出できず、「,」で区切られた 2 つの要素がある場合に文字列の誤検出が発生します。

"count1" = "array[1]",
"count2" = "array[2]"

'= "' を START_EXPRESSION として使用した場合、レクサーは最初の式を終了する引用符を検出し、2 番目の文字列を開始する引用符を文字列 ",\n" として検出しましたが、これは明らかに正しくありません。

編集 3: 構文述語を試す

STRING_LITERAL のルールを次のように変更しました

STRING_LITERAL  
    :   (~('=') '"' ( EscapeSequence | ~('\\'|'"') )* '"')=> '"' ( EscapeSequence | ~('\\'|'"') )* '"'
    ;

それでも機能しません。また、要素ラベルなどを割り当てて、ルール自体で ~('=') を生成する方法も知りませんでした

4

3 に答える 3

1

10年以上経っているので、今は構文を思い出せませんが、ANTLRの主な強みの1つは、バックトラックを伴う任意の長さの先読みです。したがって、二重引用符が表示されたら、先読みして一致するかどうかを確認してくださいelement。含まれている場合は、ストリームをelement;として消費します。STRING_LITERALそうでない場合は、ルールにフォールバックします。


ANTLRリファレンスガイドを掘り下げて、構文述語の例を見つけました。それを適応させると、あなたのルールは次のようになると思います。

protected
STRING : whatever...
;
protected
EXPRESSION: whatever...
;
STRING_OR_EXPR
: ( EXPRESSION ) => EXPRESSION { $setType(EXPRESSION); }
| STRING { $setType(STRING); }
;
于 2009-10-08T16:41:46.753 に答える
0

どんな種類のスクリューボール言語を解析しようとしていますか?私はあなたの最善の策はこれらの線に沿ってあなたのレクサーにいくつかの状態を追加することであると思い切って推測したいと思います:

ASSIGN:
    ('=' '"')=> /* assuming whitespace doesn't exist */
     '=' {some_global_flaggy_thing=1;}
    |'='
    ;
STRING_LITERAL:
    {some_global_flaggy_thing==1}? '"' {$type=QUOTE; some_gobal_flaggy_thing=2;}
    |{some_global_flaggy_thing==2}? '"' {$type=QUOTE; some_global_flaggy_thing=0;}
    | '"' /* normal string literal stuff */ '"'
    ;

もちろん、埋め込み式に文字列リテラルを含めることはできません。
私はANTLR2に精通していることに注意してください

于 2009-10-10T03:59:34.160 に答える
0

このSO Webページに表示される方法と、強調のために追加した引用を考えると、パーサーが効果的に何を受け取るかを判断するのは困難です。したがって、この単純な推測を許してください。ただし、ANTLRが効果的に取得される場合

"variable_name" = "array[3]"

(引用符に注意してください)、これは等号で区切られた 2 つの STRING_LITERAL トークンとして鳴りますが、おそらくルールはありません。

variable_name = "array[3]"

または多分より良い

variable_name = array[3]

あなたがやろうとしていることです。

編集:
名前がSTRING (他の場所で定義され、引用符なし)であることを明確にした後、上記の推測が「開始」されていることは明らかです。ただし、別の問題は、式がSTRING_LITERALで禁止されている文字で定義されていない限り、math_formulaがあいまいになるため、レクサーは要素を認識せず、要素 がない「name '=' STRING_LITERAL」シーケンスを認識しないことです。ルール。

于 2009-10-08T16:49:47.983 に答える