在parboiled中使用变量

时间:2015-02-20 21:13:55

标签: java parsing parser-generator parboiled

我正在尝试使用parboiled Java library创建一个简单的XML解析器。

以下代码尝试使用变量来验证结束标记是否包含与开始标记相同的标识符。

class SimpleXmlParser2 extends BaseParser<Object> {
    Rule Expression() {
        StringVar id = new StringVar();
        return Sequence(OpenElement(id), ElementContent(), CloseElement(id));
    }

    Rule OpenElement(StringVar id) {        
        return Sequence('<', Identifier(), ACTION(id.set(match())), '>');
    }

    Rule CloseElement(StringVar id) {    
        return Sequence("</", id.get(), '>');                               
    }

    Rule ElementContent() {
        return ZeroOrMore(NoneOf("<>"));
    }

    Rule Identifier() {
        return OneOrMore(CharRange('A', 'z'));
    }    
}

但是,当我创建ParseRunner时,上面的错误消息org.parboiled.errors.GrammarException: 'null' cannot be automatically converted to a parser Rule失败了。

似乎我对变量应该如何在parboiled中使用有一个基本的误解。任何人都可以帮我解决这个问题吗?

1 个答案:

答案 0 :(得分:1)

想出了答案。在这里包括任何其他可能会遇到同样问题的新手。

问题在于,任何对变量内容的访问都必须在解析器操作中发生,以确保它发生在解析阶段,而不是在规则构建阶段。

上述程序的以下更改可确保在元素标识符不匹配时解析失败。

Rule CloseElement(StringVar id) {    
    return Sequence("</", Identifier(), matchStringVar(id), '>');                               
}

Action matchStringVar(final StringVar var) {
    return new Action() {
        public boolean run(Context ctx) {
            String match = ctx.getMatch();
            return match.equals(var.get());
        }
    };
}