rparsec 0.4 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,266 @@
1
+ require 'import'
2
+ import :misc
3
+ class Module
4
+ include DefHelper
5
+ end
6
+ class Expr
7
+ def self.binary(*ops)
8
+ ops.each do |op|
9
+ define_method(op) do |other|
10
+ BinaryExpr.new(self, op, other)
11
+ end
12
+ end
13
+ end
14
+ binary :+,:-,:*,:/,:%
15
+ def -@
16
+ PrefixExpr.new(:-, self)
17
+ end
18
+ def self.compare(*ops)
19
+ ops.each do |op|
20
+ define_method(op) do |other|
21
+ ComparePredicate.new(self, op, other)
22
+ end
23
+ end
24
+ end
25
+ compare :'==', :'>', :'<', :'>=', :'<='
26
+ end
27
+ class LiteralExpr < Expr
28
+ def_readable :lit
29
+ def to_s
30
+ @lit.to_s
31
+ end
32
+ end
33
+ class VarExpr < Expr
34
+ def_readable :name
35
+ def to_s
36
+ "$#{name}"
37
+ end
38
+ end
39
+ class WordExpr < Expr
40
+ def_readable :name
41
+ def to_s
42
+ name
43
+ end
44
+ end
45
+ class QualifiedColumnExpr < Expr
46
+ def_readable :owner, :col
47
+ def to_s
48
+ "#{owner}.#{col}"
49
+ end
50
+ end
51
+ class WildcardExpr < Expr
52
+ Instance = WildcardExpr.new
53
+ def to_s
54
+ '*'
55
+ end
56
+ end
57
+ class BinaryExpr < Expr
58
+ def_readable :left, :op, :right
59
+ def to_s
60
+ "(#{left} #{op} #{right})"
61
+ end
62
+ end
63
+ class PostfixExpr < Expr
64
+ def_readable :expr, :op
65
+ def to_s
66
+ "(#{expr} #{op})"
67
+ end
68
+ end
69
+ class PrefixExpr < Expr
70
+ def_readable :op, :expr
71
+ def to_s
72
+ "(#{op} #{expr})"
73
+ end
74
+ end
75
+ def cases_string cases, default, result
76
+ cases.each do |cond, val|
77
+ result << " when #{cond}: #{val}"
78
+ end
79
+ unless default.nil?
80
+ result << " else #{default}"
81
+ end
82
+ result << " end"
83
+ result
84
+ end
85
+ class SimpleCaseExpr < Expr
86
+ def_readable :expr, :cases, :default
87
+ def to_s
88
+ cases_string cases, default, "case #{expr}"
89
+ end
90
+ end
91
+ class CaseExpr < Expr
92
+ def_readable :cases, :default
93
+ def to_s
94
+ cases_string cases, default, 'case'
95
+ end
96
+ end
97
+
98
+
99
+ ############Predicate########################
100
+ class Predicate
101
+ end
102
+
103
+ class ComparePredicate < Predicate
104
+ def_readable :left, :op, :right
105
+ def to_s
106
+ "#{left} #{op_name} #{right}"
107
+ end
108
+ def op_name
109
+ case op when :"!=": "<>" else op.to_s end
110
+ end
111
+ end
112
+ class CompoundPredicate < Predicate
113
+ def_readable :left, :op, :right
114
+ def to_s
115
+ "(#{left} #{op} #{right})"
116
+ end
117
+ end
118
+ class NotPredicate < Predicate
119
+ def_readable :predicate
120
+ def to_s
121
+ "(not #{predicate})"
122
+ end
123
+ end
124
+ class ExistsPredicate < Predicate
125
+ def_readable :relation
126
+ def to_s
127
+ "exists(#{relation})"
128
+ end
129
+ end
130
+ class NotExistsPredicate < Predicate
131
+ def_readable :relation
132
+ def to_s
133
+ "not exists(#{relation})"
134
+ end
135
+ end
136
+ class InRelationPredicate < Predicate
137
+ def_readable :expr, :relation
138
+ def to_s
139
+ "#{expr} in (#{relation})"
140
+ end
141
+ end
142
+ class NotInRelationPredicate < Predicate
143
+ def_readable :expr, :relation
144
+ def to_s
145
+ "#{expr} not in (#{relation})"
146
+ end
147
+ end
148
+ class InPredicate < Predicate
149
+ def_readable :expr, :vals
150
+ def to_s
151
+ "#{expr} in (#{vals.join(', ')})"
152
+ end
153
+ end
154
+ class NotInPredicate < Predicate
155
+ def_readable :expr, :vals
156
+ def to_s
157
+ "#{expr} not in (#{vals.join(', ')})"
158
+ end
159
+ end
160
+ class BetweenPredicate < Predicate
161
+ def_readable :expr, :from, :to
162
+ def to_s
163
+ "#{expr} between #{from} and #{to}"
164
+ end
165
+ end
166
+ class NotBetweenPredicate < Predicate
167
+ def_readable :expr, :from, :to
168
+ def to_s
169
+ "#{expr} not between #{from} and #{to}"
170
+ end
171
+ end
172
+ class GroupComparisonPredicate < Predicate
173
+ def_readable :group1, :op, :group2
174
+ def to_s
175
+ "#{list_exprs group1} #{op} #{list_exprs group2}"
176
+ end
177
+ def list_exprs exprs
178
+ "(#{exprs.join(', ')})"
179
+ end
180
+ end
181
+ #############Relations######################
182
+
183
+ class OrderElement
184
+ def_readable :expr, :asc
185
+ def to_s
186
+ result = "#{expr}"
187
+ unless asc
188
+ result << ' desc'
189
+ end
190
+ result
191
+ end
192
+ end
193
+ class GroupByClause
194
+ def_readable :exprs, :having
195
+ def to_s
196
+ result = exprs.join(', ')
197
+ unless having.nil?
198
+ result << " having #{having}"
199
+ end
200
+ result
201
+ end
202
+ end
203
+ class Relation
204
+ def as_inner
205
+ to_s
206
+ end
207
+ end
208
+ class TableRelation < Relation
209
+ def_readable :table
210
+ def to_s
211
+ table
212
+ end
213
+ end
214
+ class SelectRelation < Relation
215
+ def_readable :select, :distinct, :from, :where, :groupby, :orderby
216
+ def to_s
217
+ result = "select "
218
+ if distinct
219
+ result << 'distinct '
220
+ end
221
+ result << "#{select.join(', ')} from #{from.as_inner}"
222
+ unless where.nil?
223
+ result << " where #{where}"
224
+ end
225
+ unless groupby.nil?
226
+ result << " group by #{groupby}"
227
+ end
228
+ unless orderby.nil?
229
+ result << " order by #{orderby.join(', ')}"
230
+ end
231
+ result
232
+ end
233
+ def as_inner
234
+ "(#{self})"
235
+ end
236
+ end
237
+ class LimitRelation < Relation
238
+ def_readable :rel, :limit
239
+ def to_s
240
+ "#{rel} limit #{limit}"
241
+ end
242
+ end
243
+ class JoinRelation < Relation
244
+ def_readable :kind, :left, :right, :on
245
+ def to_s
246
+ "#{left} #{kind} join #{right} on #{on}"
247
+ end
248
+ end
249
+ class CrossJoinRelation < Relation
250
+ def_readable :left, :right
251
+ def to_s
252
+ "#{left} cross join #{right}"
253
+ end
254
+ end
255
+ class AliasRelation < Relation
256
+ def_readable :relation, :name
257
+ def to_s
258
+ "#{relation.as_inner} AS #{name}"
259
+ end
260
+ end
261
+ class UnionRelation < Relation
262
+ def_readable :left, :all, :right
263
+ def to_s
264
+ "#{left} union #{case when all: 'all ' else '' end}#{right}"
265
+ end
266
+ end
@@ -0,0 +1,255 @@
1
+ require 'import'
2
+ import :parsers, :keywords, :operators, :functors, :expressions
3
+ class Method
4
+ include FunctorMixin
5
+ end
6
+ class Proc
7
+ include FunctorMixin
8
+ end
9
+ module SqlParser
10
+ include Functors
11
+ include Parsers
12
+ extend Parsers
13
+ MyKeywords = Keywords.case_insensitive(%w{
14
+ select from where group by having order desc asc
15
+ inner left right full outer inner join on cross
16
+ union all distinct as exists in between limit
17
+ case when else end and or not true false
18
+ })
19
+ MyOperators = Operators.new(%w{+ - * / % = > < >= <= <> != : ( ) . ,})
20
+ def self.operators(*ops)
21
+ result = []
22
+ ops.each do |op|
23
+ result << (MyOperators[op] >> op.to_sym)
24
+ end
25
+ sum(*result)
26
+ end
27
+ Comparators = operators(*%w{= > < >= <= <> !=})
28
+ StringLiteral = (char(?') >> (not_char(?')|str("''")).many_.fragment << char(?')).
29
+ map do |raw|
30
+ raw.gsub!(/''/,"'")
31
+ end
32
+ QuotedName = char(?[) >> not_char(?]).many_.fragment << char(?])
33
+ Variable = char(?$) >> word
34
+ MyLexer = number.token(:number) | StringLiteral.token(:string) | Variable.token(:var) | QuotedName.token(:word) |
35
+ MyKeywords.lexer | MyOperators.lexer
36
+ MyLexeme = MyLexer.lexeme(whitespaces | comment_line('#')) << eof
37
+
38
+
39
+ ######################################### utilities #########################################
40
+ def keyword
41
+ MyKeywords
42
+ end
43
+ def operator
44
+ MyOperators
45
+ end
46
+ def comma
47
+ operator[',']
48
+ end
49
+ def list expr
50
+ paren(expr.delimited(comma))
51
+ end
52
+ def word(&block)
53
+ if block.nil?
54
+ token(:word, &Id)
55
+ else
56
+ token(:word, &block)
57
+ end
58
+ end
59
+ def paren parser
60
+ operator['('] >> parser << operator[')']
61
+ end
62
+ def ctor cls
63
+ cls.method :new
64
+ end
65
+ def rctor cls, arity=2
66
+ ctor(cls).reverse_curry arity
67
+ end
68
+ ################################### predicate parser #############################
69
+ def logical_operator op
70
+ proc{|a,b|CompoundPredicate.new(a,op,b)}
71
+ end
72
+ def make_predicate expr, rel
73
+ expr_list = list expr
74
+ comparison = make_comparison_predicate expr, rel
75
+ group_comparison = sequence(expr_list, Comparators, expr_list, &ctor(GroupComparisonPredicate))
76
+ bool = nil
77
+ lazy_bool = lazy{bool}
78
+ bool_term = keyword[:true] >> true | keyword[:false] >> false |
79
+ comparison | group_comparison | paren(lazy_bool) |
80
+ make_exists(rel) | make_not_exists(rel)
81
+ bool_table = OperatorTable.new.
82
+ infixl(keyword[:or] >> logical_operator(:or), 20).
83
+ infixl(keyword[:and] >> logical_operator(:and), 30).
84
+ prefix(keyword[:not] >> ctor(NotPredicate), 40)
85
+ bool = Expressions.build(bool_term, bool_table)
86
+ end
87
+ def make_exists rel
88
+ keyword[:exists] >> rel.map(&ctor(ExistsPredicate))
89
+ end
90
+ def make_not_exists rel
91
+ keyword[:not] >> keyword[:exists] >> rel.map(&ctor(NotExistsPredicate))
92
+ end
93
+ def make_in expr
94
+ keyword[:in] >> list(expr) >> map(&rctor(InPredicate))
95
+ end
96
+ def make_not_in expr
97
+ keyword[:not] >> keyword[:in] >> list(expr) >> map(&rctor(NotInPredicate))
98
+ end
99
+ def make_in_relation rel
100
+ keyword[:in] >> rel.map(&rctor(InRelationPredicate))
101
+ end
102
+ def make_not_in_relation rel
103
+ keyword[:not] >> keyword[:in] >> rel.map(&rctor(NotInRelationPredicate))
104
+ end
105
+ def make_between expr
106
+ make_between_clause(expr, &ctor(BetweenPredicate))
107
+ end
108
+ def make_not_between expr
109
+ keyword[:not] >> make_between_clause(expr, &ctor(NotBetweenPredicate))
110
+ end
111
+ def make_comparison_predicate expr, rel
112
+ comparison = sequence(Comparators, expr) do |op,e2|
113
+ proc{|e1|ComparePredicate.new(e1, op, e2)}
114
+ end
115
+ in_clause = make_in expr
116
+ not_in_clause = make_not_in expr
117
+ in_relation = make_in_relation rel
118
+ not_in_relation = make_not_in_relation rel
119
+ between = make_between expr
120
+ not_between = make_not_between expr
121
+ compare_with = comparison | in_clause | not_in_clause |
122
+ in_relation | not_in_relation | between | not_between
123
+ sequence(expr, compare_with, &Feed)
124
+ end
125
+ def make_between_clause expr, &maker
126
+ factory = proc do |a,_,b|
127
+ proc {|v|maker.call(v,a,b)}
128
+ end
129
+ variant1 = keyword[:between] >> paren(sequence(expr, comma, expr, &factory))
130
+ variant2 = keyword[:between] >> sequence(expr, keyword[:and], expr, &factory)
131
+ variant1 | variant2
132
+ end
133
+
134
+ ################################ expression parser ###############################
135
+ def calculate_simple_cases(val, cases, default)
136
+ SimpleCaseExpr.new(val, cases, default)
137
+ end
138
+ def calculate_full_cases(cases, default)
139
+ CaseExpr.new(cases, default)
140
+ end
141
+ def make_expression predicate, rel
142
+ expr = nil
143
+ lazy_expr = lazy{expr}
144
+ simple_case = sequence(keyword[:when], lazy_expr, operator[':'], lazy_expr) do |_,cond,_,val|
145
+ [cond, val]
146
+ end
147
+ full_case = sequence(keyword[:when], predicate, operator[':'], lazy_expr) do |_,cond,_,val|
148
+ [cond, val]
149
+ end
150
+ default_case = (keyword[:else] >> lazy_expr).optional
151
+ simple_when_then = sequence(lazy_expr, simple_case.many, default_case,
152
+ keyword[:end]) do |val, cases, default, _|
153
+ calculate_simple_cases(val, cases, default)
154
+ end
155
+ full_when_then = sequence(full_case.many, default_case, keyword[:end]) do |cases, default, _|
156
+ calculate_full_cases(cases, default)
157
+ end
158
+ case_expr = keyword[:case] >> (simple_when_then | full_when_then)
159
+ wildcard = operator[:*] >> WildcardExpr::Instance
160
+ lit = token(:number, :string, &ctor(LiteralExpr)) | token(:var, &ctor(VarExpr))
161
+ atom = lit | wildcard |
162
+ sequence(word, operator['.'], word|wildcard) {|owner, _, col| QualifiedColumnExpr.new owner, col} |
163
+ word(&ctor(WordExpr))
164
+ term = atom | (operator['('] >> lazy_expr << operator[')']) | case_expr
165
+ table = OperatorTable.new.
166
+ infixl(operator['+'] >> Plus, 20).
167
+ infixl(operator['-'] >> Minus, 20).
168
+ infixl(operator['*'] >> Mul, 30).
169
+ infixl(operator['/'] >> Div, 30).
170
+ infixl(operator['%'] >> Mod, 30).
171
+ prefix(operator['-'] >> Neg, 50)
172
+ expr = Expressions.build(term, table)
173
+ end
174
+
175
+ ################################ relation parser ###############################
176
+ def make_relation expr, pred
177
+ exprs = expr.delimited1(comma)
178
+ relation = nil
179
+ lazy_relation = lazy{relation}
180
+ term_relation = word {|w|TableRelation.new w} | operator['('] >> lazy_relation << operator[')']
181
+ sub_relation = sequence(term_relation, (keyword[:as].optional >> word).optional) do |rel, name|
182
+ case when name.nil?: rel else AliasRelation.new(rel, name) end
183
+ end
184
+ joined_relation = sub_relation.postfix(join_maker(lazy{joined_relation}, pred))
185
+ where_clause = keyword[:where] >> pred
186
+ order_element = sequence(expr, (keyword[:asc] >> true | keyword[:desc] >> false).optional(true),
187
+ &ctor(OrderElement))
188
+ order_elements = order_element.separated1(comma)
189
+ exprs = expr.separated1(comma)
190
+ order_by_clause = keyword[:order] >> keyword[:by] >> order_elements
191
+ group_by = keyword[:group] >> keyword[:by] >> exprs
192
+ group_by_clause = sequence(group_by, (keyword[:having] >> pred).optional, &ctor(GroupByClause))
193
+ relation = sub_relation | sequence(keyword[:select],
194
+ keyword[:distinct].optional(false), exprs,
195
+ keyword[:from], joined_relation,
196
+ where_clause.optional, group_by_clause.optional, order_by_clause.optional
197
+ ) do |_, distinct, projected, _, from, where, groupby, orderby|
198
+ SelectRelation.new(projected, distinct, from, where, groupby, orderby)
199
+ end
200
+ relation = sequence(relation, (keyword[:limit] >> token(:number, &To_i)).optional) do |rel, limit|
201
+ case when limit.nil?: rel else LimitRelation.new(rel, limit) end
202
+ end
203
+ relation = relation.infixl(union_maker)
204
+ end
205
+ def union_maker
206
+ keyword[:union] >> (keyword[:all]>>true|false).map do |all|
207
+ proc {|r1, r2|UnionRelation.new(r1, all, r2)}
208
+ end
209
+ end
210
+ def join_maker rel, pred
211
+ crossjoin = keyword[:cross] >> keyword[:join] >> rel.map(&rctor(CrossJoinRelation))
212
+ leftjoin = outer_join :left
213
+ rightjoin = outer_join :right
214
+ fulljoin = outer_join :full
215
+ innerjoin = keyword[:inner].optional >> keyword[:join] >> :inner
216
+ join_with_condition = sequence(sum(leftjoin, rightjoin, innerjoin), rel,
217
+ keyword[:on], pred) do |kind, r, _, on|
218
+ proc{|r0|JoinRelation.new(kind, r0, r, on)}
219
+ end
220
+ sum(crossjoin, join_with_condition)
221
+ end
222
+ def outer_join kind
223
+ keyword[kind] >> keyword[:outer].optional >> keyword[:join] >> kind
224
+ end
225
+
226
+
227
+
228
+ ########################## put together ###############################
229
+ def expression
230
+ assemble[0]
231
+ end
232
+
233
+ def relation
234
+ assemble[2]
235
+ end
236
+ def predicate
237
+ assemble[1]
238
+ end
239
+
240
+ def assemble
241
+ pred = nil
242
+ rel = nil
243
+ lazy_predicate = lazy{pred}
244
+ lazy_rel = lazy{rel}
245
+ expr = make_expression lazy_predicate, lazy_rel
246
+ pred = make_predicate expr, lazy_rel
247
+ rel = make_relation expr, pred
248
+ return expr, pred, rel
249
+ end
250
+
251
+
252
+ def make parser
253
+ MyLexeme.nested(parser << eof)
254
+ end
255
+ end