Created
September 11, 2017 06:47
-
-
Save sleepingkingstudios/7097315999a0631ea49c6cc7ae375e9e 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
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