class Stockade::Parser

Parser

Takes a raw list (a set really) of lexemes returned by Lexer and further processes them. Currently this means:

  1. Deduping - >1 ambiguous lexemes matching exactly same fragment are deduped according to their priority. Only the highest priority lexeme kept.

  2. Removing covered lexems - lexeme that matches a string that is a

substring of another matched string is removed.

Attributes

lexemes[R]

Public Class Methods

call(lexemes) click to toggle source
# File lib/stockade/parser.rb, line 23
def self.call(lexemes)
  new(lexemes).call
end
new(lexemes) click to toggle source
# File lib/stockade/parser.rb, line 19
def initialize(lexemes)
  @lexemes = lexemes
end

Public Instance Methods

call() click to toggle source
# File lib/stockade/parser.rb, line 27
def call
  non_covered_lexemes
end

Private Instance Methods

covers?(head, lex) click to toggle source
# File lib/stockade/parser.rb, line 71
def covers?(head, lex)
  head != lex &&
    head.start_pos <= lex.start_pos &&
    head.end_pos >= lex.end_pos
end
deduped() click to toggle source
# File lib/stockade/parser.rb, line 38
def deduped
  grouped.map do |group|
    if group.size == 1
      group.first
    else
      group.max_by do |lexeme|
        priority(lexeme)
      end
    end
  end
end
grouped() click to toggle source
# File lib/stockade/parser.rb, line 33
def grouped
  lexemes.group_by(&:range).values
end
non_covered_lexemes() click to toggle source
# File lib/stockade/parser.rb, line 56
def non_covered_lexemes
  res = deduped.dup

  res.each_index do |index|
    head, *rest = *res[index..-1]

    rest.each do |lex|
      next unless covers?(head, lex)
      res.delete(lex)
    end
  end.to_a

  res
end
ordered() click to toggle source
# File lib/stockade/parser.rb, line 51
def ordered
  lexemes.sort_by(&:start_pos)
end
priority(lexeme) click to toggle source
# File lib/stockade/parser.rb, line 77
def priority(lexeme)
  if [Lexemes::Firstname, Lexemes::Lastname].include?(lexeme.class)
    lexeme.capitalized? ? 3 : 1
  elsif lexeme.is_a?(Lexemes::Word)
    2
  else
    3
  end
end