2017-04-13 29 views
0

为什么JavaCC总是在前瞻中给出终端错误?就像在这个例子中,JavaCC遇到词法错误,当lookahead遇到文件结尾

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" 
} 

在Q1()是有2个选择,一个是读“B”,并移动到Q0,或阅读“b”和最终读数。但是,如果我给出一个输入“ab”,它将会给出一个错误,即使它具有lookahead选项。但是如果我给“(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

问题是您的输入字符串包含词法分析器不期望的返回字符。它与lookhahead无关;前瞻与解析有关,而不是轻视。我建议把这样的规则。

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

我明白了,我的不好。感谢这对我有用。 虽然如果我直接从命令提示符输入,它仍然在等待输入。有没有什么方法可以说明阅读完成? – tettra

+0

在UNIX或Mac上,使用cntl-d。在DOS或Windows上使用cntl-z。这将作为一个EOF令牌而变得松散。 –

0

你所建议的示例规则:

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

有效地说:“一定有"terminal_x"后跟零个或一个non-terminal()”。

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

这种方式,因为它总是会"terminal_x",然后允许零个或一个"non-terminal()",消除不需要前瞻:这将通过使用?运营商(零或一个),如下来容易做来难完全的问题。

+0

是的,这种形式更简单,但错误仍然出现。 – tettra