2012-03-02 14 views
1

dir1/dir2/filenameという形式のファイルシステムパスを解析する、世界で最もシンプルな文法と思われるものがあります。私は問題を呈している小さなサンプルを得るためにいくつかの細部を切り捨てました。Antlr MissingTokenException(単純文法)

compilationUnit : relativePath; 
identifier: IdentifierStart IdentifierPart*;  
relativePath : identifier (SLASH identifier)*; 

SLASH : '/'; 
fragment IdentifierPart : 'a'..'z' | 'A'..'Z' | '_' | '0'..'9'; 
fragment IdentifierStart : 'a'..'z' | 'A'..'Z' | '_';  

私はそれをFOO/AA/BBのようなものを養うならば、私はMissingTokenExceptionを取得します。それは識別子を特定し、次にSLASHを取得し、識別子にハングするMissingTokenExceptionを取得します。何か根本的なものでなければなりませんが、何がありますか?

答えて

2

キーワードfragmentをレクサールールの前に置くと、このルールはパーサールールで使用できません。 fragmentは、他のレクサールール内でのみ使用できます。そのようなルールは、決して独自のトークンにならず、他のトークン(他のレクサールール)の一部としてのみ使用できます。言い換えれば

:あなたはfragmentキーワードを残す必要がありますがすることができ、その場合には

// parser rules 
compilationUnit : relativePath; 
relativePath : identifier (SLASH identifier)*; 
identifier  : IdentifierStart (IdentifierStart | Digit)*;  

// lexer rules 
SLASH   : '/'; 
IdentifierStart : 'a'..'z' | 'A'..'Z' | '_'; 
Digit   : '0'..'9'; 

しかし、相対パスでも単一のトークンにすることができ、:あなたの文法からこれらのfragmentキーワードを削除

// parser rule 
compilationUnit : RelativePath; 

// lexer rules 
RelativePath : Identifier ('/' Identifier)*; 

fragment Identifier  : IdentifierStart IdentifierPart*; 
fragment IdentifierPart : 'a'..'z' | 'A'..'Z' | '_' | '0'..'9'; 
fragment IdentifierStart : 'a'..'z' | 'A'..'Z' | '_';  

をしかし、その後RelativePathのmatch以来、パーサの作成Identifierトークンがあることはありません。このように、レクサールールにいくつかの構文規則を作ります単一のIdentifierです。そのため、Identifierfragmentである必要があります。だから、おそらくそれはあなたが望むものではありません。

+0

私はantlrのリストでこの質問をしました。提供される説明は、パーサーが断片IdenifierStartとIdentifierEndを決して見ないので、それを大文字にすることによって識別子をパーサー規則に変えることが問題を解決するはずであるという説明が提供された。レクサーでルールを実行すると、問題が解決しました。 –

+0

@ seven-seven、私はあなたがそこに尋ねた理由を理解していない:私はすでに答えを与えた、いいえ? –