再次在JavaCC中解析XPATH表达式的一步

时间:2013-06-22 13:10:15

标签: xpath javacc

前段时间我正在努力为XPath步骤编写JavaCC模板,以便它支持全步骤定义和省略轴名称的定义(在这种情况下,轴名称将默认为child)。我发布了a question on SO并得到了Theodore Norvell的工作答案。

现在我正在尝试扩展模板,以便除了之前的两种可能性之外,解析器还支持使用“@”符号作为属性轴的快捷方式。

以下代码段不起作用:

Step Step() :
{
    Token t;

    Step step;

    Axis axis;
    NodeTest nodeTest;
    Expression predicate;
}
{
    { axis = Axis.child; }

    (
        <AT>
        { axis = Axis.attribute; }
    |
        LOOKAHEAD( <IDENTIFIER> <DOUBLE_COLON> )

        t = <IDENTIFIER>
        { axis = Axis.valueOf(t.image); }

        <DOUBLE_COLON>
    )?

    t = <IDENTIFIER>
    { nodeTest = new NodeNameTest(t.image); }

    { step = new Step(axis, nodeTest); }

    (       
        <OPEN_PAR>

        predicate = Expression()

        { step.addPredicate(predicate); }

        <CLOSE_PAR>
    )*

    { return step; }
}

相反,它会发出以下警告消息:

Choice conflict in [...] construct at line 162, column 9.
Expansion nested within construct and expansion following construct
have common prefixes, one of which is: <IDENTIFIER>
Consider using a lookahead of 2 or more for nested expansion.

我已尝试以各种方式设置LOOKAHEAD参数,但唯一有效的方法是将其全局设置为2.我宁愿在本地更改它。

我该怎么做?为什么这个问题中显示的片段不起作用?

1 个答案:

答案 0 :(得分:1)

试试这个

(
    <AT>
    { axis = Axis.attribute; }
|
    LOOKAHEAD( <IDENTIFIER> <DOUBLE_COLON> )

    t = <IDENTIFIER>
    { axis = Axis.valueOf(t.image); }

    <DOUBLE_COLON>
 |
     {}
 )

- 编辑 -

我忘了回答第二个问题:“为什么给定的代码片段不起作用?” 您只能应用于交替的前瞻规范。我很惊讶JavaCC没有给你一个警告,因为LOOKAHEAD是最后的选择,因此没用。当解析器到达LOOKAHEAD时,它已经决定(基于下一个标记是标识符)来处理(...)?内的部分。因此另一个解决方案是

( LOOKAHEAD( <AT> | <IDENTIFIER> <DOUBLE_COLON>  )
   (<AT> {...} | <IDENTIFIER> {...} <DOUBLE_COLON> )
)?