Created
January 24, 2016 17:31
-
-
Save diiq/10ac884e49ae6aacf843 to your computer and use it in GitHub Desktop.
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
require "rsec" | |
module Parsing | |
extend Rsec::Helpers | |
# build the parser | |
def self.query_lang | |
# Predicate should be constructed with loop over keywords | |
predicate = /.*?(?=STATUS IS|TYPE IS|AND|OR|\(|\)|$)/.r.map { |s| s.strip } | |
# write a helper method to add new statement types | |
status_statement = (symbol('STATUS IS') >> predicate).map { |s| {status: s} } | |
type_statement = (symbol('TYPE IS') >> predicate).map { |s| {type: s} } | |
# statement should loop over all statement types | |
statement = status_statement | type_statement | |
# Once this part is settled, it shouldn't need to change. Hardest | |
# part: building a query for TASK THING OR (TASK THING AND TASK | |
# THING) | |
parenthetical = ('('.r >> lazy { expr } << ')') | |
unit = statement | parenthetical | |
and_ = symbol('AND').map { {} } # cheating, won't work forever | |
anded = unit.join(and_).map { |s| s.reduce(&:merge) } | |
expr = anded.join(symbol('OR')) | |
expr.eof | |
end | |
def self.parse str | |
query_lang.parse! str | |
end | |
end | |
p Parsing::parse 'STATUS IS hi' | |
p Parsing::parse 'STATUS IS hi AND TYPE IS good bye' | |
p Parsing::parse 'STATUS IS sweet OR (TYPE IS sweet AND STATUS IS super sweet)' | |
p Parsing::parse 'STATUS IS sweet OR ((STATUS IS super sweet AND TYPE IS rockin) OR TYPE IS sweet)' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment