1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
%{
#include <stdio.h>
#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 <lval> T_INTEGER
%token <sval> T_STRING
%type <atom> alternation
%type <atom> atom
%type <atom> input
%type <atom> sequence
%type <atom> molecule
%type <repeat> 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 } } }); }
;
|