0

複数の変数で多項式を解析する Antlr 文法に取り組んでいます。したがって、次の文法を作成しました。

grammar Function;

parseFunction returns [java.util.List<java.util.List<Object>>]  :   { list = new java.util.ArrayList(); } (p=polypart { list.add($p.list); })+
;

polypart returns [java.util.List<Object> list]: 
  m=NUMBER { list = new java.util.ArrayList(); list.add("+"); list.add($m.text); list.add("0"); }
| s=SIGN m=NUMBER {list = new java.util.ArrayList(); list.add($s.text); list.add($m.text); }
| v=VARIABLE {list = new java.util.ArrayList(); list.add("+"); list.add($v.text); }
| s=SIGN v=VARIABLE {list = new java.util.ArrayList(); list.add($s.text); list.add($v.text); }
| v=VARIABLE e=exponent { list = new java.util.ArrayList(); list.add("+"); list.add($v.text); list.add($e.value); } 
| s=SIGN v=VARIABLE e=exponent { list = new java.util.ArrayList(); list.add($s.text); list.add($v.text); list.add($e.value); }
| m=NUMBER v=VARIABLE { list = new java.util.ArrayList(); list.add("+"); list.add($m.text); $list.add($v.text); }
| s=SIGN m=NUMBER v=VARIABLE { list = new java.util.ArrayList(); list.add($s.text); list.add($m.text); $list.add($v.text); }
| m=NUMBER v=VARIABLE e=exponent { list = new java.util.ArrayList(); list.add("+"); list.add($m.text); list.add($v.text); list.add($e.value); }
| s=SIGN m=NUMBER v=VARIABLE e=exponent { list = new java.util.ArrayList(); list.add($s.text); list.add($m.text); list.add($e.value); }
;

exponent returns [int value]: ('^' n=NUMBER) { $value = 1; if ( $n != null && $n.text.length() > 0) $value = Integer.parseInt($n.text); }
;

VARIABLE    : ('a'..'z'|'A'..'Z')+
;

NUMBER  : ('0'..'9')+
;

SIGN    :   ('+'|'-')
;

WS  :   (' '|'\t')+ {skip();} ;

どうやら、これは機能しません。これを Antlr 3.4 でコンパイルすると、次の警告が表示されます。

"SIGN NUMBER VARIABLE" は選択肢 2,8 を使用します。"SIGN NUMBER VARIABLE '^' NUMBER" は代替 2,10 を使用します。「NUMBER VARIABLE」は選択肢 1、7 を使用し、「NUMBER VARIABLE '^' NUMBER」は選択肢 1、9 を使用します。

私はこれらの警告を受け入れることができました (ただし、警告がポップアップする理由には非常に興味があります) が、難しいのは、次のエラーが表示されることです。

error(201): Function.g:6:47: The following alternatives can never be matched: 7,8,9,10

これは、警告のために無効になっているために発生するため、最初に警告を解決する必要があると思います。


編集:

この問題についてかなり考えた後、いくつかのコード行を変更してコードを変更しましたが、少なくともエラーは発生しなくなりました。ただし、まだテストしていないため、最後の 2 つの警告も削除したいと考えています。新しいコードは次のとおりです。

grammar Function;

parseFunction returns [java.util.List<java.util.List<Object>>]  :   { list = new java.util.ArrayList(); } (p=polypart { list.add($p.list); })+
;

polypart returns [java.util.List<Object> list]: 
s=SIGN m=NUMBER v=VARIABLE e=exponent { list = new java.util.ArrayList(); list.add($s.text); list.add($m.text); list.add($e.value); }
| m=NUMBER v=VARIABLE e=exponent { list = new java.util.ArrayList(); list.add("+"); list.add($m.text); list.add($v.text); list.add($e.value); }
| s=SIGN m=NUMBER v=VARIABLE { list = new java.util.ArrayList(); list.add($s.text); list.add($m.text); $list.add($v.text); }
| m=NUMBER v=VARIABLE { list = new java.util.ArrayList(); list.add("+"); list.add($m.text); $list.add($v.text); }
| s=SIGN v=VARIABLE e=exponent { list = new java.util.ArrayList(); list.add($s.text); list.add($v.text); list.add($e.value); }
| v=VARIABLE e=exponent { list = new java.util.ArrayList(); list.add("+"); list.add($v.text); list.add($e.value); } 
| s=SIGN v=VARIABLE {list = new java.util.ArrayList(); list.add($s.text); list.add(1); list.add($v.text); }
| v=VARIABLE {list = new java.util.ArrayList(); list.add("+"); list.add(1); list.add($v.text); }
| s=SIGN m=NUMBER {list = new java.util.ArrayList(); list.add($s.text); list.add($m.text); }
| m=NUMBER { list = new java.util.ArrayList(); list.add("+"); list.add($m.text); }
;

