%{ #include #include "ast.h" #include "lex-pattern.h" void yyerror(const char *msg) { fprintf(stderr, "%s\n", msg); } %} %output "parse-pattern.c" %defines "parse-pattern.h" %union { long lval; char *sval; struct atom *atom; struct repeat repeat; } %token END 0 "end of file" %token T_BADLIT %token T_NOMEM %token T_ALPHABETIC %token T_NUMERIC %token T_UPPERCASE %token T_LOWERCASE %token T_CONTROL %token T_PUNCTUATION %token T_EVERYTHING %token T_LPAREN "(" %token T_RPAREN ")" %token T_COMMA "," %token T_PERIOD "." %token T_INTEGER %token T_STRING %type alternation %type atom %type input %type sequence %type molecule %type repeat %% start: input END { ast = $1; } ; input: molecule | input molecule { $$ = mkatom(&(struct atom) { .type = ATOM_SEQUENCE, .u = { .children = { $1, $2 } } }); } ; molecule: repeat sequence { if ($1.min == 1 && $1.max == 1) { $$ = $2; } else { $$ = mkatom(&(struct atom) { .type = ATOM_REPETITION, .u = { .repeat = { .counts = $1, .child = $2 } } }); } } ; repeat: T_INTEGER T_PERIOD T_INTEGER { $$ = (struct repeat) { $1, $3 }; } | T_INTEGER T_PERIOD { $$ = (struct repeat) { $1, -1 }; } | T_PERIOD T_INTEGER { $$ = (struct repeat) { 0, $2 }; } | T_PERIOD { $$ = (struct repeat) { 0, -1 }; } | T_INTEGER { $$ = (struct repeat) { $1, $1 }; } ; sequence: atom | sequence atom { $$ = mkatom(&(struct atom) { .type = ATOM_SEQUENCE, .u = { .children = { $1, $2 } } }); } ; atom: T_ALPHABETIC { $$ = mkatom(&(struct atom) { .type = ATOM_ALPHABETIC }); } | T_NUMERIC { $$ = mkatom(&(struct atom) { .type = ATOM_NUMERIC }); } | T_UPPERCASE { $$ = mkatom(&(struct atom) { .type = ATOM_UPPERCASE }); } | T_LOWERCASE { $$ = mkatom(&(struct atom) { .type = ATOM_LOWERCASE }); } | T_CONTROL { $$ = mkatom(&(struct atom) { .type = ATOM_CONTROL }); } | T_PUNCTUATION { $$ = mkatom(&(struct atom) { .type = ATOM_PUNCTUATION }); } | T_EVERYTHING { $$ = mkatom(&(struct atom) { .type = ATOM_EVERYTHING }); } | T_STRING { $$ = mkatom(&(struct atom) { .type = ATOM_LITERAL, .u = { .literal = $1 } }); } | T_LPAREN alternation T_RPAREN { $$ = $2; } ; alternation: molecule | alternation T_COMMA molecule { $$ = mkatom(&(struct atom) { .type = ATOM_ALTERNATION, .u = { .children = { $1, $3 } } }); } ;