Class: CqlRuby::CqlParser
- Inherits:
-
Object
- Object
- CqlRuby::CqlParser
- Defined in:
- lib/cql_ruby/cql_parser.rb
Overview
Compiles CQL strings into parse trees of CQLNode subtypes.
Constant Summary collapse
- V1POINT1 =
12368
- V1POINT2 =
12369
- V1POINT1SORT =
12370
Instance Attribute Summary collapse
-
#compat ⇒ Object
Returns the value of attribute compat.
-
#debug ⇒ Object
Returns the value of attribute debug.
-
#lex_debug ⇒ Object
Returns the value of attribute lex_debug.
-
#lexer ⇒ Object
Returns the value of attribute lexer.
Instance Method Summary collapse
- #gather_modifiers(base) ⇒ Object
-
#initialize(set_compat = CqlParser::V1POINT2) ⇒ CqlParser
constructor
A new instance of CqlParser.
- #log(s) ⇒ Object
- #match(token) ⇒ Object
- #match_symbol(symbol_type) ⇒ Object
- #parse(s) ⇒ Object
- #parse_prefix(index, relation, top_level) ⇒ Object
- #parse_query(index, relation) ⇒ Object
- #parse_term(index, relation) ⇒ Object
- #parse_top_level_prefixes(index, relation) ⇒ Object
- #relation? ⇒ Boolean
Constructor Details
Instance Attribute Details
#compat ⇒ Object
Returns the value of attribute compat.
9 10 11 |
# File 'lib/cql_ruby/cql_parser.rb', line 9 def compat @compat end |
#debug ⇒ Object
Returns the value of attribute debug.
9 10 11 |
# File 'lib/cql_ruby/cql_parser.rb', line 9 def debug @debug end |
#lex_debug ⇒ Object
Returns the value of attribute lex_debug.
9 10 11 |
# File 'lib/cql_ruby/cql_parser.rb', line 9 def lex_debug @lex_debug end |
#lexer ⇒ Object
Returns the value of attribute lexer.
9 10 11 |
# File 'lib/cql_ruby/cql_parser.rb', line 9 def lexer @lexer end |
Instance Method Details
#gather_modifiers(base) ⇒ Object
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/cql_ruby/cql_parser.rb', line 84 def gather_modifiers( base ) log "gather modifiers" ms = ModifierSet.new( base ) until @lexer.token_type != '/' match( '/' ) raise CqlException, "parse error: expected modifier, got: #{@lexer.render}" unless @lexer.word? type = @lexer.value.downcase match( @lexer.token_type ) if not relation? ms.add_modifier( type ) else comparison = @lexer.render( @lexer.token_type, false ) match( @lexer.token_type ) value = match_symbol( "modifier value" ) ms.add_modifier( type, comparison, value ) end end ms end |
#log(s) ⇒ Object
182 183 184 |
# File 'lib/cql_ruby/cql_parser.rb', line 182 def log( s ) puts "log: #{s}" if @debug end |
#match(token) ⇒ Object
146 147 148 149 150 151 |
# File 'lib/cql_ruby/cql_parser.rb', line 146 def match( token ) if @lexer.token_type != token raise CqlException, "parse exception expected: #{@lexer.render( token, true )}, got: #{@lexer.render(token)}" end @lexer.next_token end |
#match_symbol(symbol_type) ⇒ Object
153 154 155 156 157 158 159 160 161 162 |
# File 'lib/cql_ruby/cql_parser.rb', line 153 def match_symbol( symbol_type ) log "in match_symbol(#{symbol_type})" if CqlLexer.symbol_tokens.include?( @lexer.token_type ) symbol = @lexer.value match( @lexer.token_type ) return symbol end raise CqlException, "parse exception match_symbol, expected: #{symbol_type}, got: #{@lexer.render()}" end |
#parse(s) ⇒ Object
21 22 23 24 25 26 27 28 29 30 |
# File 'lib/cql_ruby/cql_parser.rb', line 21 def parse( s ) @lexer = CqlLexer.new( s, @lex_debug ) log( "starting parser" ) @lexer.next_token root = parse_top_level_prefixes( "cql.serverChoice", CqlRelation.new( @compat == CqlParser::V1POINT2 ? "=" : "scr" )) raise CqlException, "junk after end: #{@lexer.render}" unless @lexer.eof? root end |
#parse_prefix(index, relation, top_level) ⇒ Object
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 |
# File 'lib/cql_ruby/cql_parser.rb', line 164 def parse_prefix( index, relation, top_level ) log "prefix mapping" match( '>' ) name = nil identifier = match_symbol( "prefix-name" ) if @lexer.token_type == '=' match('=') name = identifier identifier = match_symbol( "prefix-identifier" ) end node = top_level ? parse_top_level_prefixes( index, relation ) : parse_query( index, relation ) CqlPrefixNode.new( name, identifier, node ) end |
#parse_query(index, relation) ⇒ Object
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/cql_ruby/cql_parser.rb', line 59 def parse_query( index, relation ) log "parse_query" term = parse_term( index, relation ) until @lexer.eof? or @lexer.token_type == ')' or @lexer.token_type == CqlLexer::TT_SORTBY if [CqlLexer::TT_AND,CqlLexer::TT_OR,CqlLexer::TT_NOT,CqlLexer::TT_PROX].include?( @lexer.token_type) token_type = @lexer.token_type value = @lexer.value match( token_type ) ms = gather_modifiers( value ) term2 = parse_term( index, relation ) term = case token_type when CqlLexer::TT_AND then CqlAndNode.new( term, term2, ms ) when CqlLexer::TT_OR then CqlOrNode.new( term, term2, ms ) when CqlLexer::TT_NOT then CqlNotNode.new( term, term2, ms ) when CqlLexer::TT_PROX then CqlProxNode.new( term, term2, ms ) end else raise CqlException, "parse exception: expect boolean, got: #{@lexer.render}" end end term end |
#parse_term(index, relation) ⇒ Object
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/cql_ruby/cql_parser.rb', line 105 def parse_term( index, relation ) log "parse_term" while true if @lexer.token_type == '(' log "parenthesised form" match( '(' ) expr = parse_query( index, relation ) match( ')' ) return expr elsif @lexer.token_type == '>' return parse_prefix( index, relation, false ) end log "non-parenthesized form" word = match_symbol( "index or term" ) break if not relation? and not @lexer.word? index = word relstr = @lexer.word? ? @lexer.value : @lexer.render( @lexer.token_type, false ) relation = CqlRelation.new( relstr ) match( @lexer.token_type ) ms = gather_modifiers( relstr ) relation.set_modifiers( ms ) log( "index='#{index}', relation='#{relation.to_cql}'") end # change backslashed double quotes in term to plain double-quotes # since the backslashes have served their purpose. word.gsub!('\\"', '"') node = CqlTermNode.new( index, relation, word ) log( "made term node #{node.to_cql}" ) node end |
#parse_top_level_prefixes(index, relation) ⇒ Object
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/cql_ruby/cql_parser.rb', line 32 def parse_top_level_prefixes( index, relation ) log "topl level prefix mapping" if @lexer.token_type == '>' return parse_prefix( index, relation, true ) end node = parse_query( index, relation ) if ( @compat == V1POINT2 || @compat == V1POINT1SORT ) && @lexer.token_type == CqlLexer::TT_SORTBY match( @lexer.token_type ) log "sortspec" sortnode = CqlSortNode.new( node ) until @lexer.eof? sortindex = match_symbol( "sort index" ) ms = gather_modifiers( sortindex ) sortnode.add_sort_index( ms ) end if sortnode.keys.empty? raise CqlException, "parse exception: no sort keys" end node = sortnode end node end |