ebnsf 0.1.2

A CLI to generate railroad (syntax) diagrams from EBNF specs
Documentation
// TODO: only really supports BNF syntax, need to add support for EBNF things like repitition specifiers

syntax = _{ SOI ~ rules ~ EOI }

rules = { rule+ }

rule = { lbrack ~ rule_name ~ rbrack ~ "::=" ~ expression ~ NEWLINE*}

expression = { (( grouped_list ~ opt_modifier ) | list) ~ ( "\n"* ~ "|" ~ (grouped_list | list) )* }

list = { (grouped_list ~ opt_modifier) | term+ }

term = { grouped_list ~ opt_modifier |(literal | lbrack ~ rule_name ~ rbrack) ~ opt_modifier }

grouped_list = { lparen ~ expression ~ rparen ~ opt_modifier }

literal = @{
    "\"" ~ not_quote_or_nl+ ~ "\"" | 
    "'" ~ not_squote_or_nl+ ~ "'"
}

rule_name = { ASCII_ALPHA ~ (ASCII_ALPHA | ASCII_DIGIT | "_" | " " | "-")* }


WHITESPACE = _{ " " | "\t" }

// TODO: Need to handle escape characters at some point
not_quote_or_nl = {
    !(                // if the following text is not
        "\""          //     a quote
        | "\n"        //     or a newline
    )
    ~ ( "\\" ~ "\"" | ANY )             // then consume one character
}
not_squote_or_nl = {
    !(                // if the following text is not
        "\'"          //     a quote
        | "\n"        //     or a newline
    )
    ~ ( "\\" ~ "\'" | ANY )             // then consume one character
}

lbrack = _{ "<" }
rbrack = _{ ">" }
lparen = _{ "(" }
rparen = _{ ")" }

opt_modifier = { (oper_cond | oper_alo | oper_rep)? }
oper_cond    = { "?" }
oper_alo     = { "+" } // alo = At Least One
oper_rep     = { "*" }