2013-05-16 1 views
0

Мне нужно создать (очень) простой парсер выражений XPath. Я пытаюсь использовать JavaCC для этой цели. Я совершенно не знаком с JavaCC (хотя мы изучили Flex & Bison в школе), и поэтому я пытаюсь построить JJ-скрипт поэтапно, добавив крошечную функциональность за раз.JavaCC - парсер XPath

До сих пор я до следующей грамматикой:

XPATHEXPRESSION ::= ("/" <STEP>)+ 
STEP ::= <AXIS_NAME> ":" <NODE_TEST> ("[" <EXPRESSION> "]")* 
EXPRESSION ::= <XPATHEXPRESSION> "=" """ <IDENTIFIER> """ 

И соответствующий файл JJ выглядит следующим образом:

options { 
    STATIC = false ; 
} 

PARSER_BEGIN(XPathParser) 

    package cz.me.generator.parser; 

    import cz.me.generator.expression.*; 

    import java.io.Reader; 
    import java.io.StringReader; 

    public class XPathParser 
    {   
     public static XPathExpr parse(String exprLiteral) 
      throws TokenMgrError, ParseException 
     { 
      Reader in = new StringReader(exprLiteral); 
      XPathParser parser = new XPathParser(in); 
      return parser.XPathExpr(); 
     } 
    } 

PARSER_END(XPathParser) 

SKIP : { " " } 

TOKEN : { < SLASH : "/" > } 
TOKEN : { < COLON : ":" > } 
TOKEN : { < OPEN_PAR : "[" > } 
TOKEN : { < CLOSE_PAR : "]" > } 
TOKEN : { < QUOTE : "\"" > } 

TOKEN : { < EQ : "=" > } 
TOKEN : { < GT : ">" > } 
TOKEN : { < LT : "<" > } 

TOKEN : { < IDENTIFIER : (["a"-"z","A"-"Z","0"-"9"])+ > } 
TOKEN : { < NUMBER : (["0"-"9"])+ > } 

Expression Expression() : 
{ 
    Token t; 

    XPathExpr xPathExpr; 
    String value; 
} 
{ 
    xPathExpr = XPathExpr() 

    <EQ> 

    <QUOTE> 
    t = <IDENTIFIER> 
    { value = t.image; } 
    <QUOTE> 

    { return new EqExpr(xPathExpr, new StringLiteral(value)); } 
} 

XPathExpr XPathExpr() : 
{ 
    XPathExpr xPathExpr; 
    Step step; 
} 
{ 
    { xPathExpr = new XPathExpr(); } 

    (
     <SLASH> 

     step = Step() 
     { xPathExpr.addStep(step); } 
    )+ 

    <EOF> 

    { return xPathExpr; } 
} 

Step Step() : 
{ 
    Token t; 

    Step step; 

    Axis axis; 
    NodeTest nodeTest; 
    Expression predicate; 
} 
{ 
    t = <IDENTIFIER> 
    { axis = Axis.valueOf(t.image); } 

    <COLON> 

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

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

    (  
     <OPEN_PAR> 

     predicate = Expression() 

     { step.addPredicate(predicate); } 

     <CLOSE_PAR> 
    )* 

    { return step; } 
} 

Однако, это не работает.

Следующий код:

XPathExpr expr = XPathParser.parse("/self:house/child:window[/child:material = \"glass\"]"); 
System.out.println(expr); 

дает следующий результат (при запуске JavaCC в режиме отладки):

Call: XPathExpr 
    Consumed token: <"/" at line 1 column 1> 
    Call: Step 
    Consumed token: <<IDENTIFIER>: "self" at line 1 column 2> 
    Consumed token: <":" at line 1 column 6> 
    Consumed token: <<IDENTIFIER>: "house" at line 1 column 7> 
    Return: Step 
    Consumed token: <"/" at line 1 column 12> 
    Call: Step 
    Consumed token: <<IDENTIFIER>: "child" at line 1 column 13> 
    Consumed token: <":" at line 1 column 18> 
    Consumed token: <<IDENTIFIER>: "window" at line 1 column 19> 
    Consumed token: <"[" at line 1 column 25> 
    Call: Expression 
     Call: XPathExpr 
     Consumed token: <"/" at line 1 column 26> 
     Call: Step 
      Consumed token: <<IDENTIFIER>: "child" at line 1 column 27> 
      Consumed token: <":" at line 1 column 32> 
      Consumed token: <<IDENTIFIER>: "material" at line 1 column 33> 
     Return: Step 
     Return: XPathExpr 
    Return: Expression 
    Return: Step 
Return: XPathExpr 
Exception in thread "main" cz.me.generator.parser.ParseException: Encountered " "=" "= "" at line 1, column 42. 
Was expecting one of: 
    <EOF> 
    "/" ... 
    "[" ... 

    at cz.me.generator.parser.XPathParser.generateParseException(XPathParser.java:270) 
    at cz.me.generator.parser.XPathParser.jj_consume_token(XPathParser.java:207) 
    at cz.me.generator.parser.XPathParser.XPathExpr(XPathParser.java:65) 
    at cz.me.generator.parser.XPathParser.Expression(XPathParser.java:32) 
    at cz.me.generator.parser.XPathParser.Step(XPathParser.java:100) 
    at cz.me.generator.parser.XPathParser.XPathExpr(XPathParser.java:54) 
    at cz.me.generator.parser.XPathParser.parse(XPathParser.java:22) 
    at cz.me.generator.Main.main(Main.java:17) 

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

Что не так?

ответ

1

Проблема: <EOF> в XPathExpr. Возьмите это. Добавить производство

void Start() : 
{ } 
{ 
    XPathExpr() 
    <EOF> 
} 

и переписать parse использовать Start.

+0

Я вижу. Я начал с скелетного скрипта из учебника, а затем итеративно расширил его. В конце концов я забыл про токен EOF. Спасибо за вашу помощь. –