class Gamefic::Syntax


Syntax.new(‘search :container for :thing’, ‘look :thing :container’)
Syntax.new(‘look at :thing inside :container’, ‘look :thing :container’)
Syntax.new(‘examine :thing in :container’, ‘look :thing :container’)
form “look thing container”
@example All of these syntaxes will translate input into a command of the
`:thing`) to identify phrases that should be tokenized into arguments.
The template and command patterns use words beginning with a colon (e.g.,
variations in sentence structure.
Common uses are to provide synonyms for response verbs and allow for
Syntaxes provide rules for matching input patterns to existing responses.

def self.literal_or_nil(string)

Returns:
  • (Symbol, nil) -

Parameters:
  • string (String) --
def self.literal_or_nil(string)
  string.start_with?(':') ? nil : string.to_sym
end

def self.tokenize(text, syntaxes)

Returns:
  • (Array) - The tokenized expressions.

Parameters:
  • syntaxes (Array) -- The syntaxes to use.
  • text (String) -- The text to tokenize.
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

def ==(other)

def ==(other)
  signature == other&.signature
end

def accept?(text)

Returns:
  • (Boolean) -

Parameters:
  • text (String) --
def accept?(text)
  !!text.match(regexp)
end

def initialize(template, command)

Parameters:
  • command (String) --
  • template (String) --
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

def make_tokens

Returns:
  • (Array) -
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

def match_to_args(match)

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

def parse_replace

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

def regexp

Returns:
  • (Regexp) -
def regexp
  @regexp ||= Regexp.new("^#{make_tokens.join(' ')}$", Regexp::IGNORECASE)
end

def signature


Signatures are used to compare Syntaxes to each other.
Get a signature that identifies the form of the Syntax.
def signature
  [regexp, replace]
end

def synonym

Returns:
  • (Symbol) -
def synonym
  @synonym ||= Syntax.literal_or_nil(template.keywords.first)
end

def tokenize(text)

Returns:
  • (Expression, nil) -

Parameters:
  • text (String) --
def tokenize(text)
  match = text&.match(regexp)
  return nil unless match
  Expression.new(verb, match_to_args(match))
end