2009-06-06 10 views
0

トークンレベルであいまいな言語を認識できるパーサーをJavaCCに書き込もうとしています。この特定のケースでは、言語は、除算演算子として "/"トークンを単独でサポートしますが、正規表現リテラルもサポートします。次のコードを考えるとJavaCCでのトークンのあいまいさの処理

TOKEN : 
{ 
    ... 
    < VAR : "var" > | 
    < DIV : "/" > | 
    < EQUALS : "=" > | 
    < SEMICOLON : ";" > | 
    ... 
} 

TOKEN : 
{ 
    < IDENTIFIER : <IDENTIFIER_START> (<IDENTIFIER_START> | <IDENTIFIER_CHAR>)* > | 
    < #IDENTIFIER_START : ([ "$","_","A"-"Z","a"-"z" ])> | 
    < #IDENTIFIER_CHAR : ([ "$","_","A"-"Z","a"-"z","0"-"9" ]) > | 

    < REGEX_LITERAL : ("/" <REGEX_BODY> "/" (<REGEX_FLAGS>)?) > | 
    < #REGEX_BODY : (<REGEX_FIRST_CHAR> <REGEX_CHARS>) > | 
    < #REGEX_CHARS : (<REGEX_CHAR>)* > | 
    < #REGEX_FIRST_CHAR : (~["\r", "\n", "*", "/", "\\"] | <BACKSLASH_SEQUENCE>) > | 
    < #REGEX_CHAR : (~[ "\r", "\n", "/", "\\" ] | <BACKSLASH_SEQUENCE>) > | 
    < #BACKSLASH_SEQUENCE : ("\\" ~[ "\r", "\n"]) > | 
    < #REGEX_FLAGS : (<IDENTIFIER_CHAR>)* > 

} 

:トークンの

var y = a/b/c; 

二つの異なるセットを生成することができ

は、次のJavaCCの文法を考えてみましょう。トークンストリームのいずれかでなければなりません:

<VAR> <IDENTIFIER> <EQUALS> <IDENTIFIER> <DIV> <IDENTIFIER> <DIV> <SEMICOLON> 

または

<VAR> <IDENTIFIER> <EQUALS> <IDENTIFIER> <REGEX_LITERAL> <SEMICOLON> 

どのように私はそれTokenManagerが、私はこのような場合のために期待するトークンストリームを生成することを保証することができますか?限り、私は(私はいつか戻ったJavaCCで働いていた)覚えて

答えて

2

JavaCCは常に利用可能な最大のトークンを消費します。それ以外の場合は、JavaCCを設定する方法はありません。これを達成する唯一の方法は、IGNORE_REGEXというトークンを除外する語彙状態を追加することです(この場合は<REGEX_LITERAL>)。その後、トークンが認識できない場合は、<REGEX_LITERAL>の字句状態をIGNORE_REGEXに変更する必要があります。

var y = a/b/c 

以下が起こる:入力と

  1. <VAR>が消費され、字句状態をIGNORE_REGEX
  2. に、字句状態が設定されて消費さ DEFAULT
  3. <IDENTIFIER>に設定されています
  4. <EQUALS>が使用され、字句状態は消費され
  5. <IDENTIFIER>は、字句状態はこの時点でIGNORE_REGEX

    に設定されている、いずれか<DIV>または<REGEX_LITERAL>が消費され、文法におけるあいまいさがあります。語彙状態がIGNORE_REGEXであり、その状態が<REGEX_LITERAL>と一致しないので、<DIV>が消費されます。

  6. <DIV>が消費され、字句状態をDEFAULT

  7. <IDENTIFIER>に設定されて消費され、字句状態をIGNORE_REGEX
  8. <DIV>に設定されて消費され、字句状態をDEFAULT
  9. <IDENTIFIER>に設定され、語彙消費され状態はIGNORE_REGEX
に設定されます
0

あなたは、各ルールを記述するためには、それが解析されるであろう順序ですので、常に生成するために、あなたのルールを書きますあなたが望む表現。

0

JavaScript/EcmaScriptは同じことをしています(つまり、正規表現リテラルと除算演算子があなたの例のように見えます)ので、学習するために既存のJavaCC文法を探したいかもしれません。私はthis blog entryからリンクされたものを見つけました。

関連する問題