Class: Antelope::Generator::Base Abstract

Inherits:
Object
  • Object
show all
Defined in:
lib/antelope/generator/base.rb

Overview

This class is abstract.

Subclass and redefine #generate to create a generator.

Generates a parser. This is normally the parent class, and the specific implementations inherit from this. The generated parser should, ideally, be completely independent (not requiring any external source code), as well as be under a permissive license.

Direct Known Subclasses

Group, Null, Output, Ruby

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(grammar, mods) ⇒ Base

Initialize the generator.

Parameters:

  • grammar (Grammar)
  • mods (Hash<(Symbol, Object)>)


44
45
46
47
48
# File 'lib/antelope/generator/base.rb', line 44

def initialize(grammar, mods)
  @file    = grammar.name
  @grammar = grammar
  @mods    = mods
end

Instance Attribute Details

#fileString (readonly)

The file name (not including the extension) that the grammar should output to.

Returns:

  • (String)


22
23
24
# File 'lib/antelope/generator/base.rb', line 22

def file
  @file
end

#grammarAce::Grammar (readonly)

The grammar that the generator is for.

Returns:



27
28
29
# File 'lib/antelope/generator/base.rb', line 27

def grammar
  @grammar
end

#modsHash<(Symbol, Object)> (readonly)

The modifiers that were applied to the grammar.

Returns:

  • (Hash<(Symbol, Object)>)


16
17
18
# File 'lib/antelope/generator/base.rb', line 16

def mods
  @mods
end

Class Method Details

.register_as(*names) ⇒ Object



36
37
38
# File 'lib/antelope/generator/base.rb', line 36

def self.register_as(*names)
  Generator.register_generator(self, *names)
end

.source_rootPathname

The source root directory for templates. Overwrite to change.

Returns:

  • (Pathname)


32
33
34
# File 'lib/antelope/generator/base.rb', line 32

def self.source_root
  Pathname.new("../templates").expand_path(__FILE__)
end

Instance Method Details

#generatevoid

This method returns an undefined value.

Actually does the generation. A subclass should implement this.

Raises:

  • (NotImplementedError)


54
55
56
# File 'lib/antelope/generator/base.rb', line 54

def generate
  raise NotImplementedError
end

#productionsArray<Array<(Ace::Token::Nonterminal, Numeric, String)>] (protected)

Returns an array of the production information of each production needed by the parser. The first element of any element in the array is an Ace::Token::Nonterminal that that specific production reduces to; the second element is a number describing the number of items in the right hand side of the production; the string represents the action that should be taken on reduction.

This information is used for :reduce actions in the parser; the value of the :reduce action corresponds to the array index of the production in this array.

Returns:



118
119
120
121
122
123
124
# File 'lib/antelope/generator/base.rb', line 118

def productions
  grammar.all_productions.map do |production|
    [production[:label],
     production[:items].size,
     production[:block]]
  end
end

#tableArray<Hash<Symbol => Array<(Symbol, Numeric)>>> (protected)

The actual table that is used for parsing. This returns an array of hashes; the array index corresponds to the state number, and the hash keys correspond to the lookahead tokens. The hash values are an array; the first element of that array is the action to be taken, and the second element of the array is the argument for that action. Possible actions include :accept, :reduce, and :state; :accept means to accept the string; :reduce means to perform the given reduction; and :state means to transition to the given state.

Returns:

  • (Array<Hash<Symbol => Array<(Symbol, Numeric)>>>)


101
102
103
# File 'lib/antelope/generator/base.rb', line 101

def table
  mods[:tableizer].table
end

#template(source, destination) {|content| ... } ⇒ void (protected)

This method returns an undefined value.

Copies a template from the source, runs it through erb (in the context of this class), and then outputs it at the destination. If given a block, it will call the block after the template is run through erb with the content from erb; the result of the block is then used as the content instead.

Parameters:

  • source (String)

    the source file. This should be in source_root.

  • destination (String)

    the destination file. This will be in Ace::Grammar#output.

Yield Parameters:

  • content (String)

    The content that ERB created.

Yield Returns:

  • (String)

    The new content to write to the output.



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/antelope/generator/base.rb', line 73

def template(source, destination)
  src_file  = Pathname.new(source)
    .expand_path(self.class.source_root)
  src       = src_file.open("r")
  context   = instance_eval('binding')
  erb       = ERB.new(src.read, nil, "%")
  erb.filename = source
  content   = erb.result(context)
  content   = yield content if block_given?
  dest_file = Pathname.new(destination)
    .expand_path(grammar.output)
  dest_file.open("w") do |f|
    f.write(content)
  end
end