Skip to content

Instantly share code, notes, and snippets.

@billdueber
Created November 18, 2011 05:26
Show Gist options
  • Save billdueber/1375681 to your computer and use it in GitHub Desktop.
Save billdueber/1375681 to your computer and use it in GitHub Desktop.
Simple term parser
require 'parslet'
require 'pp'
class AdvParser < Parslet::Parser
rule(:space) { match['\\s\\t'].repeat(1) } # at least one space/tab
rule(:space?) { space.maybe } # zero or 1 things that match the 'space' rule
rule(:startexpr) { str('(') >> space? } # '(' followed by optional space
rule(:endexpr) { space? >> str(')') }
# A phrase is anything (but a double-quote) between double-quotes
rule(:phrase) { str('"') >> match['^"'].repeat(1).as(:phrase) >> str('"') }
rule(:opand) { str('AND') }
rule(:opor) { str('OR') }
rule(:opnot) { str('NOT') }
rule(:op) { opand | opor | opnot }
rule(:fname) { str('TI') | str('AU') | str('KY') }
rule(:field) { fname.as(:field) >> str(':') }
rule(:word) { match['^\\s\\t"()'].repeat(1) }
rule(:searchword) { field.absent? >> op.absent? >> word }
rule(:searchwords) { (space? >> searchword).repeat(1) }
rule(:term) { phrase | searchwords.as(:words) }
rule(:terms) { (space? >> term).repeat(1) }
rule(:fsearch) { field >> space? >> terms.as(:search) }
root(:fsearch)
end
pp AdvParser.new.parse('TI: hello there "Bill Dueber" how are you?')
# puts AdvParser.new.parse('TI: bill AND dueber')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment