class Talk::Parser

Attributes

basepath[RW]

Public Class Methods

error(tag, file, line, message) click to toggle source
# File lib/parser.rb, line 12
def self.error(tag, file, line, message)
  near_msg = tag.nil? ? "" : " near @#{tag}"
  raise ParseError, "#{file}:#{line}  parse error#{near_msg}: #{message}"
end
new() click to toggle source
# File lib/parser.rb, line 17
def initialize
  @contexts = [ Context.context_for_name(:base).new("base", "n/a", "0") ]
  @base = @contexts.first
  @finalized = false
  @closed_contexts = []
end

Public Instance Methods

close_active_context() click to toggle source
# File lib/parser.rb, line 98
def close_active_context
  @closed_contexts.push @contexts.pop
  @contexts.last.end_tag(@closed_contexts.last) unless @contexts.empty?
end
finalize() click to toggle source

signal that we are done parsing files, and it is time to do final validation

# File lib/parser.rb, line 25
def finalize
  close_active_context until @contexts.empty?
  @closed_contexts.each { |ctx| ctx.finalize }
  finalized = true
end
identifier_from_tag_word(word) click to toggle source
# File lib/parser.rb, line 107
def identifier_from_tag_word(word)
  word[1..-1].to_sym
end
line_is_comment?(line) click to toggle source
# File lib/parser.rb, line 111
def line_is_comment?(line)
  line.length > 0 and line[0].length > 0 and line[0][0] == '#'
end
parse(filename, contents) click to toggle source
# File lib/parser.rb, line 49
def parse(filename, contents)
  contents = contents.split("\n") unless contents.is_a? Array
  contents.each_with_index { |line, line_num| parse_line(line.strip.split, filename, line_num+1) }
end
parse_error(message) click to toggle source
# File lib/parser.rb, line 115
def parse_error(message)
  raise Talk::Parser.error(@tag, @file, @line, message)
end
parse_file(filename) click to toggle source
# File lib/parser.rb, line 45
def parse_file(filename)
  parse(filename, IO.read(filename))
end
parse_line(words, file, line) click to toggle source
# File lib/parser.rb, line 54
def parse_line(words, file, line)
  return if line_is_comment?(words)

  @file = trim_filename(file)
  @line = line
  words.each { |word| parse_word(word) }
end
parse_supported_tag() click to toggle source
# File lib/parser.rb, line 77
def parse_supported_tag
  new_context = @contexts.last.start_tag(@tag, @file, @line)
  if new_context.nil? then
    close_active_context
  else
    @contexts.push new_context
    @closed_contexts.push new_context
  end
end
parse_tag(tag) click to toggle source
# File lib/parser.rb, line 72
def parse_tag(tag)
  @tag = tag
  @contexts.last.has_tag?(tag) ? parse_supported_tag : parse_unsupported_tag
end
parse_unsupported_tag() click to toggle source
# File lib/parser.rb, line 87
def parse_unsupported_tag
  stack = Array.new(@contexts)
  stack.pop until stack.empty? or stack.last.has_tag? @tag

  parse_error("tag not supported in @#{@contexts.last.tag.to_s}") if stack.empty?

  close_active_context until @contexts.last == stack.last

  parse_supported_tag
end
parse_word(word) click to toggle source
# File lib/parser.rb, line 62
def parse_word(word)
  @word = word

  if word_is_tag?(word) then
    parse_tag(identifier_from_tag_word(word))
  else
    @contexts.last.parse(word, @file, @line)
  end
end
results() click to toggle source
# File lib/parser.rb, line 31
def results
  finalize unless @finalized
  @base.to_h
end
trim_filename(filename) click to toggle source
# File lib/parser.rb, line 36
def trim_filename(filename)
  if @basepath.nil? == false and filename.start_with? @basepath then
    filename = filename[@basepath.length .. -1]
    filename = filename[1..-1] while filename.start_with? "/"
  end

  filename
end
word_is_tag?(word) click to toggle source
# File lib/parser.rb, line 103
def word_is_tag?(word)
  word[0] == '@'
end