Skip to content

Instantly share code, notes, and snippets.

@nrk
Created September 22, 2009 20:08
Show Gist options
  • Save nrk/191370 to your computer and use it in GitHub Desktop.
Save nrk/191370 to your computer and use it in GitHub Desktop.
#
# [{:op=>"and"},
# [{:op=>"="}, [{:path=>"hello"}, {:lit=>":ivan"}]],
# [{:op => "or"},
# [{:op=>"="}, [{:path=>"test"}, {:lit=>":ivan"}]],
# [{:op => ">"}, [:path => "test3", {:list => ":ivan"}]]]]
#
# hello = :ivan and (test = :ivan or test3 = :ivan)
class Parser
def initialize(where_clause, binding)
@binding = binding
@tokens = where_clause.scan(/\(|\)|>=|<=|<>|=|>|<|[:?\w\.\*]+/)
@stack = @top = @current_stack = []
@previous = nil
end
def ast
@tokens.each do |token|
p token
return nil unless token
case token
when "("
@current_stack << []
@previous = @current_stack
@previous_top = @top
@top = @current_stack = @current_stack.last
when ")"
@current_stack = @previous
@top = @previous_top
when "or", "and"
@top.unshift [{:op => token}, @current_stack, []]
when ">", "<", "<>", "=", ">=", "<="
first = @current_stack.pop
@current_stack.push(:op => token)
@current_stack << []
@previous = @current_stack
@current_stack = @current_stack.last
@current_stack.push first
when /:[\w\.\*]+/
@current_stack.push :lit => token
@current_stack = @previous
when /[\w\.\*]+/
@current_stack.push(:path => token)
end
end
#@stack.push(@current_stack)
#@current_stack = []
@stack
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment