class Gamefic::Syntax
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.
@example All of these syntaxes will translate input into a command of the
form "look thing container" Syntax.new('examine :thing in :container', 'look :thing :container') Syntax.new('look at :thing inside :container', 'look :thing :container') Syntax.new('search :container for :thing', 'look :thing :container')
Constants
- PARAM_REGEXP
Attributes
The pattern that will be used to tokenize the input into a command.
@return [String]
@return [Array<String>]
@return [String]
@return [String]
The response verb to which the command will be translated.
@example
syntax = Syntax.new('examine :thing', 'look :thing') syntax.verb #=> :look
@return [Symbol]
Public Class Methods
Source
# File lib/gamefic/syntax.rb, line 117 def self.literal_or_nil(string) string.start_with?(':') ? nil : string.to_sym end
@param string [String] @return [Symbol, nil]
Source
# 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
@param template [String] @param command [String]
Source
# File lib/gamefic/syntax.rb, line 107 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
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.
@param text [String] The text to tokenize. @param syntaxes [Array<Syntax>] The syntaxes to use. @return [Array<Expression>] The tokenized expressions.
Public Instance Methods
Source
# File lib/gamefic/syntax.rb, line 96 def ==(other) signature == other&.signature end
Source
# File lib/gamefic/syntax.rb, line 85 def accept?(text) !!text.match(regexp) end
Determine if the specified text matches the syntax’s expected pattern.
@param text [String] @return [Boolean]
Source
# File lib/gamefic/syntax.rb, line 66 def regexp @regexp ||= Regexp.new("^#{make_tokens.join(' ')}$", Regexp::IGNORECASE) end
@return [Regexp]
Source
# File lib/gamefic/syntax.rb, line 92 def signature [regexp, replace] end
Get a signature that identifies the form of the Syntax
. Signatures are used to compare Syntaxes to each other.
Source
# File lib/gamefic/syntax.rb, line 61 def synonym @synonym ||= Syntax.literal_or_nil(template.keywords.first) end
A symbol for the first word in the template. Used by rulebooks to classify groups of related syntaxes.
@example
syntax = Syntax.new('examine :thing', 'look :thing') syntax.synonym #=> :examine
@return [Symbol]
Source
Private Instance Methods
Source
# File lib/gamefic/syntax.rb, line 144 def make_tokens template.keywords.map.with_index do |word, idx| next word unless word.match?(PARAM_REGEXP) next nil if idx.positive? && template.keywords[idx - 1].match?(PARAM_REGEXP) '([\w\W\s\S]*?)' end.compact end
@return [Array<String>]
Source
# File lib/gamefic/syntax.rb, line 136 def match_to_args(match) start = replace.start_with?('{') ? 0 : 1 replace.keywords[start..].map do |str| str.match?(/^\{\$[0-9]+\}$/) ? match[str[2..-2].to_i] : str end end
Source
# File lib/gamefic/syntax.rb, line 126 def parse_replace command.keywords.map do |word| next word unless word.start_with?(':') index = params.index(word) || raise(ArgumentError, "syntax command references undefined parameter `#{word}`") "{$#{index + 1}}" end.join(' ') end