duesee / abnf

A nom-based ABNF parser.
Apache License 2.0
17 stars 3 forks source link

Having issues using this library #17

Closed spf5000 closed 3 years ago

spf5000 commented 3 years ago

I was hoping to use this library to build an abnf "parser generator". I was going to use this library to parse the abnf, then use the types from this library to generate a parser for the given abnf language. However, I've been unable to parse a relatively simple statement from an abnf language I'm trying to parse to test with:

    let rule = match rulelist("idl = ws control_section metadata_section shape_section\n") {
        Ok(rule) => rule,
        Err(err) => { eprintln!("{:?}", err); return Err(anyhow::Error::new(err))}
    };
    println!("{:#?}", rule);

I'm getting:

Error: Error(VerboseError { errors: [("idl = ws control_section metadata_section shape_section\n", Nom(CrLf)), ("idl = ws control_section metadata_section shape_section\n", Nom(Alt)), ("idl = ws control_section metadata_section shape_section\n", Nom(Alt)), ("idl = ws control_section metadata_section shape_section\n", Nom(Many1))] })
ParseError { message: "Error(VerboseError { errors: [(\"idl = ws control_section metadata_section shape_section\\n\", Nom(CrLf)), (\"idl = ws control_section metadata_section shape_section\\n\", Nom(Alt)), (\"idl = ws control_section metadata_section shape_section\\n\", Nom(Alt)), (\"idl = ws control_section metadata_section shape_section\\n\", Nom(Many1))] })" }

I'm using linux to run this code, so maybe there is something going on there? It seems like it doesn't ever find a newline character? I like what you're doing with this library and would love to leverage it for my own project, but I'm new to parsing and not sure what's going on here.

duesee commented 3 years ago

Hey, the reason why you get an error is because ABNF does not allow _ in non-terminals.

rulename = ALPHA *(ALPHA / DIGIT / "-")

Using idl = ws control-section metadata-section shape-section\n yields the correct result:

[
    Rule {
        name: "idl",
        node: Concatenation(
            [
                Rulename(
                    "ws",
                ),
                Rulename(
                    "control-section",
                ),
                Rulename(
                    "metadata-section",
                ),
                Rulename(
                    "shape-section",
                ),
            ],
        ),
        kind: Basic,
    },
]

You should also Display the error in line 3 and not Debug it. When you change {:?} to {}, it will print

0: at line 1, in CrLf:
idl = ws control_section metadata_section shape_section
^

1: at line 1, in Alt:
idl = ws control_section metadata_section shape_section
^

2: at line 1, in Alt:
idl = ws control_section metadata_section shape_section
^

3: at line 1, in Many1:
idl = ws control_section metadata_section shape_section
^

Still, this is a bad error message and I understand why you thought it is related to newline. I do not have much time to work on this library currently, but do you mind if I include your test as a unit test? I think that I want to change two things in the future: 1) first accepting - in non-terminals and then yielding a better error message and 2) reworking how errors are displayed altogether. This is a painpoint, because I have not fully understood how Nom works here :-)

Thank you for the kind words, btw!