0

テキスト ファイルからマークされた重要な部分だけを取得するパーサーが必要です。これはサンプル入力です:

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

私はこのパーサーを書きました:

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 を使用します。

@Data
@AllArgsConstructor
public static class Body {
    private final String val;
    @Override public String toString() { return val; }
}

次のように実行します。

ExpressionDefinition def = new ExpressionDefinition();
Parser parser = def.build();
Result result = parser.parse(input);

そして、それは私に例外をスローします: しかし、最後の行は一種のコンテンツであり、スター状態でそれを持っていることを期待しているorg.petitparser.context.ParseError: end of input expected ため、目に見える理由はありません:elseexprref("else").starLazy(ref("expr_start")).optional()

パーサーを変更するにはどうすればよいので、入力の最後に改行文字がある場合とないexpr場合に、それぞれの末尾がいくらでもあると期待できますか? 貪欲にelse作るだけで二の次消費させてしまう。無限ループのハングを引き起こします。これに対する解決策はありますか?elseexpr_bodyany().optional()

4

1 に答える 1