Question

A while ago I was struggling with writing a JavaCC template for XPath steps so that it would support both a full step definition and a definition with axis name omitted (in which case the axis name would default to child). I posted a question on SO and got a working answer by Theodore Norvell.

Now I'm trying to extend the template so that the parser would, in addition to the two previous possibilities, also support using a "@" sign as a shortcut for the attribute axis.

The following snippet does not work:

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; }
}

Instead it emits the following warning message:

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.

I have tried setting the LOOKAHEAD parameter in various ways but the only way that worked was to set it globally to 2. I would prefer changing it locally though.

How do I do that? And why doesn't the snippet shown in this question work?

Was it helpful?

Solution

Try this

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

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

    <DOUBLE_COLON>
 |
     {}
 )

--Edit--

I'd forgotten to answer the second question: "Why doesn't the given snippet work?" The look ahead spec that you have only applies to the alternation. I'm suprised JavaCC doesn't give you a warning, as the LOOKAHEAD is on the last alternative and hence useless. By the time the parser gets to the LOOKAHEAD, it has already decided (on the basis of the next token being an identifier) to process the part inside the (...)? Another solution is thus

( LOOKAHEAD( <AT> | <IDENTIFIER> <DOUBLE_COLON>  )
   (<AT> {...} | <IDENTIFIER> {...} <DOUBLE_COLON> )
)?
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top