Class: Gamefic::Syntax
Instance Attribute Summary collapse
-
#command ⇒ Object
readonly
Returns the value of attribute command.
-
#first_word ⇒ Object
readonly
Returns the value of attribute first_word.
-
#template ⇒ Object
readonly
Returns the value of attribute template.
-
#token_count ⇒ Object
readonly
Returns the value of attribute token_count.
-
#verb ⇒ Object
readonly
Returns the value of attribute verb.
Class Method Summary collapse
-
.tokenize(text, syntaxes) ⇒ Array<Gamefic::Command>
Tokenize an Array of Commands from the specified text.
Instance Method Summary collapse
- #==(other) ⇒ Object
-
#accept?(text) ⇒ Boolean
Determine if the specified text matches the syntax’s expected pattern.
-
#initialize(template, command) ⇒ Syntax
constructor
A new instance of Syntax.
-
#signature ⇒ Object
Get a signature that identifies the form of the Syntax.
-
#tokenize(text) ⇒ Gamefic::Command
Convert a String into a Command.
Constructor Details
#initialize(template, command) ⇒ Syntax
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/gamefic/syntax.rb', line 7 def initialize template, command words = template.split_words @token_count = words.length command_words = command.split_words @verb = nil if words[0][0] == ':' @token_count -= 1 @first_word = '' else @first_word = words[0].to_s @verb = command_words[0].to_sym end @command = command_words.join(' ') @template = words.join(' ') tokens = [] variable_tokens = [] last_token_is_reg = false words.each { |w| if w.match(/^:[a-z0-9_]+$/i) variable_tokens.push w if last_token_is_reg next else tokens.push '([\w\W\s\S]*?)' last_token_is_reg = true end else tokens.push w last_token_is_reg = false end } subs = [] index = 0 command_words.each { |t| if t[0] == ':' index = variable_tokens.index(t) + 1 subs.push "{$#{index}}" else subs.push t end } @replace = subs.join(' ') @regexp = Regexp.new("^#{tokens.join(' ')}$", Regexp::IGNORECASE) end |
Instance Attribute Details
#command ⇒ Object (readonly)
Returns the value of attribute command.
5 6 7 |
# File 'lib/gamefic/syntax.rb', line 5 def command @command end |
#first_word ⇒ Object (readonly)
Returns the value of attribute first_word.
5 6 7 |
# File 'lib/gamefic/syntax.rb', line 5 def first_word @first_word end |
#template ⇒ Object (readonly)
Returns the value of attribute template.
5 6 7 |
# File 'lib/gamefic/syntax.rb', line 5 def template @template end |
#token_count ⇒ Object (readonly)
Returns the value of attribute token_count.
5 6 7 |
# File 'lib/gamefic/syntax.rb', line 5 def token_count @token_count end |
#verb ⇒ Object (readonly)
Returns the value of attribute verb.
5 6 7 |
# File 'lib/gamefic/syntax.rb', line 5 def verb @verb end |
Class Method Details
.tokenize(text, syntaxes) ⇒ Array<Gamefic::Command>
Tokenize an Array of Commands from the specified text.
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/gamefic/syntax.rb', line 98 def self.tokenize text, syntaxes matches = [] syntaxes.each { |syntax| result = syntax.tokenize text matches.push(result) if !result.nil? } matches.sort! { |a,b| if a.arguments.length == b.arguments.length b.verb.to_s <=> a.verb.to_s else b.arguments.length <=> a.arguments.length end } matches end |
Instance Method Details
#==(other) ⇒ Object
88 89 90 91 |
# File 'lib/gamefic/syntax.rb', line 88 def ==(other) return false unless other.is_a?(Syntax) signature == other.signature end |
#accept?(text) ⇒ Boolean
Determine if the specified text matches the syntax’s expected pattern.
77 78 79 |
# File 'lib/gamefic/syntax.rb', line 77 def accept? text !text.match(@regexp).nil? end |
#signature ⇒ Object
Get a signature that identifies the form of the Syntax. Signatures are used to compare Syntaxes to each other.
84 85 86 |
# File 'lib/gamefic/syntax.rb', line 84 def signature [@regexp, @replace] end |
#tokenize(text) ⇒ Gamefic::Command
Convert a String into a Command.
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/gamefic/syntax.rb', line 56 def tokenize text m = text.match(@regexp) return nil if m.nil? arguments = [] # HACK: Skip the first word if the verb is not nil. # This is ugly. b = @verb.nil? ? 0 : 1 @replace.to_s.split_words[b..-1].each { |r| if r.match(/^\{\$[0-9]+\}$/) arguments.push m[r[2..-2].to_i] else arguments.push r end } Command.new @verb, arguments end |