1

私の実際の文法はもっと複雑ですが、問題を取り除くことができました。したがって、これは文法です:

grammar test2;
options {language=CSharp3;}

@parser::namespace { Test.Parser }
@lexer::namespace { Test.Parser }

start   : 'VERSION' INT INT project;

project :   START 'project' NAME TEXT END 'project';

START: '/begin';
END: '/end';

WS  :   ( ' '
        | '\t'
        | '\r'
        | '\n'
        ) {$channel=HIDDEN;}
    ;

    INT :   '0'..'9'+;

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

    TEXT  :  '"'  ( '\\' (.) |'"''"' |~( '\\' | '"' | '\n' | '\r' ) )* '"';

    STARTA 
        :   '/begin hello';

そして、これを解析したい(たとえば):

バージョン 1 1

/プロジェクト開始

testproject "ここに説明が入ります"

/終わり

事業

現在、このようには機能しません (Mismatched token exception)。最後のトークン STARTA を削除すると、機能します。しかし、なぜ?理解できません。

助けていただければ幸いです。ありがとう。

4

1 に答える 1

2

レクサー入力"/begin "(スペースを含む!)を確認すると、ルールにコミットされSTARTAます。上記のルールに一致しない場合、入力の次の文字は"p"( from)では"project"なく"h"(from )であるため、一致する可能性のある別のルール(スペースを含む!)"hello"に一致しようとします。"/begin "しかし、そのようなルールはなく、エラーが発生します。

mismatched character 'p' expecting 'h'

レクサーはスペースを放棄せSTART、ルールに一致しません。

最後の部分を覚えておいてください。レクサーが何かと一致すると、それはあきらめません。同じ入力に一致する他のルールを試す可能性がありますが、一致する文字が少ないルールに一致するようにバックトラックすることはありません。

これは、ANTLR 3.xでレクサーがどのように機能するかを示したものであり、それを回避する方法はありません。

于 2012-09-10T12:52:23.557 に答える