首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java petitparser表达式可选结尾

Java petitparser表达式可选结尾
EN

Stack Overflow用户
提问于 2021-07-13 20:27:31
回答 1查看 37关注 0票数 0

我需要一个解析器,只需要从文本文件中重要的标记部分。以下是示例输入:

代码语言:javascript
复制
else before 1
else before 2
--Start Query 1
important 1
--End 1
else between 1 and 2 - 1
else between 1 and 2 - 2
--Start Query 2
important 2
--End 2 
else after1-1
else after1-2

我写了这个解析器:

代码语言:javascript
复制
public class ExpressionDefinition extends GrammarDefinition {
        {
            def("start", ref("expr").star().end());
            def("nl",  of("\r\n").or(of("\n").or(of("\r"))));
            def("expr", 
                    ref("else").starLazy(ref("expr_start").flatten())
                    .seq(ref("expr_start"))
                    .seq(ref("expr_body"))
                    .seq(ref("expr_end"))
                    .seq(ref("else").starLazy(ref("expr_start")).optional()).map(in -> {
                        if (in instanceof List) {
                            for (Object o: (List)in) {
                                if (o instanceof Body) {
                                    return o;
                                } 
                            }
                        }
                        return null;
                    }));
            def("expr_start", of("--Start Query").seq(any().starLazy(ref("nl")), ref("nl")));
            def("expr_body", any().starLazy(ref("expr_end")).flatten().map((String in) -> new Body(in)));
            def("expr_end", of("--End").seq(any().starLazy(ref("nl")).optional(), ref("nl").optional()));
            def("else", any().starLazy(ref("nl")).seq(ref("nl")));
        }

使用这个用于获取重要数据的小工具Pojo:

代码语言:javascript
复制
@Data
@AllArgsConstructor
public static class Body {
    private final String val;
    @Override public String toString() { return val; }
}

运行方式如下:

代码语言:javascript
复制
ExpressionDefinition def = new ExpressionDefinition();
Parser parser = def.build();
Result result = parser.parse(input);

它抛出了一个异常:org.petitparser.context.ParseError: end of input expected,但没有明显的原因,因为最后一行是else类型的内容,我们希望它具有星形条件,并且它是expr的一部分:ref("else").starLazy(ref("expr_start")).optional()

我怎样才能改变解析器,让它期望每个expr的末尾都是任意数量的else,在输入的末尾有或没有可能的换行符?让else变得贪婪会让它消耗第二个expr_body。使其为any().optional()会导致无限循环挂起。有什么解决方案吗?

EN

回答 1

Stack Overflow用户

发布于 2021-07-16 03:44:33

您可能想要使用a.delimitedBy(b)运算符,它提供了一个使用a的解析器,该解析器使用一次或多次参数b分隔并可能结束。如果你需要更多的控制,看看它是如何implemented的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68362412

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档