Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 212 lines (176 sloc) 3.956 kb
572660c @jnthn omg can haz lolsql to sql translator too!
authored
1 grammar LolSql {
2 rule TOP { ^ <statement> $ {*} }
3
4 rule statement {
5 'HAI!'
6 [
7 | <select>
8 | <update>
9 ]
10 KTHNXBYE
11 {*}
12 }
13
14 rule select {
15 <from>
16 <columns>
17 <where>?
18 {*}
19 }
20
21 rule update {
22 <from>
23 <set>
24 <where>?
25 {*}
26 }
27
28 rule from {
29 I\'M IN UR \`<ident>\` {*}
30 }
31
32 rule where {
33 I CAN HAZ \`$<column>=<ident>\`
34 $<comp>=[ LIEK | '=' | '<' | '<=' | '>' | '>=' ]
35 <value>
36 {*}
37 }
38
39 rule set {
40 PLZ MAKES
41 $<sets>=[ \`<ident>\` LIEKS <value> ]**','
42 {*}
43 }
44
45 rule columns {
46 SELECTIN UR <column>**',' {*}
47 }
48
49 rule column {
50 \`$<name>=<ident>\` [AZ \`$<as>=<ident>\`]? {*}
51 }
52
53 rule value { <str_value> | <number> }
54 rule str_value { \' [ '\\\'' | <-[']>+ ]* \' }
55 rule number { \d+[\.\d+]? }
56 }
57
58
59 class Column {
60 has $.name;
61 has $.as;
62 has $.new_value;
63 }
64
65
66 class Where {
67 has $.column;
68 has $.comparative;
69 has $.value;
70
71 method to_sql() {
72 return ($.column, $.comparative, $.value).join(' ');
73 }
74 }
75
76
77 class Select {
78 has $.table_name;
79 has Column @.columns;
80 has Where $.where;
81
82 method to_sql {
83 return [~] gather {
84 take 'SELECT ';
85 take @.columns.map({
86 .name ~ (.as ?? ' AS ' ~ .as !! '')
87 }).join(', ');
88 take ' FROM ' ~ $.table_name;
89 if $.where {
90 take ' WHERE ' ~ $.where.to_sql;
91 }
92 take "\n";
93 }
94 }
95 }
96
97
98 class Update {
99 has $.table_name;
100 has Column @.columns;
101 has Where $.where;
102
103 method to_sql {
104 return [~] gather {
105 take 'UPDATE ' ~ $.table_name ~ ' SET ';
106 take @.columns.map({
107 .name ~ ' = ' ~ .new_value
108 }).join(', ');
109 if $.where {
110 take ' WHERE ' ~ $.where.to_sql;
111 }
112 take "\n";
113 }
114 }
115 }
116
117
118 class LolSqlToTree {
119 method TOP($/) {
120 make $<statement>.ast;
121 }
122
123 method statement($/) {
124 if $<select> {
125 make $<select>.ast;
126 }
127 elsif $<update> {
128 make $<update>.ast;
129 }
130 }
131
132 method select($/) {
133 my %optionals;
134 if $<where> {
135 %optionals<where> = $<where>[0].ast;
136 }
137 make Select.new(
138 table_name => $<from>.ast,
139 columns => $<columns>.ast,
140 |%optionals
141 );
142 }
143
144 method update($/) {
145 my %optionals;
146 if $<where> {
147 %optionals<where> = $<where>[0].ast;
148 }
149 make Update.new(
150 table_name => $<from>.ast,
151 columns => $<set>.ast,
152 |%optionals
153 );
154 }
155
156 method from($/) {
157 make ~$<ident>;
158 }
159
160 method columns($/) {
161 my Column @columns;
162 for $<column>.list -> $col {
163 push @columns, $col.ast;
164 }
165 make @columns;
166 }
167
168 method column($/) {
169 make Column.new(
170 name => ~$<name>,
171 as => $<as>?? ~$<as> !! undef
172 );
173 }
174
175 method set($/) {
176 my Column @columns;
177 for $<set>.list -> $set {
178 push @columns, Column.new(
179 name => $<ident>.trim,
180 new_value => $<value>.trim
181 );
182 }
183 make @columns;
184 }
185
186 method where($/) {
187 my $comp = $<comp>.trim;
188 if $comp eq 'LIEK' { $comp = 'LIKE' }
189 make Where.new(
190 column => $<column>.trim,
191 comparative => $comp,
192 value => $<value>.trim
193 );
194 }
195 }
196
197
198 loop {
199 my $expr = $*IN.get;
200 my $match = LolSql.parse($expr,
201 :action(LolSqlToTree.new));
202 if $match {
203 my $tree = $match.ast;
204 say $tree.to_sql;
205 } else {
206 say "PARSE FAIL! UR DOIN IT RONG";
207 }
208 }
209
210
211
Something went wrong with that request. Please try again.