3

単純な関数型言語の文法を定義しようとしています。定義はほぼ完了していますが、次のあいまいさを乗り越えることができません。

[14:43:53] warning(200): mygrammar.g:14:11: Decision can match input such as "ATOM" using multiple alternatives: 1, 2 As a result, alternative(s) 2 were disabled for that input 

[14:43:53] warning(200): mygrammar.g:14:11: Decision can match input such as "ID" using multiple alternatives: 1, 2 As a result, alternative(s) 2 were disabled for that input

これが、ATOMとIDの図面がほぼ同じである関連ルールだと私が思うものです。

program : (statement'.')* ;

statement : assignment
          | expression;

assignment : func '->' statement ((','statement)=> ',' statement)*
           | ID '->' expression
           | ATOM '->' ( string | number ); 

func : (ID '(' args ')')=> ID '(' args ')'; 

term : func
     | '(' expression ')'  
     | number
     | string
     | ID
     | ATOM ;

ATOM : ('A'..'Z'|'_')+;

ID : ('a'..'z'|'_')('a'..'z'|'A'..'Z'|'0'..'9'|'_')*;

これがANTLRWorksの構文木です

idの代替http://www.vertigrated.com/images/id_alternatives.png

これは、私が構文解析をサポートしようとしているものの大まかなストローマンです。

hypotenuse(a,b) -> 
  sqr(x) -> x * x,
  sqr(sqr(a) + sqr(b)). 

print(hypotnenuse(2,3)).

statementsだから私は内部の入れ子をサポートできる必要がありますfunctions

私の代入演算子はどこ->ですか、これは単一の代入言語です

.私のステートメント終了マーカーはどこにありますか

これはANTLR3で解析することさえ可能ですか?

4

1 に答える 1

2

文法を曖昧さを少なくするためのヒント:

  1. '.'ステートメントの終わりの文字としてを削除します。たとえば、に置き換えます';'。どちらも1文字であり、フロートの内部';'と競合しません。'.'
  2. floatに一致するレクサールールを作成します。
  3. 関数の後には1つ以上のステートメントが続きますが、明確な終わりはありません(「main」関数が)で終わる場合を除き'.'ます。関数がどこで終了するか(「メイン」関数だけでなく)をパーサーに指示するか、複数の末尾がなくstatement単一の「内部」関数に一致するルールを導入する必要がありexpressionます。
  4. ルールexpressionに本当に必要ですか?statementどちらも関数にすることができます(これもあいまいです)。

これらは、言語を定義する方法に関する問題のほんの一部です。もし私があなたなら、私はこのように続けることはしません。述語でいくつかのことを修正するかもしれませんが、別の場所で何かを変更すると、さらに別のワームの缶が開きます。言語を大幅に再設計することをお勧めします。

再設計したくない場合は、文法からすべての述語を削除し、options {...}セクションに次の行を入力するだけです。

backtrack=true;

これは(一見)あいまいなルールに関するすべての警告を魔法のように削除しますが、これは推奨される修正ではありません。そうすることで、ANTLRは、あいまいさが発生したときに解析ツリーを選択します。これにより、(非常に)予期しない動作が発生する可能性があり、入力が大きい場合は、解析時間が長くなります。繰り返しますが、これは私が望んでいることではありません!グローバルバックトラッキングの詳細については、Wikiを参照してください:http ://www.antlr.org/wiki/display/ANTLR3/How+to+remove+global+backtracking+from+your+grammar

于 2011-11-15T12:41:31.330 に答える