Class: Gamefic::Syntax

Inherits:
Object show all
Defined in:
lib/gamefic/syntax.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

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

#commandObject (readonly)

Returns the value of attribute command.



5
6
7
# File 'lib/gamefic/syntax.rb', line 5

def command
  @command
end

#first_wordObject (readonly)

Returns the value of attribute first_word.



5
6
7
# File 'lib/gamefic/syntax.rb', line 5

def first_word
  @first_word
end

#templateObject (readonly)

Returns the value of attribute template.



5
6
7
# File 'lib/gamefic/syntax.rb', line 5

def template
  @template
end

#token_countObject (readonly)

Returns the value of attribute token_count.



5
6
7
# File 'lib/gamefic/syntax.rb', line 5

def token_count
  @token_count
end

#verbObject (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

#signatureObject

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