Class: SQLTree::Parser
- Inherits:
-
Object
- Object
- SQLTree::Parser
- Defined in:
- lib/sql_tree/parser.rb
Instance Method Summary collapse
- #consume(check) ⇒ Object
- #current_token ⇒ Object
- #debug ⇒ Object
- #error(token) ⇒ Object
- #next_token ⇒ Object
- #parse(tokens, options = {:as => :query}) ⇒ Object
- #parse_comparison_expression ⇒ Object
- #parse_expression ⇒ Object
- #parse_field ⇒ Object
- #parse_from_clause ⇒ Object
- #parse_from_expression ⇒ Object
- #parse_function_call ⇒ Object
- #parse_logical_expression ⇒ Object
- #parse_logical_not_expression ⇒ Object
- #parse_primary_arithmetic_expression ⇒ Object
- #parse_query ⇒ Object
- #parse_secondary_arithmetic_expression ⇒ Object
- #parse_select_clause ⇒ Object
- #parse_select_expression ⇒ Object
- #parse_select_query ⇒ Object
- #parse_single_expression ⇒ Object
- #parse_table_import ⇒ Object
- #parse_value ⇒ Object
- #parse_variable ⇒ Object
- #parse_variable_name ⇒ Object
- #parse_where_clause ⇒ Object
- #peek_token(distance = 1) ⇒ Object
Instance Method Details
#consume(check) ⇒ Object
11 12 13 |
# File 'lib/sql_tree/parser.rb', line 11 def consume(check) error(current_token) unless check == next_token end |
#current_token ⇒ Object
3 4 5 |
# File 'lib/sql_tree/parser.rb', line 3 def current_token @current_token end |
#debug ⇒ Object
23 24 25 |
# File 'lib/sql_tree/parser.rb', line 23 def debug p @tokens.inspect end |
#error(token) ⇒ Object
19 20 21 |
# File 'lib/sql_tree/parser.rb', line 19 def error(token) raise "Unexpected token: #{token.inspect}" end |
#next_token ⇒ Object
7 8 9 |
# File 'lib/sql_tree/parser.rb', line 7 def next_token @current_token = @tokens.shift end |
#parse(tokens, options = {:as => :query}) ⇒ Object
27 28 29 30 31 32 33 34 35 36 |
# File 'lib/sql_tree/parser.rb', line 27 def parse(tokens, = {:as => :query}) if tokens.kind_of?(String) tokenizer = SQLTree::Tokenizer.new @tokens = tokenizer.tokenize(tokens) else @tokens = tokens end send("parse_#{options[:as]}".to_sym) end |
#parse_comparison_expression ⇒ Object
120 121 122 123 124 125 126 |
# File 'lib/sql_tree/parser.rb', line 120 def parse_comparison_expression expr = parse_primary_arithmetic_expression while [SQLTree::Token::EQ, SQLTree::Token::NE, SQLTree::Token::GT, SQLTree::Token::GTE, SQLTree::Token::LT, SQLTree::Token::LTE].include?(peek_token) expr = SQLTree::Node::ComparisonExpression.new(next_token.literal, expr, parse_primary_arithmetic_expression) end return expr end |
#parse_expression ⇒ Object
99 100 101 |
# File 'lib/sql_tree/parser.rb', line 99 def parse_expression parse_logical_expression end |
#parse_field ⇒ Object
180 181 182 183 184 185 186 187 188 189 190 191 192 |
# File 'lib/sql_tree/parser.rb', line 180 def parse_field lhs = next_token lhs = (lhs == SQLTree::Token::MULTIPLY) ? :all : lhs.literal if peek_token == SQLTree::Token::DOT consume(SQLTree::Token::DOT) rhs = next_token rhs = (rhs == SQLTree::Token::MULTIPLY) ? :all : rhs.literal SQLTree::Node::Field.new(rhs, lhs) else SQLTree::Node::Field.new(lhs) end end |
#parse_from_clause ⇒ Object
152 153 154 155 156 157 158 159 160 161 |
# File 'lib/sql_tree/parser.rb', line 152 def parse_from_clause consume(SQLTree::Token::FROM) from_expressions = [parse_from_expression] while peek_token == SQLTree::Token::COMMA consume(SQLTree::Token::COMMA) from_expressions << parse_from_expression end return from_expressions end |
#parse_from_expression ⇒ Object
163 164 165 166 167 168 169 |
# File 'lib/sql_tree/parser.rb', line 163 def parse_from_expression from_expression = case peek_token when SQLTree::Token::Variable; parse_table_import else; error(peek_token) end return from_expression end |
#parse_function_call ⇒ Object
140 141 142 143 144 145 146 147 148 149 150 |
# File 'lib/sql_tree/parser.rb', line 140 def parse_function_call expr = SQLTree::Node::FunctionExpression.new(next_token.literal) consume(SQLTree::Token::LPAREN) until peek_token == SQLTree::Token::RPAREN expr.arguments << parse_expression consume(SQLTree::Token::COMMA) if peek_token == SQLTree::Token::COMMA end consume(SQLTree::Token::RPAREN) return expr end |
#parse_logical_expression ⇒ Object
128 129 130 131 132 133 134 |
# File 'lib/sql_tree/parser.rb', line 128 def parse_logical_expression expr = parse_comparison_expression while [SQLTree::Token::AND, SQLTree::Token::OR].include?(peek_token) expr = SQLTree::Node::LogicalExpression.new(next_token.literal, [expr, parse_comparison_expression]) end return expr end |
#parse_logical_not_expression ⇒ Object
136 137 138 |
# File 'lib/sql_tree/parser.rb', line 136 def parse_logical_not_expression end |
#parse_primary_arithmetic_expression ⇒ Object
112 113 114 115 116 117 118 |
# File 'lib/sql_tree/parser.rb', line 112 def parse_primary_arithmetic_expression expr = parse_secondary_arithmetic_expression while [SQLTree::Token::PLUS, SQLTree::Token::MINUS].include?(peek_token) expr = SQLTree::Node::ArithmeticExpression.new(next_token.literal, expr, parse_secondary_arithmetic_expression) end return expr end |
#parse_query ⇒ Object
38 39 40 41 42 43 |
# File 'lib/sql_tree/parser.rb', line 38 def parse_query case peek_token when SQLTree::Token::SELECT; parse_select_query else raise "Could not parse query" end end |
#parse_secondary_arithmetic_expression ⇒ Object
103 104 105 106 107 108 109 |
# File 'lib/sql_tree/parser.rb', line 103 def parse_secondary_arithmetic_expression expr = parse_single_expression while [SQLTree::Token::PLUS, SQLTree::Token::MINUS].include?(peek_token) expr = SQLTree::Node::ArithmeticExpression.new(next_token.literal, expr, parse_single_expression) end return expr end |
#parse_select_clause ⇒ Object
61 62 63 64 65 66 67 68 |
# File 'lib/sql_tree/parser.rb', line 61 def parse_select_clause expressions = [parse_select_expression] while peek_token == SQLTree::Token::COMMA consume(SQLTree::Token::COMMA) expressions << parse_select_expression end return expressions end |
#parse_select_expression ⇒ Object
70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/sql_tree/parser.rb', line 70 def parse_select_expression if peek_token == SQLTree::Token::MULTIPLY consume(SQLTree::Token::MULTIPLY) return SQLTree::Node::ALL_FIELDS else expr = SQLTree::Node::SelectExpression.new(parse_expression) if peek_token == SQLTree::Token::AS consume(SQLTree::Token::AS) expr.variable = parse_variable_name end return expr end end |
#parse_select_query ⇒ Object
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/sql_tree/parser.rb', line 45 def parse_select_query select_node = SQLTree::Node::SelectQuery.new consume(SQLTree::Token::SELECT) if peek_token == SQLTree::Token::DISTINCT consume(SQLTree::Token::DISTINCT) select_node.distinct = true end select_node.select = parse_select_clause select_node.from = parse_from_clause if peek_token == SQLTree::Token::FROM select_node.where = parse_where_clause if peek_token == SQLTree::Token::WHERE return select_node end |
#parse_single_expression ⇒ Object
84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/sql_tree/parser.rb', line 84 def parse_single_expression if SQLTree::Token::LPAREN === peek_token(1) consume(SQLTree::Token::LPAREN) expr = parse_expression consume(SQLTree::Token::RPAREN) return expr elsif SQLTree::Token::Variable === peek_token(1) && peek_token(2) == SQLTree::Token::LPAREN return parse_function_call elsif SQLTree::Token::Variable === peek_token(1) return parse_variable else return parse_value end end |
#parse_table_import ⇒ Object
171 172 173 174 175 176 177 178 |
# File 'lib/sql_tree/parser.rb', line 171 def parse_table_import table_import = SQLTree::Node::TableImport.new(next_token.literal) if peek_token == SQLTree::Token::AS || SQLTree::Token::Variable === peek_token consume(SQLTree::Token::AS) if peek_token == SQLTree::Token::AS table_import.variable = parse_variable end return table_import end |
#parse_value ⇒ Object
206 207 208 |
# File 'lib/sql_tree/parser.rb', line 206 def parse_value SQLTree::Node::Value.new(next_token.literal) end |
#parse_variable ⇒ Object
198 199 200 201 202 203 204 |
# File 'lib/sql_tree/parser.rb', line 198 def parse_variable if peek_token(2) == SQLTree::Token::DOT parse_field else parse_variable_name end end |
#parse_variable_name ⇒ Object
194 195 196 |
# File 'lib/sql_tree/parser.rb', line 194 def parse_variable_name return SQLTree::Node::Variable.new(next_token.literal) end |
#parse_where_clause ⇒ Object
211 212 |
# File 'lib/sql_tree/parser.rb', line 211 def parse_where_clause end |
#peek_token(distance = 1) ⇒ Object
15 16 17 |
# File 'lib/sql_tree/parser.rb', line 15 def peek_token(distance = 1) @tokens[distance - 1] end |