dolik-rce / pegof

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

Support action at start of the rule #2

Closed dolik-rce closed 2 years ago

dolik-rce commented 2 years ago

When trying to use the grammar shown bellow I'm getting syntax error, it seems that the problem is this rule:

definition      <- {printf("\n\n");} name  {printf(" ::=\n\t");} S (asttag S)? arrow exp

I'm using an action before a pattern/element -> name, packcc does accept it.

Grammar that give the problem:

%prefix "lpeg_re"

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

%auxil "lpeg_re_st *"

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

alternative     <- seq (<'/'> {printf("\n\t%s ", $1);} S seq)*
seq             <- prefix*
prefix          <- '&' S prefix / '!' S prefix / suffix
suffix          <- primary S ((<[+*?]> {printf(" %s ", $1);}
                            / '^' [+-]? num
                            / '->' {auxil->doOutput=0;} S (string / '{}' / name / num) {auxil->doOutput=1;}
                            / '=>' {auxil->doOutput=0;} S name) S)* {auxil->doOutput=1;}

primary         <- '(' {printf(" ( ");} exp  ')' {printf(" ) ");} / (string / keyword) / class / defined
                 / '{:' (name ':')? exp ':}'
                 / '=' name
                 / '@' exp
                 / '{}'
                 / '{~' exp '~}'
                 / '{|' exp '|}'   # missing table capture
                 / '{' exp '}'
         / '~?' # Expected match
         / '~>' S ( 'foldleft' / 'foldright' / 'rfoldleft' / 'rfoldright' )
         / '$' (string / name / num) # Arbitrary capture
                 / '.'
                 / name S !(asttag / arrow )
                 / '<' name '>'          ## old-style non terminals
         / '^' name
         / '%{' S name S '}'

grammar         <- definition+
definition      <- {printf("\n\n");} name  {printf(" ::=\n\t");} S (asttag S)? arrow exp

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

S               <- ([ \t\f\r\n]  /  '--' [^\r\n]*)*  # spaces and comments
name            <- <[A-Za-z_]([A-Za-z0-9_] / '-' !'>' )*> { if(auxil->doOutput) printf(" %s ", $1);}
arrow           <- (  '<--' / '<==' / '<-|'  / '<-' )
num             <- [0-9]+
string          <- <'"' [^"]* '"' / "'" [^']* "'">  { if(auxil->doOutput) printf(" %s ", $1);}
defined         <- '%' name
keyword     <-  '`' <[^`]+> '`' { printf(" '%s' ", $1);}
asttag         <- ':' S name

%%
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-1103652933

dolik-rce commented 2 years ago

This should be fixed now (by d0c92e1).