Class: Antelope::DSL::Compiler

Inherits:
Object
  • Object
show all
Defined in:
lib/antelope/dsl/compiler.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(env = {}, &block) ⇒ Compiler

Returns a new instance of Compiler.



58
59
60
61
62
# File 'lib/antelope/dsl/compiler.rb', line 58

def initialize(env = {}, &block)
  @env = env
  @options = {}
  @block = block
end

Instance Attribute Details

#bodyString (readonly)

The body of the output compiler. This should be formatted in the language that the parser is to be written in. Some output generators may have special syntax that allows the parser to be put in the body; see the output generators for more.

For the DSL compiler, this is the :default template; if the :default template does not exist, the compilation will error.

Returns:

  • (String)


17
18
19
# File 'lib/antelope/dsl/compiler.rb', line 17

def body
  @body
end

#optionsHash (readonly)

Options defined by the file itself.

  • :terminals (Array<Symbol, String?)>) — A list of all of the terminals in the language. If this is not properly defined, the grammar will throw an error saying that a symbol used in the grammar is not defined.
  • :prec (Array<(Symbol, Array<Symbol>)>) — A list of the precedence rules of the grammar. The first element of each element is the type of precedence (and should be any of :left, :right, or :nonassoc), and the second element should be the symbols that are on that level.
  • :type (String) — The type of generator to generate; this should be a language.
  • :extra (Hash<Symbol, Array<Object>>) — Extra options that are not defined here.

Returns:

  • (Hash)


52
53
54
# File 'lib/antelope/dsl/compiler.rb', line 52

def options
  @options
end

#rulesArray<Hash> (readonly)

A list of all the rules that are defined in the file. The rules are defined as such:

  • label (Symbol) — The left-hand side of the rule; this is the nonterminal that the right side reduces to.
  • set (Array<Symbol>) — The right-hand side of the rule. This is a combination of terminals and nonterminals.
  • block (String) — The code to be run on a reduction. this should be formatted in the language that the output parser is written in. Optional; default value is "".
  • prec (String) — The precedence level for the rule. This should be a nonterminal or terminal. Optional; default value is "".

Returns:

  • (Array<Hash>)


34
35
36
# File 'lib/antelope/dsl/compiler.rb', line 34

def rules
  @rules
end

Class Method Details

.compile(env = {}, &block) ⇒ Object



54
55
56
# File 'lib/antelope/dsl/compiler.rb', line 54

def self.compile(env = {}, &block)
  new(env, &block).tap(&:compile)
end

Instance Method Details

#callObject



72
73
74
75
# File 'lib/antelope/dsl/compiler.rb', line 72

def call
  @context ||= Contexts::Main.new(options.fetch(:context, {}))
               .call(&@block)
end

#compileObject



64
65
66
67
68
69
70
# File 'lib/antelope/dsl/compiler.rb', line 64

def compile
  call
  handle_requirement
  handle_rules
  handle_options
  @body = @context[:templates].fetch(:default)
end

#handle_optionsObject (protected)



102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/antelope/dsl/compiler.rb', line 102

def handle_options
  @options[:prec]         = @context[:precedences]
  @options[:extra]        = @context[:defines]
  @options[:type]         = @env[:output]
  @options[:nonterminals] = []
  @options[:terminals]    = @context[:terminals].map do |name, value|
    if value.is_a?(TrueClass)
      [name.intern, nil, nil, nil]
    else
      [name.intern, nil, nil, value]
    end
  end
end

#handle_requirementObject (protected)



79
80
81
82
83
84
85
86
87
# File 'lib/antelope/dsl/compiler.rb', line 79

def handle_requirement
  required = @options.fetch(:require, ">= 0.0.0")
  antelope_version = Gem::Version.new(Antelope::VERSION)
  required_version = Gem::Requirement.new(required)

  raise IncompatibleVersionError, "Grammar requires " \
    "#{required}, have #{Antelope::VERSION}" unless
    required_version =~ antelope_version
end

#handle_rulesObject (protected)



89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/antelope/dsl/compiler.rb', line 89

def handle_rules
  @rules = []

  @context[:productions].each do |label, rules|
    rules.each do |rule|
      @rules << { label: label,
                  set: rule[:body].map { |x| [x, nil] },
                  block: rule[:action],
                  prec: rule[:prec] }
    end
  end
end