Javacc用于解析'<upper_case> <arrow> </arrow> </upper_case>

时间:2012-10-18 20:26:57

标签: javacc

我正在为一组CFG编写解析器。 (注意:RHS只能是一个大写字母)

/ *忽略声明和东西,这是代码* /

的主要部分
void
start():
{
}
{
    (
     <UPPER_CHAR>
     <ARROW>
     <STRING>
     ( <PIPE> <STRING> )*
    )*
}


TOKEN:
{
 <ARROW: "=>" >
|
 <PIPE: "|">
|
 <UPPER_CHAR: (["A"-"Z"])>
}

TOKEN: {<STRING: (<LETTER> |  <DIGIT> | <SYMBOL>)+ > }

这显然错过了一些边缘案例,其中一些包括:

A => A | a | D E => e

那我做错了什么?

1 个答案:

答案 0 :(得分:1)

我猜SYMBOL包含“=”和“&gt;”但不是“|”。在这种情况下。 STRING将匹配整个“D E =&gt; e”。

为什么你想要STRING?为什么不这样做呢。

void start() : {} {
   (
      <UPPER_CHAR> <ARROW>
      choices()
   )*
}
void choices() : {} {
      choice() ( <PIPE> choice())*
}
void choice() : {} {
    LOOKAHEAD(<UPPER_CHAR> <ARROW> )
    {}
 |
    (<UPPER_CHAR> | <LOWER_CHAR>) choice()
 |
    {}
}

我为choice使用递归的原因是没有办法使用语法前瞻来退出循环。即你想要的是(<UPPER_CHAR> | <LOWER_CHAR>)*,但是当你接下来的两个代币是<UPPER_CHAR> <ARROW>时,你想要摆脱这个循环。