-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
15 changed files
with
504 additions
and
83 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -35,3 +35,5 @@ measurements | |
Gemfile.lock | ||
|
||
## PROJECT::SPECIFIC | ||
lib/sql/scanner.rb | ||
lib/sql/parser.rb |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,4 +3,6 @@ AllCops: | |
- 'Gemfile' | ||
Excludes: | ||
- 'Gemfile.devtools' | ||
- 'lib/sql/parser.rb' | ||
- 'lib/sql/scanner.rb' | ||
- 'vendor/**' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,217 @@ | ||
# Rule naming conventions follow the ANSI SQL-92 BNF grammar: | ||
# http://savage.net.au/SQL/sql-92.bnf | ||
|
||
# An SQL parser | ||
class SQL::Parser | ||
|
||
token select from as | ||
true false null | ||
left_paren right_paren | ||
comma period | ||
pow | ||
asterisk solidus mod | ||
plus_sign minus_sign | ||
E | ||
identifier | ||
unsigned_integer | ||
string | ||
|
||
prechigh | ||
left IDENTIFIER_SEPARATOR | ||
right UNARY | ||
left pow | ||
left asterisk solidus mod | ||
left plus_sign minus_sign | ||
preclow | ||
|
||
start | ||
query_specification | ||
|
||
rule | ||
sign | ||
: plus_sign { result = :uplus } | ||
| minus_sign { result = :uminus } | ||
|
||
truth_value | ||
: true { result = s(:true) } | ||
| false { result = s(:false) } | ||
|
||
general_literal | ||
: character_string_literal | ||
| truth_value | ||
| null { result = s(:null) } | ||
|
||
character_string_literal | ||
: character_string_literal string { result = s(:string, [*val[0], val[1]].join) } | ||
| string { result = s(:string, val[0]) } | ||
|
||
subquery | ||
: left_paren query_expression right_paren { result = val[1] } | ||
|
||
query_expression | ||
: non_join_query_expression | ||
|
||
non_join_query_expression | ||
: non_join_query_term | ||
|
||
non_join_query_term | ||
: non_join_query_primary | ||
|
||
non_join_query_primary | ||
: simple_table | ||
| left_paren non_join_query_term right_paren { result = val[1] } | ||
|
||
simple_table | ||
: query_specification | ||
|
||
table_name | ||
: qualified_name | ||
|
||
qualified_name | ||
: qualified_identifier | ||
|
||
qualified_identifier | ||
: identifier { result = s(:id, *val) } | ||
|
||
column_name | ||
: identifier { result = s(:id, *val) } | ||
|
||
column_reference | ||
: qualifier period =IDENTIFIER_SEPARATOR column_name { result = val[0].concat(val[2]) } | ||
| column_name | ||
|
||
qualifier | ||
: table_name | ||
|
||
correlation_name | ||
: identifier { result = s(:id, *val) } | ||
|
||
query_specification | ||
: query_specification table_expression { result = val[0].append(val[1]) } | ||
| select select_list { result = s(:select, val[1]) } | ||
|
||
select_list | ||
: asterisk { result = s(:fields, s(:asterisk)) } | ||
| select_list comma select_sublist { result = val[0].append(val[2]) } | ||
| select_sublist { result = s(:fields, *val) } | ||
|
||
select_sublist | ||
: derived_column | ||
| qualifier period =IDENTIFIER_SEPARATOR asterisk { result = val[0].append(s(:asterisk)) } | ||
|
||
derived_column | ||
: derived_column as_clause { result = s(:as, *val) } | ||
| value_expression | ||
|
||
as_clause | ||
: as column_name { result = val[1] } | ||
|
||
table_expression | ||
: from_clause | ||
|
||
from_clause | ||
: from table_reference { result = val[1] } | ||
| from derived_table_reference { result = val[1] } | ||
|
||
table_reference | ||
: table_reference correlation_specification { result = s(:as, *val) } | ||
| table_name | ||
|
||
derived_table_reference | ||
: derived_table correlation_specification { result = s(:as, *val) } | ||
|
||
derived_table | ||
: table_subquery | ||
|
||
table_subquery | ||
: subquery | ||
|
||
correlation_specification | ||
: as correlation_name { result = val[1] } | ||
|
||
value_expression | ||
: numeric_value_expression | ||
|
||
numeric_value_expression | ||
: term | ||
| numeric_value_expression plus_sign term { result = s(:add, val[0], val[2]) } | ||
| numeric_value_expression minus_sign term { result = s(:sub, val[0], val[2]) } | ||
|
||
term | ||
: factor | ||
| term pow factor { result = s(:pow, val[0], val[2]) } | ||
| term asterisk factor { result = s(:mul, val[0], val[2]) } | ||
| term solidus factor { result = s(:div, val[0], val[2]) } | ||
| term mod factor { result = s(:mod, val[0], val[2]) } | ||
|
||
factor | ||
: sign =UNARY numeric_primary { result = s(*val) } | ||
| numeric_primary | ||
|
||
numeric_primary | ||
: value_expression_primary | ||
|
||
value_expression_primary | ||
: unsigned_value_specification | ||
| column_reference | ||
| left_paren value_expression right_paren { result = val[1] } | ||
|
||
unsigned_value_specification | ||
: unsigned_literal | ||
|
||
unsigned_literal | ||
: unsigned_numeric_literal | ||
| general_literal | ||
|
||
unsigned_numeric_literal | ||
: exact_numeric_literal | ||
| approximate_numeric_literal | ||
|
||
exact_numeric_literal | ||
: exact_numeric_literal period unsigned_integer { result = s(:float, sprintf('%d.%d', *val[0], val[2]).to_f) } | ||
| unsigned_integer { result = s(:integer, val[0]) } | ||
|
||
approximate_numeric_literal | ||
: mantissa E exponent { result = s(:float, sprintf('%fE%d', *val[0], *val[2]).to_f) } | ||
|
||
mantissa | ||
: exact_numeric_literal | ||
|
||
exponent | ||
: signed_integer | ||
|
||
signed_integer | ||
: sign =UNARY unsigned_integer { | ||
op = case val[0] | ||
when :uplus then :+@ | ||
when :uminus then :-@ | ||
end | ||
result = s(:integer, val[1].public_send(op)) | ||
} | ||
| unsigned_integer { result = s(:integer, *val) } | ||
end | ||
|
||
---- inner | ||
include NodeHelper | ||
|
||
attr_reader :result | ||
|
||
def self.parse(input, scanner_class = Scanner) | ||
new(scanner_class.new(input)).parse | ||
end | ||
|
||
def initialize(scanner) | ||
@tokens = scanner.each | ||
super() | ||
end | ||
|
||
def parse | ||
@result ||= do_parse | ||
self | ||
end | ||
|
||
def next_token | ||
@tokens.next | ||
rescue StopIteration | ||
# return nil | ||
end |
Oops, something went wrong.