2012-04-13 8 views
5

私はantlrレクサールールの奇妙な副作用を持っており、私はそれを実証する(ほとんど)最小の実例を作成しました。 この例では、文字列[0..1]と一致させたいと考えています。しかし、私が文法をデバッグするとき、パーサーに達するトークンストリームは[..1]しか含んでいません。最初の整数は、それが何桁の数字を含んでいても常に消費され、どのように起こるかについての手掛かりはありません。 FLOATルールを削除しても問題ありませんので、間違いはそのルールのどこかにあります。しかし、それは[0..1]の何にも合わないはずですから、私は非常に困惑しています。ANTLRレクサールールは、一致しない場合でも文字を消費しますか?

私が間違っていた可能性のあるポインタについては、私はうれしいです。これは私の例である:

grammar min; 
options{ 
language = Java; 
output = AST; 
ASTLabelType=CommonTree; 
backtrack = true; 
} 
tokens { 
    DECLARATION; 
} 

declaration : LBRACEVAR a=INTEGER DDOTS b=INTEGER RBRACEVAR -> ^(DECLARATION $a $b); 

EXP : 'e' | 'E'; 
LBRACEVAR: '['; 
RBRACEVAR: ']'; 
DOT: '.'; 
DDOTS: '..'; 

FLOAT 
    : INTEGER DOT POS_INTEGER 
    | INTEGER DOT POS_INTEGER EXP INTEGER 
    | INTEGER EXP INTEGER 
    ; 

INTEGER : POS_INTEGER | NEG_INTEGER; 
fragment NEG_INTEGER : ('-') POS_INTEGER; 
fragment POS_INTEGER : NUMBER+; 
fragment NUMBER: ('0'..'9'); 

答えて

6

'0'は、レクサーによって破棄され、次のエラーが生成されます

レクサーは '0.'に遭遇したとき、それは FLOATトークンを作成しようとするためです
line 1:3 no viable alternative at character '.' 
line 1:2 extraneous input '..' expecting INTEGER 

、しかしできません。 '0.'に一致する他のルールはないため、エラーが生成され、'0'が破棄され、DOTトークンが作成されます。

これはANTLRのレクサーがどのように機能するか、単にある:それは(!backtrack=trueが唯一のルールをパーサーに適用されることに注意してください)DDOTS続いINTEGERに一致するようにバックトラックはありません。

FLOATのルールの中で、'.'が2つある場合は、代わりにINTEGERトークンを生成する必要があります。 '.'の後に数字(('.' DIGIT)=>の部分)が続く場合にのみ、構文述語(('..')=>部分)を追加してFLOATトークンを生成することでこれを行うことができます。次のデモを参照してください。

+0

これは、少なくとも予期せぬ動作です。包括的な例をありがとう、私はそれをすべて稼働させています:-) – Lichtblitz

+0

@Lichtblitz、あなたは大歓迎です、そして、トークン化する '..'(INT-とFLOAT-トークンとの組み合わせ)は難しいです! :) –

関連する問題