2013-06-22 1 views
0

Некоторое время назад я боролся с написанием шаблона JavaCC для шагов XPath, чтобы он поддерживал как полное определение шага, так и определение с опущенным осями (в этом случае ось имя будет по умолчанию дочерним). Я отправил a question on SO и получил рабочий ответ Теодора Норвелла.Проанализируйте шаг выражения XPATH в JavaCC снова

Теперь я пытаюсь расширить шаблон, чтобы в дополнение к двум предыдущим возможностям синтаксический анализатор также поддерживал использование знака «@» в качестве ярлыка для оси атрибута.

Следующий фрагмент кода не работает:

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

Попробуйте

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

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

    <DOUBLE_COLON> 
| 
    {} 
) 

--Edit--

я забыл ответить на второй вопрос: "Почему не дал сниппета работу?" Взгляд вперед, что вы применимы только к чередованию. Я удивлен, что JavaCC не дает вам предупреждения, поскольку LOOKAHEAD находится на последней альтернативе и, следовательно, бесполезен. К тому времени, анализатор получает на LOOKAHEAD, он уже решил (на основе следующего маркера, являющимся идентификатором) для обработки детали внутри (...)? Другим решением является, таким образом,

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