Skip to content

Instantly share code, notes, and snippets.

@sleepingkingstudios
Created September 11, 2017 06:47
Show Gist options
  • Save sleepingkingstudios/7097315999a0631ea49c6cc7ae375e9e to your computer and use it in GitHub Desktop.
Save sleepingkingstudios/7097315999a0631ea49c6cc7ae375e9e to your computer and use it in GitHub Desktop.
class CommandParser
class OptionsParser
def initialize
@parsed = nil
@buffer = nil
@bname = nil
end # constructor
def parse tokens
self.buffer = ''
self.bname = :objects
self.parsed = {}
tokens.each do |token|
process_token token
end # each
flush_buffer
parsed
end # method parse
protected
attr_accessor :bname, :buffer, :parsed
private
def flush_buffer
return if buffer.empty?
(parsed[bname] ||= []) << buffer.rstrip
self.buffer = ''
end # method flush_buffer
def process_modifier_token
flush_buffer
self.bname = :modifiers
end # method process_modifier_token
def process_target_token
flush_buffer
self.bname = :targets
end # method process_target_token
def process_token token
case token
when 'and'
flush_buffer
when 'at', 'on', 'to'
process_target_token
when 'using', 'with'
process_modifier_token
else
buffer << token << ' '
end # case
end # method process_token
end # class
def initialize commands
@commands = commands.sort { |u, v| v <=> u }
end # constructor
def parse input
return nil unless input.is_a?(String) && !input.empty?
command, remainder = parse_command input
return nil unless command
options = parse_options remainder
{ :command => command }.merge options
end # method parse
private
def flush parsed, buffer, bname
return if buffer.empty?
(parsed[bname] ||= []) << buffer.rstrip.dup
buffer.clear
end # method flush
def parse_options options
tokens = options.split(' ')
OptionsParser.new.parse(tokens)
end # method parse_options
def parse_command input
match = input.downcase
@commands.each do |command|
next unless match.start_with?(command)
remainder = input[command.length..-1].strip
return [command, remainder]
end # each
nil
end # method parse_command
def tokenize input
input.strip.split(/\s+/)
end # method tokenize
end # class
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment