1
2
3
4
5
6 using RexTokens;
7
8 parser RexParser
9 {
10 uselexer RexLexer;
11
12 main;
13
14 RegularExpression(System.RegularExpressions.Context* context) : System.RegularExpressions.Nfa
15 ::= Alternative(context):alternative{ return alternative; }
16 ;
17
18 Alternative(System.RegularExpressions.Context* context, var System.RegularExpressions.Nfa value) : System.RegularExpressions.Nfa
19 ::= (Catenation(context):left{ value = left; } (ALT Catenation(context):right!{ value = System.RegularExpressions.Alt(*context, value, right); })*)
20 {
21 return value;
22 }
23 ;
24
25 Catenation(System.RegularExpressions.Context* context, var System.RegularExpressions.Nfa value) : System.RegularExpressions.Nfa
26 ::= (Repetition(context):left{ value = left; } (Repetition(context):right{ value = System.RegularExpressions.Cat(value, right); })*)
27 {
28 return value;
29 }
30 ;
31
32 Repetition(System.RegularExpressions.Context* context, var System.RegularExpressions.Nfa value) : System.RegularExpressions.Nfa
33 ::=
34 ( Primary(context):left{ value = left; }
35 ( STAR{ value = System.RegularExpressions.Kleene(*context, value); }
36 | PLUS{ value = System.RegularExpressions.Pos(*context, value); }
37 | QUEST{ value = System.RegularExpressions.Opt(*context, value); }
38 )?
39 )
40 {
41 return value;
42 }
43 ;
44
45 Primary(System.RegularExpressions.Context* context, var System.RegularExpressions.Nfa value) : System.RegularExpressions.Nfa
46 ::=
47 ( LPAREN Alternative(context):alt!{ value = alt; } RPAREN!
48 | ESCAPE{ value = System.RegularExpressions.MakeNfa(*context, context->MakeChar(System.RegularExpressions.MakeEscapeValue(lexer.FileName(), lexer.GetToken(pos)))); }
49 | INVERSE{ value = System.RegularExpressions.MakeNfa(*context, context->MakeChar('^')); }
50 | MINUS{ value = System.RegularExpressions.MakeNfa(*context, context->MakeChar('-')); }
51 | CHAR{ ustring match = lexer.GetMatch(span); value = System.RegularExpressions.MakeNfa(*context, context->MakeChar(match[0])); }
52 | DOT{ value = System.RegularExpressions.MakeNfa(*context, context->MakeAny()); }
53 | Class(context):cls{ value = System.RegularExpressions.MakeNfa(*context, cls); }
54 )
55 {
56 return value;
57 }
58 ;
59
60 Class(System.RegularExpressions.Context* context, var System.RegularExpressions.Class* cls) : System.RegularExpressions.Class*
61 ::= (LBRACKET{ cls = context->MakeClass(); } ((INVERSE{ cls->SetInverse(); })? (Range(context):r{ cls->AddSymbol(r); })*) RBRACKET!)
62 {
63 return cls;
64 }
65 ;
66
67 Range(System.RegularExpressions.Context* context, var System.RegularExpressions.Symbol* symbol) : System.RegularExpressions.Symbol*
68 ::= (Char:s (MINUS Char:e{ symbol = context->MakeRange(s, e); } | empty{ symbol = context->MakeChar(s); }))
69 {
70 return symbol;
71 }
72 ;
73
74 Char : uchar
75 ::= LPAREN{ return '('; }
76 | RPAREN{ return ')'; }
77 | LBRACKET{ return '['; }
78 | ALT{ return '|'; }
79 | STAR{ return '*'; }
80 | PLUS{ return '+'; }
81 | QUEST{ return '?'; }
82 | DOT{ return '.'; }
83 | ESCAPE{ return System.RegularExpressions.MakeEscapeValue(lexer.FileName(), lexer.GetToken(pos)); }
84 | INVERSE{ return '^'; }
85 | MINUS{ return '-'; }
86 | CHAR{ ustring match = lexer.GetMatch(span); return match[0]; }
87 ;
88 }