Class: RText::Instantiator

Inherits:
Object
  • Object
show all
Includes:
Tokenizer
Defined in:
lib/rtext/instantiator.rb

Defined Under Namespace

Classes: InstantiatorProblem

Instance Method Summary collapse

Methods included from Tokenizer

#tokenize

Constructor Details

#initialize(language) ⇒ Instantiator

Creates an instantiator for RText::Language language



17
18
19
# File 'lib/rtext/instantiator.rb', line 17

def initialize(language)
  @lang = language
end

Instance Method Details

#instantiate(str, options = {}) ⇒ Object

instantiate str, options include:

:env
  environment to which model elements will be added

:problems
  an array to which problems will be appended

:unresolved_refs
  an array to which unresolved references will be appended

:root_elements
  an array which will hold the root elements

:file_name
  name of the file being instantiated, will be set on model elements

:fragment_ref
  object which references the fragment being instantiated, will be set on model elements 

:on_progress
  a proc which is called with a number measuring the progress made since the last call;
  progress is measured by the number of command tokens recognized plus the number of
  model elements instantiated.


46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/rtext/instantiator.rb', line 46

def instantiate(str, options={})
  @line_numbers = {}
  @env = options[:env]
  @problems = options[:problems] || []
  @unresolved_refs = options[:unresolved_refs]
  @root_elements = options[:root_elements] || []
  @file_name = options[:file_name]
  @fragment_ref = options[:fragment_ref]
  @on_progress_proc = options[:on_progress]
  @context_class_stack = []
  parser = Parser.new
  @root_elements.clear
  parser_problems = []
  tokens = tokenize(str, @lang.reference_regexp, 
    :on_command_token => @on_progress_proc && lambda do
      @on_progress_proc.call(1)
    end)
  parser.parse(tokens, 
    :descent_visitor => lambda do |command|
      clazz = @lang.class_by_command(command.value, @context_class_stack.last)
      # in case no class is found, nil will be pushed, this will case the next command
      # lookup to act as if called from toplevel
      @context_class_stack.push(clazz)
    end,
    :ascent_visitor => lambda do |*args|
      if args[0]
        element =create_element(*args)
        @context_class_stack.pop
        element
      else
        unassociated_comments(args[3])
      end
    end,
    :problems => parser_problems)
  parser_problems.each do |p|
    problem(p.message, p.line)
  end
end