javaCC解析限制

问题描述:

我想通过javaCC解析文本文件。该文件由多个句子组成,用换行符分隔。每行可以包含任何“a”和“b”序列,但应该在换行符之前以“a”结尾,之后是“b”。 JavaCC不会解析相同的消息并将终端令牌a和b作为可选系列的一部分。javaCC解析限制

这应当成功的JavaCC解析:

aa ab aab 
aab 

的JJT文件如下:

options { 
STATIC = false ; 
FORCE_LA_CHECK = true; 
LOOKAHEAD = 20000; 
DEBUG_PARSER = true; 
DEBUG_LOOKAHEAD = true; 
OTHER_AMBIGUITY_CHECK = 3; 
} 

PARSER_BEGIN(Test) 
class Test { 
public static void main(String[] args) 
throws ParseException { 
    Test act = new Test (System.in); 
    SimpleNode root = act.Start() ; 
    root.dump (" "); 
    //ystem.out.println("Total = "+val); 
} 
}PARSER_END(Test) 

TOKEN_MGR_DECLS : 
{ 
    int stringSize; 
} 

SKIP : { < WS : " " > } 
SKIP : {"\t" | "\r" | "\uFFFF" | "\u201a" | "\u00c4" | "\u00ee" | "\u00fa" | "\u00f9" | "\u00ec" | "\u2013" } 

TOKEN [IGNORE_CASE] : 
{ 
    < A : "a" > 
| < B : "b" > 
| < NEWLINE : (("\n")+) > 
} 


SimpleNode Start() throws NumberFormatException : 
{ 
    int i ; 
    int value=0 ; 
} { 
chapter() 
{ 
    return jjtThis; } 
} 

void chapter() : 
{ } { 
    (LOOKAHEAD (part_sentence()) part_sentence())+ (newline())? <EOF> 
} 
void part_sentence() : 
{ } { 
    <NEWLINE> (a() | b())+ a() b() 
} 
void a() : 
{ } { 
    <A> 
} 
void b() : 
{ } { 
    <B> 
} 
void newline() throws NumberFormatException : 
{ }{ 
    <NEWLINE> 
    { System.out.print ("N# "); } 
} 

它可以被澄清,非端子a()和b()不能用代币代替;为了简单起见,它们被认为是“a”和“b”。另外,由于其他限制,“NEWLINE”不能移动到非终端“part_sentence”的末尾。

我被困在这个问题从过去的4天。我最后的希望是语义解析--LOOKAHEAD({!(getToken(1).kind == a()& & getToken(2).kind == b()& & getToken(3).kind == newline()} ),但不能得到非终端的句柄!任何帮助将不胜感激

[注意:你说a和b的任何序列以“ab”结尾,但您的代码使用+而不是*。我会假设你确实是指任何以“ab”结尾的序列,包括“ab”序列。尾注。]

你需要在展望的基础上退出循环。想要做的是这个

(LOOKAHEAD(x) 
    (a() | b()) 
)* 
a() b() <NEWLINE> 

其中x表示如果下一项输入不匹配a() b() <NEWLINE>。不幸的是,没有办法使用句法预测来说“不匹配”。诀窍是用递归替换循环。

void oneLine() : {} { 
    LOOKAHEAD(a() b() <NEWLINE>) 
    a() b() <NEWLINE> 
| 
    a() oneLine() 
| 
    b() oneLine() 
} 

你说你想要<NEWLINE>在生产开始。出于常见问题中解释的原因,我不喜欢使用超出手头选择范围的语法预测。但是可以做到以下几点。

void oneLine() : {} { <NEWLINE> oneLinePrime() } 

void oneLinePrime() : {} { 
    LOOKAHEAD(a() b() <NEWLINE>) 
    a() b() 
| 
    a() oneLinePrime() 
| 
    b() oneLinePrime() 
} 
+0

西奥多,我留下了深刻的印象,看到你的答案的深度以及你可能会写的同样的痛苦。你已经回答了我的问题。将尝试在我的相对复杂的语法中实现这一点,并更新结果。谢谢(顺便说一句,这是我第一次在stackoverflow(或任何其他网站)关于此事的每一篇文章 – 2015-02-26 14:12:30

+0

欢迎来到StackOverflow。 – 2015-02-26 20:04:18