【发布时间】:2010-06-03 14:19:15
【问题描述】:
我已经在理解方面遇到了很多问题,即如何在 JavaCC 中优雅地(或以某种方式)处理模棱两可的标记。让我们举个例子:
我要解析 XML 处理指令。
格式为:"<?" <target> <data> "?>":target 是一个 XML 名称,data 可以是任何东西,除了?>,因为它是结束标记。
所以,让我们在 JavaCC 中定义它:
(我使用词法状态,在本例中为 DEFAULT 和 PROC_INST)
TOKEN : <#NAME : (very-long-definition-from-xml-1.1-goes-here) >
TOKEN : <WSS : (" " | "\t")+ > // WSS = whitespaces
<DEFAULT> TOKEN : {<PI_START : "<?" > : PROC_INST}
<PROC_INST> TOKEN : {<PI_TARGET : <NAME> >}
<PROC_INST> TOKEN : {<PI_DATA : ~[] >} // accept everything
<PROC_INST> TOKEN : {<PI_END : "?>" > : DEFAULT}
现在是识别处理指令的部分:
void PROC_INSTR() : {} {
(
<PI_START>
(t=<PI_TARGET>){System.out.println("target: " + t.image);}
<WSS>
(t=<PI_DATA>){System.out.println("data: " + t.image);}
<PI_END>
) {}
}
让我们用<?mytarget here-goes-some-data?>来测试它:
目标被识别:"target: mytarget"。
但现在我得到了我的 favorite JavaCC 解析错误:
!! procinstparser.ParseException: Encountered "" at line 1, column 15.
!! Was expecting one of:
!!
什么都没遇到?什么都没期待吗?要不然是啥?谢谢你,JavaCC!
我知道,我可以使用 JavaCC 的 MORE 关键字,但这会给我整个处理指令作为 one 标记,所以我不得不通过进一步解析/标记它我。我为什么要那么做?我是在写一个不解析的解析器吗?
问题是(我猜):因此<PI_DATA> 承认“一切”,我的定义是错误的。我应该告诉 JavaCC 将“除?> 之外的所有内容”识别为处理指令数据。
但是怎么做呢?
注意:我只能使用 ~["a"|"b"|"c"] 排除 单个字符,我不能排除 字符串,例如 @987654336 @ 或 ~["?>"]。 JavaCC 的另一个很棒的反特性。
谢谢。
【问题讨论】:
-
您找到解决此问题的方法了吗?我今天刚刚提出了一个类似的问题,希望对您的体验感兴趣。
-
我的解决方案是:“该死的 JavaCC”;) 我一次又一次地遇到这个“解析器”的问题和头痛。我迟早要编写自己的非确定性解析器。它会更慢,因为它不会生成代码,而是在运行时解释规则,但无论如何它都是值得的。
标签: xml parsing tokenize ambiguity javacc