Class: Gamefic::Syntax
- Inherits:
-
Object
- Object
- Gamefic::Syntax
- Defined in:
- lib/gamefic/syntax.rb
Overview
Syntaxes provide rules for matching input patterns to existing responses. Common uses are to provide synonyms for response verbs and allow for variations in sentence structure.
The template and command patterns use words beginning with a colon (e.g., ‘:thing`) to identify phrases that should be tokenized into arguments.
Constant Summary collapse
- PARAM_REGEXP =
/^:[a-z0-9_]+$/i.freeze
Instance Attribute Summary collapse
-
#command ⇒ String
readonly
The pattern that will be used to tokenize the input into a command.
- #params ⇒ Array<String> readonly
- #template ⇒ String readonly
-
#verb ⇒ Symbol
readonly
The response verb to which the command will be translated.
Class Method Summary collapse
- .literal_or_nil(string) ⇒ Symbol?
-
.split(template) ⇒ Array<String>
Split a syntax template by words and expressions.
-
.tokenize(text, syntaxes) ⇒ Array<Expression>
Tokenize an array of commands from the specified text.
Instance Method Summary collapse
- #==(other) ⇒ Object
-
#initialize(template, command) ⇒ Syntax
constructor
A new instance of Syntax.
-
#match?(text) ⇒ Boolean
(also: #accept?)
Determine if the specified text matches the syntax’s expected pattern.
- #regexp ⇒ Regexp
-
#signature ⇒ Object
Get a signature that identifies the form of the Syntax.
-
#synonym ⇒ Symbol
A symbol for the first word in the template.
-
#tokenize(text) ⇒ Expression?
Convert a String into a Command.
Constructor Details
#initialize(template, command) ⇒ Syntax
Returns a new instance of Syntax.
45 46 47 48 49 50 51 |
# File 'lib/gamefic/syntax.rb', line 45 def initialize(template, command) @template = template.normalize @params = @template.keywords.select { |word| word.start_with?(':') } @command = command.normalize @verb = Syntax.literal_or_nil(@command.keywords[0]) @replace = parse_replace end |
Instance Attribute Details
#command ⇒ String (readonly)
The pattern that will be used to tokenize the input into a command.
32 33 34 |
# File 'lib/gamefic/syntax.rb', line 32 def command @command end |
#params ⇒ Array<String> (readonly)
27 28 29 |
# File 'lib/gamefic/syntax.rb', line 27 def params @params end |
#template ⇒ String (readonly)
24 25 26 |
# File 'lib/gamefic/syntax.rb', line 24 def template @template end |
#verb ⇒ Symbol (readonly)
The response verb to which the command will be translated.
41 42 43 |
# File 'lib/gamefic/syntax.rb', line 41 def verb @verb end |
Class Method Details
.literal_or_nil(string) ⇒ Symbol?
118 119 120 |
# File 'lib/gamefic/syntax.rb', line 118 def self.literal_or_nil(string) string.start_with?(':') ? nil : string.to_sym end |
.split(template) ⇒ Array<String>
Split a syntax template by words and expressions.
126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/gamefic/syntax.rb', line 126 def self.split(template) parens = 0 result = template.normalize.chars.each.with_object(['']) do |char, result| parens = parse_token(char, parens, result) end raise "Unbalanced parentheses in syntax '#{template}'" unless parens.zero? result.pop if result.last.empty? result end |
.tokenize(text, syntaxes) ⇒ Array<Expression>
Tokenize an array of commands from the specified text. The resulting array is in descending order of precision, i.e., most to least matched tokens.
108 109 110 111 112 113 114 |
# File 'lib/gamefic/syntax.rb', line 108 def self.tokenize(text, syntaxes) syntaxes .map { |syn| syn.tokenize(text) } .compact .uniq { |exp| [exp.verb, exp.tokens] } .sort_by { |exp| [-exp.tokens.compact.length] } end |
Instance Method Details
#==(other) ⇒ Object
97 98 99 |
# File 'lib/gamefic/syntax.rb', line 97 def ==(other) signature == other&.signature end |
#match?(text) ⇒ Boolean Also known as: accept?
Determine if the specified text matches the syntax’s expected pattern.
85 86 87 |
# File 'lib/gamefic/syntax.rb', line 85 def match?(text) !!text.match(regexp) end |
#regexp ⇒ Regexp
66 67 68 |
# File 'lib/gamefic/syntax.rb', line 66 def regexp @regexp ||= Regexp.new("^#{make_tokens.join(' ')}$", Regexp::IGNORECASE) end |
#signature ⇒ Object
Get a signature that identifies the form of the Syntax. Signatures are used to compare Syntaxes to each other.
93 94 95 |
# File 'lib/gamefic/syntax.rb', line 93 def signature [regexp, replace] end |
#synonym ⇒ Symbol
A symbol for the first word in the template. Used by rulebooks to classify groups of related syntaxes.
61 62 63 |
# File 'lib/gamefic/syntax.rb', line 61 def synonym @synonym ||= Syntax.literal_or_nil(template.keywords.first) end |
#tokenize(text) ⇒ Expression?
Convert a String into a Command.
74 75 76 77 78 79 |
# File 'lib/gamefic/syntax.rb', line 74 def tokenize(text) match = text&.match(regexp) return nil unless match Expression.new(verb, match_to_args(match)) end |