有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

JavaCC XPath解析器

我需要创建一个(非常)简单的XPath表达式解析器。我正试图使用JavaCC实现这个目的。我对JavaCC完全陌生(尽管我们在学校学过Flex&;Bison),因此我试图通过一次添加一小段功能逐步构建JJ脚本

到目前为止,我掌握了以下语法:

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) 个答案

  1. # 1 楼答案

    问题是xpathxpr中的<EOF>。把它拿出来。添加一个产品

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

    并重写parse以使用Start