Class: Aspen::CustomGrammar::Compiler
- Inherits:
-
Object
- Object
- Aspen::CustomGrammar::Compiler
- Defined in:
- lib/aspen/custom_grammar/compiler.rb
Instance Attribute Summary collapse
-
#environment ⇒ Object
readonly
Returns the value of attribute environment.
-
#root ⇒ Object
readonly
Returns the value of attribute root.
Class Method Summary collapse
Instance Method Summary collapse
- #compile ⇒ Object
-
#initialize(root, environment = {}) ⇒ Compiler
constructor
A new instance of Compiler.
- #render ⇒ Object
- #visit(node) ⇒ Object
- #visit_bare(node) ⇒ Object
- #visit_capturesegment(node) ⇒ Object
- #visit_content(node) ⇒ Object
- #visit_expression(node) ⇒ Object
Constructor Details
Instance Attribute Details
#environment ⇒ Object (readonly)
Returns the value of attribute environment.
5 6 7 |
# File 'lib/aspen/custom_grammar/compiler.rb', line 5 def environment @environment end |
#root ⇒ Object (readonly)
Returns the value of attribute root.
5 6 7 |
# File 'lib/aspen/custom_grammar/compiler.rb', line 5 def root @root end |
Class Method Details
Instance Method Details
#compile ⇒ Object
22 23 24 25 26 27 28 29 30 31 |
# File 'lib/aspen/custom_grammar/compiler.rb', line 22 def compile # Call #render before accessing the registry. If this code # changes, we may need more process control to ensure #render # goes first. { pattern: render, type_registry: @type_registry, label_registry: @label_registry } end |
#render ⇒ Object
33 34 35 |
# File 'lib/aspen/custom_grammar/compiler.rb', line 33 def render visit(root) end |
#visit(node) ⇒ Object
37 38 39 40 41 42 43 |
# File 'lib/aspen/custom_grammar/compiler.rb', line 37 def visit(node) short_name = node.class.to_s.split('::').last.downcase method_name = "visit_#{short_name}" # puts "---- #{method_name}" # puts node.inspect send(method_name, node) end |
#visit_bare(node) ⇒ Object
70 71 72 |
# File 'lib/aspen/custom_grammar/compiler.rb', line 70 def (node) visit(node.content) end |
#visit_capturesegment(node) ⇒ Object
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/aspen/custom_grammar/compiler.rb', line 53 def visit_capturesegment(node) value = case node.type when :integer then /(?<#{node.var_name}>[\d,]+\d*)/ # No decimal when :float then /(?<#{node.var_name}>[\d,]+\.\d+)/ # Decimal point required when :numeric then /(?<#{node.var_name}>[\d,]+\.?\d*)/ # Optional decimal when :string then /(?<#{node.var_name}>.*?)/ when :node then /(?<#{node.var_name}>.*?)/ else raise ArgumentError, "No regexp pattern for type \"#{node.type}\"." end # Add type to type registry @type_registry[node.var_name] = node.type # Add label to label registry @label_registry[node.var_name] = node.label if node.type == :node return value end |
#visit_content(node) ⇒ Object
74 75 76 |
# File 'lib/aspen/custom_grammar/compiler.rb', line 74 def visit_content(node) node.content end |
#visit_expression(node) ⇒ Object
45 46 47 48 49 50 51 |
# File 'lib/aspen/custom_grammar/compiler.rb', line 45 def visit_expression(node) segments = node.segments.map { |segment| visit(segment) } segments.last.gsub!(/\.$/, '') # Make the last period optional? Maybe? segments.unshift "^" # Add a bol matcher to the front. segments.push "\\.?$" # Make the last period optional? Again? Regexp.new(segments.join) end |