javaCC 解析限制
javaCC Parsing Limitation
我正在尝试通过 javaCC 解析文本文件。该文件由多个句子组成,以换行符分隔。每行可以包含 "a" 和 "b" 的任意序列,但应以 "a" 结尾,然后是换行符之前的 "b" 。 JavaCC 不解析相同的内容并将终端标记 a 和 b 作为可选系列的一部分使用。
这应该被 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()}) 但是无法获得非终端句柄!任何帮助将不胜感激。
[注意:您说的是任何以 "ab" 结尾的 a 和 b 序列,但您的代码使用的是 +
而不是 *
。我假设您确实指的是任何以 "ab" 结尾的序列,包括 "ab" 的序列。尾注。]
需要在look ahead的基础上退出循环。你要做的是这个
( LOOKAHEAD( x )
(a() | b() )
)*
a() b() <NEWLINE>
其中 x
表示如果输入的下一项 不匹配 a() b() <NEWLINE>
。不幸的是,无法使用句法前瞻来表示 "do not match"。诀窍是用递归替换循环。
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()
}
我正在尝试通过 javaCC 解析文本文件。该文件由多个句子组成,以换行符分隔。每行可以包含 "a" 和 "b" 的任意序列,但应以 "a" 结尾,然后是换行符之前的 "b" 。 JavaCC 不解析相同的内容并将终端标记 a 和 b 作为可选系列的一部分使用。
这应该被 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()}) 但是无法获得非终端句柄!任何帮助将不胜感激。
[注意:您说的是任何以 "ab" 结尾的 a 和 b 序列,但您的代码使用的是 +
而不是 *
。我假设您确实指的是任何以 "ab" 结尾的序列,包括 "ab" 的序列。尾注。]
需要在look ahead的基础上退出循环。你要做的是这个
( LOOKAHEAD( x )
(a() | b() )
)*
a() b() <NEWLINE>
其中 x
表示如果输入的下一项 不匹配 a() b() <NEWLINE>
。不幸的是,无法使用句法前瞻来表示 "do not match"。诀窍是用递归替换循环。
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()
}