2013-05-16 77 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

的问题是在XPathExpr的<EOF>。把它拿出来。添加产品

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

并重写parse使用开始。

+0

我明白了。我从一个教程的脚本开始,然后迭代扩展它。最后,我完全忘记了EOF令牌。谢谢你的帮助。 –