2

うまくいけば、これがこの問題を解決するのに役立つ適切な量の情報です。

次のANTLR3構文が与えられた場合

grammar mygrammar;

program : statement* | function*;

function : ID '(' args ')' '->' statement+ (','statement+) '.' ;    

args    : arg (',' arg)*;       

arg     : ID ('->' expression)?;

statement : assignment
          | number
          | string
          ;

assignment : ID '->' expression;    

string  : UNICODE_STRING;

number : HEX_NUMBER | INTEGER ( '.' INTEGER )?;


// ================================================================

HEX_NUMBER : '0x' HEX_DIGIT+;

INTEGER : DIGIT+;

fragment
DIGIT   :   ('0'..'9');

パーサーで問題を引き起こしている行は次のとおりです。

my_function(x, y, z -> 42) -> 10001.

ANTLRWorks は、10001 の後の最後のエラーを次のエラーの問題として赤で強調表示します。 .

これを投げないようにするにはどうすればよいorg.antlr.runtime.EarlyExitExceptionですか?

これは、パーサー ルールと をEOL 区切り文字としてnumber使用しようとするあいまいさが原因であると確信しています。.

4

2 に答える 2

3

修正が必要な別のあいまいさもあります。変化する:

program : statement* | function*;

の中へ:

program  : (statement | function)*;

(2つは同等ではありませんが、後者が必要だと思います)

そして、functionルールでは、少なくとも 2 つstatementの sがあるように定義しました。

function : ID '(' args ')' '->' statement (','statement)+ '.' ; 

私はあなたが本当に少なくとも1つ欲しいと思っています:

function : ID '(' args ')' '->' statement (','statement)* '.' ; 

さて、あなたの本当の問題:パーサールールでフロートを構築しているため、入力の終わりから、10001.パーサーはそれの a を構築しようとしますが、あなた自身がすでに言ったように、それを anと次に anumberに一致させたいあなたのOPで。INTEGER.

これを修正するには、このあいまいさを超えて「見る」ために、パーサーに少し余分な先読みを与える必要があります。(INTEGER '.' INTEGER)=>上記の入力を実際に照合する前に述語を追加することにより、それを行います。

number
  :  HEX_NUMBER 
  |  (INTEGER '.' INTEGER)=> INTEGER '.' INTEGER 
  | INTEGER
  ;

これで、入力によって次の解析ツリーが生成されます。

ここに画像の説明を入力

于 2011-11-11T14:03:06.863 に答える
1

関係ないかもしれませんが、気になるのは以下の点です。

function : ID '(' args ')' '->' statement+ (','statement+) '.' ;

これは代わりに次のようにする必要があります。

function : ID '(' args ')' '->' statement (',' statement)* '.' ;

最初のものは関数定義に単一のコンマが必要だと思いますが、2番目のものはステートメントの区切りとしてコンマが必要です。

argsまた、 allowのルールはz -> 42正しく設定されていますか?

于 2011-11-11T00:58:31.757 に答える