dolik-rce / pegof

PEG grammar optimizer and formatter
Other
9 stars 2 forks source link

Broken grammar #6

Closed dolik-rce closed 2 years ago

dolik-rce commented 2 years ago

When I ask pegof to optimize the the grammar shown above and pass the result to packcc I'm getting this error:

packcc -o lpegrex lpegrex.peg 
packcc: lpegrex.peg:45:1: Illegal rule syntax
packcc: lpegrex.peg:45:21: Invalid directive
packcc: lpegrex.peg:45:22: Illegal rule syntax
packcc: lpegrex.peg:45:53: Invalid directive
packcc: lpegrex.peg:45:54: Illegal rule syntax
packcc: lpegrex.peg:45:96: Invalid directive
packcc: lpegrex.peg:45:99: Illegal rule syntax
packcc: lpegrex.peg:25:7: No definition of rule 'class'

Optimized grammar:

%prefix "lpeg_re"

%header {
    typedef struct  {
    int doOutput;
    } lpeg_re_st;
}

%auxil "lpeg_re_st *"

pattern <- S (definition+ / alternative) !. { printf("\n\n"); }

alternative <- prefix* (<"/"> { printf("\n\t%s ", $1); } S prefix*)*

prefix
    <- "&" S prefix
    / "!" S prefix
    / suffix

suffix <- primary S ((<[*+?]> { printf(" %s ", $1); } / "^" [+-]? [0-9]+ / "->" { auxil->doOutput=0; } S (string / "{}" / name / [0-9]+) { auxil->doOutput=1; } / "=>" { auxil->doOutput=0; } S name) S)* { auxil->doOutput=1; }

primary
    <- "(" { printf(" ( "); } S (definition+ / alternative) ")" { printf(" ) "); }
    / (string / keyword)
    / class
    / "%" name
    / "{:" (name ":")? S (definition+ / alternative) ":}"
    / "=" name
    / "@" S (definition+ / alternative)
    / "{}"
    / "{~" S (definition+ / alternative) "~}"
    / "{|" S (definition+ / alternative) "|}"
    / "{" S (definition+ / alternative) "}"
    / "~?"
    / "~>" S ("foldleft" / "foldright" / "rfoldleft" / "rfoldright")
    / "$" (string / name / [0-9]+)
    / "."
    / name S !(":" S name / ("<--" / "<==" / "<-|" / "<-"))
    / "<" name ">"
    / "^" name
    / "%{" S name S "}"

definition <-  { printf("\n\n"); } S (":" S name S)? ("<--" / "<==" / "<-|" / "<-") S (definition+ / alternative)

class <- <"[" "^"? "%" name / . "-" [^]] / . (!"]" "%" name / . "-" [^]] / .)* "]"> { printf(" %s ", $1); }

S <- ([\t\n\r f] / "--" [^\n\r]*)*

name <- <[A-Z_a-z] ([0-9A-Z_a-z] / "-" !">")*> { if(auxil->doOutput) printf(" %s ", $1); }

string <- <"\"" [^"]* "\"" / "'" [^']* "'"> { if(auxil->doOutput) printf(" %s ", $1); }

keyword <- "`" <[^`]+> "`" { printf(" '%s' ", $1); }

%%
int main() {
    lpeg_re_st state;
    state.doOutput = 1;
    lpeg_re_context_t *ctx = lpeg_re_create(&state);
    while (lpeg_re_parse(ctx, NULL));
    lpeg_re_destroy(ctx);
    return 0;
}

Originally posted by @mingodad in https://github.com/dolik-rce/pegof/issues/1#issuecomment-1103707756

See also following comments:

dolik-rce commented 2 years ago

The problem was that pegof didn't correctly escape some characters in character classes. It is fixed now. I'm sorry it took so long, in the end it was quite trivial bug.

mingodad commented 2 years ago

Thank you !