我正在尝试通过javaCC解析一个文本文件。该文件由多个句子组成,用换行符分隔。每一行可能包含"a“和"b”的任何序列,但应在换行符前以"a“后面的"b”结尾。JavaCC不解析相同的内容,而是使用终端标记a和b作为可选系列的一部分。
JavaCC应该成功地分析这一点:
aa ab aab
aabjjt文件如下:
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天里,我一直被困在这个问题上。我最后的希望是语义解析-查找({!( getToken(1).kind==a() & getToken(2).kind==b() & getToken(3).kind==newline()}),但不能获得非终端的句柄!任何帮助都将不胜感激。
发布于 2015-02-25 13:01:58
注意:您说任何以"ab“结尾的a和b序列,但是您的代码使用的是+而不是*。我假设你真的是指任何以"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>。由于FAQ中所解释的原因,我不喜欢使用超出手头选择范围的句法前瞻性。但以下工作是可以完成的。
void oneLine() : {} { <NEWLINE> oneLinePrime() }
void oneLinePrime() : {} {
LOOKAHEAD( a() b() <NEWLINE> )
a() b()
|
a() oneLinePrime()
|
b() oneLinePrime()
}https://stackoverflow.com/questions/28698355
复制相似问题