exponent returns [int value]: ('^' n=INTEGER) { $value = 1; if ( $n != null && $n.text.length() > 0) $value = Integer.parseInt($n.text); }
;

VARIABLE    : ('a'..'z'|'A'..'Z')+
;

INTEGER : ('0'..'9')+
;

NUMBER  : ('0'..'9')+(','('0'..'9')+)?
;

SIGN    :   ('+'|'-')
;

WS  :    (' ' | '\t' | '\r'| '\n')+ {skip();} 
;

そして今、次の警告が表示されます。

"NUMBER VARIABLE" uses mutiple alternatives: 4,10 (10 is disabled).
"SIGN NUMBER VARIABLE" uses multiple alternatives: 3,9 (9 is disabled).

これらの最後の 2 つの警告を取り除く方法を誰かが説明してくれたらありがたいです。


パーサーをテストした後、私はそれが受け入れると言うことができます:

X; +X; -X; X^42; +X^42; -X^42

そして、それは受け入れません:

42; +42; -42; 42X^42; +42X^42; -42X^42
4

1 に答える 1

0

NUMBERとVARIABLEの両方が先行記号なしで受け入れられ、NUMBER VARIABLE形式の入力も受け入れられる場合、2つの解釈が可能です。NUMBERVARIABLE-> polypart polypart-> NUMBER polypart->NUMBERVARIABLEまたはNUMBERVARIABLE-> polypart-> NUMBER VARIABLEしたがって、先頭にSIGNが付いているケースをソース化する必要があります。そうすれば、機能します。

次のコードは、警告やエラーなしでコンパイルされます。

grammar Function;

parseFunction returns [java.util.List<java.util.List<Object>> list] :   
    { list = new java.util.ArrayList(); }                                              ( f=functionPart { list.add($f.list); } )+
|   { list = new java.util.ArrayList(); } ( fb=functionBegin ) { list.add($fb.list); } ( f=functionPart { list.add($f.list); } )*
;

functionBegin returns [java.util.List<Object> list]:
m=NUMBER v=VARIABLE e=exponent  { list = new java.util.ArrayList(); list.add("+"); list.add($m.text); list.add($v.text); list.add($e.value); }
| m=NUMBER v=VARIABLE           { list = new java.util.ArrayList(); list.add("+"); list.add($m.text); list.add($v.text); }
| v=VARIABLE e=exponent         { list = new java.util.ArrayList(); list.add("+"); list.add("1");     list.add($v.text); list.add($e.value); }  
| v=VARIABLE                    { list = new java.util.ArrayList(); list.add("+"); list.add("1");     list.add($v.text); }
| m=NUMBER                      { list = new java.util.ArrayList(); list.add("+"); list.add($m.text); }
;

functionPart returns [java.util.List<Object> list] :    
s=SIGN m=NUMBER v=VARIABLE e=exponent   { list = new java.util.ArrayList(); list.add($s.text); list.add($m.text); list.add($v.text); list.add($e.value); }
| s=SIGN m=NUMBER v=VARIABLE            { list = new java.util.ArrayList(); list.add($s.text); list.add($m.text); list.add($v.text); }
| s=SIGN v=VARIABLE e=exponent          { list = new java.util.ArrayList(); list.add($s.text); list.add("1");     list.add($v.text); list.add($e.value); }
| s=SIGN v=VARIABLE                     { list = new java.util.ArrayList(); list.add($s.text); list.add("1");     list.add($v.text); }
| s=SIGN m=NUMBER                       { list = new java.util.ArrayList(); list.add($s.text); list.add($m.text); }
;

exponent returns [int value]: ('^' n=INTEGER) { $value = 1; if ( $n != null && $n.text.length() > 0) $value = Integer.parseInt($n.text); }
;

VARIABLE    : ('a'..'z'|'A'..'Z')+
;

INTEGER : ('0'..'9')+
;

NUMBER  : ('0'..'9')+ (','('0'..'9')+)?
;

SIGN    :   ('+'|'-')
;

WS  :    (' ' | '\t' | '\r'| '\n')+ {skip();} 
;

この文法は、Javaでコンパイルおよび使用された場合、ほとんどの入力値を受け入れます。明らかに、すべての有効な入力値が受け入れられるわけではありません。+42のように、コンマを使用しない数値がポップアップするとすぐに、エラーがスローされます。

line 1:1 no viable alternative at input '+'

ただし、これは元の質問と一致しないため、ここで説明します。

于 2012-07-31T09:00:09.620 に答える