2013-06-04 1 views
0

Я пытаюсь написать сценарий JavaCC для (простого) синтаксического анализатора XPath, и у меня возникают проблемы с частью для анализа отдельных шагов.JavaCC - разобрать шаг выражения XPATH

Моя идея грамматики заключается в следующем:

Step ::= (AxisName "::")? NodeTest ("[" Predicate "]")* 

Я превратили его в следующем фрагменте сценария:

Step Step() : 
{ 
    Token t; 

    Step step; 

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

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

     <COLON> 
     <COLON> 
    )? 

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

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

    (  
     <OPEN_PAR> 

     predicate = Expression() 

     { step.addPredicate(predicate); } 

     <CLOSE_PAR> 
    )* 

    { return step; } 
} 

Это, однако, не работает. Учитывая следующее выражение:

p 

он выдает следующее сообщение об ошибке:

Exception in thread "main" java.lang.IllegalArgumentException: No enum constant cz.dusanrychnovsky.generator.expression.Axis.p 
    at java.lang.Enum.valueOf(Unknown Source) 
    at cz.dusanrychnovsky.generator.expression.Axis.valueOf(Axis.java:3) 
    at cz.dusanrychnovsky.generator.parser.XPathParser.Step(XPathParser.java:123) 
    at cz.dusanrychnovsky.generator.parser.XPathParser.RelativeLocationPath(XPathParser.java:83) 
    at cz.dusanrychnovsky.generator.parser.XPathParser.AbsoluteLocationPath(XPathParser.java:66) 
    at cz.dusanrychnovsky.generator.parser.XPathParser.Start(XPathParser.java:23) 
    at cz.dusanrychnovsky.generator.parser.XPathParser.parse(XPathParser.java:16) 
    at cz.dusanrychnovsky.generator.Main.main(Main.java:24) 

Я считаю, что то, что происходит, что синтаксический анализатор видит идентификатор на входе, так это занимает ветвь оси, даже если не колонов будет следовать, что парсер не может знать в то время.

Каков наилучший способ исправить это? Должен ли я каким-то образом увеличить значение lookahead для правила Step, и если это так, то как именно я это сделал? Или мне нужно как-то переписать правило?

ответ

1

Два варианта:

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

    <COLON> 
    <COLON> 
)? 

или

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

    <COLON> 
    <COLON> 
)?