2017-04-13 12 views
0

JavaCCが先読みで端末にエラーを表示するのはなぜですか? Q1を先読みがファイルの終わりを満たしたときにJavaCCに字句エラーがありました

options{ 
    LOOKAHEAD = 2; 
} 

PARSER_BEGIN(GS) 
    public class GS{ 
     public static void main(String args[]) throws ParseException { 
      GS parser = new GS(System.in); 
      parser.q0(); 
     } 
    } 
PARSER_END(GS) 

void q0(): 
{} 
{ 
    "a" q1() | 
    "c" 
} 

void q1(): 
{} 
{ 
    "b" q0() 
    | "b" 
} 

、この例でのように(2つのオプションがあります)、1は「b」を読み、Q0に移動したり、「b」を読み、読書を終了することです。しかし、もし私が入力 "ab"を与えると、先読みオプションを持っていてもエラーになります。しかし、私が "(ab)* c"を与えると、JavaCCはそれをうまく受け入れます。

Exception in thread "main" TokenMgrError: Lexical error at line 1, column 3. Encountered: "\r" (13), after : "" 

生成規則が

{ 
    "terminal_x" non-terminal() 
    | "terminal_x" 
} 

あるときに、この同じエラーが必ず起こるエラーを与えることなく生成規則のこの種を作るための方法はありますか?

私はJavaCC版を使用しています。 6.0_1。

ありがとうございました。

編集:生成規則は、フォーム

{ 
    "terminal_x" 
    | "terminal_x" non-terminal() 
} 

である場合

どうやら、エラーが文句を言わない起こりました。しかし、まだ、このエラーの原因は何ですか?

答えて

0

問題は、入力文字列にレクサーが期待していない戻り文字が含まれていることです。それは見返りとは関係ありません。先読みは、レキシングではなく、解析と関係しています。私はこのようなルールを入れることをお勧めします。

SKIP : { " " | "\t" | "\r" | "\n" } 
+0

私の悪いことが分かります。ありがとう、これは私のために働く。 コマンドプロンプトから直接入力を与えても、入力を待っています。読書が終わったことを伝える方法はありますか? – tettra

+0

UNIXまたはMacでは、cntl-dを使用します。 DOSまたはWindowsでは、cntl-zを使用します。これはEOFトークンとしてレキシングされます。 –

0

あなたが示唆されている例のルール:

{ 
     "terminal_x" 
     | "terminal_x" non-terminal() 
    } 

が効果的に「ゼロまたは1 non-terminal()続い "terminal_x"がなければならない」と言っています。それは常にゼロまたは1 "non-terminal()"、排除することができ、その後 "terminal_x"を探してますよう

{ 
     "terminal_x" (non-terminal())? 
    } 

この方法で、先読みが必要とされていません。これは以下のように?オペレータ(0または1)を使用することによって容易に行われることになります問題は完全に。

+0

はい、そのフォームは簡単ですが、エラーは引き続き表示されます。 – tettra