Module: Antelope::Ace::Grammar::Productions
- Included in:
- Antelope::Ace::Grammar
- Defined in:
- lib/antelope/ace/grammar/productions.rb
Overview
Manages the productions of the grammar.
Instance Method Summary collapse
-
#all_productions ⇒ Array<Production>
Returns all productions for all nonterminals, sorted by id.
-
#default_production ⇒ Production
private
Creates the default production for the grammar.
-
#find_token(value) ⇒ Token
private
Finds a token based on its corresponding symbol.
-
#generate_production_for(rule, id) ⇒ Production
private
Generates a production for a given compiler rule.
-
#generate_productions ⇒ Hash<(Symbol, Array<Production>)>
private
Actually generates the productions.
-
#productions ⇒ Hash<(Symbol, Array<Production>)>
Returns a hash of all of the productions.
Instance Method Details
#all_productions ⇒ Array<Production>
Returns all productions for all nonterminals, sorted by id.
19 20 21 |
# File 'lib/antelope/ace/grammar/productions.rb', line 19 def all_productions productions.values.flatten.sort_by(&:id) end |
#default_production ⇒ Production (private)
Creates the default production for the grammar. The left
hand side of the production is the :$start symbol, with
the right hand side being the first rule's left-hand side
and the terminal $. This production is automagically
given the last precedence, and an id of 0.
83 84 85 86 87 88 |
# File 'lib/antelope/ace/grammar/productions.rb', line 83 def default_production Production.new(Token::Nonterminal.new(:$start), [ Token::Nonterminal.new(@compiler.rules.first[:label]), Token::Terminal.new(:"$") ], "", precedence.last, 0) end |
#find_token(value) ⇒ Token (private)
Finds a token based on its corresponding symbol. First
checks the productions, to see if it's a nonterminal; then,
tries to find it in the terminals; otherwise, if the symbol
is error, it returns a Token::Error; if the symbol is
nothing or ε, it returns a Token::Epsilon; if it's
none of those, it raises an UndefinedTokenError.
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/antelope/ace/grammar/productions.rb', line 101 def find_token(value) value = value.intern if productions.key?(value) Token::Nonterminal.new(value) elsif terminal = terminals. find { |term| term.name == value } terminal elsif value == :error Token::Error.new elsif [:nothing, : |
#generate_production_for(rule, id) ⇒ Production (private)
Generates a production for a given compiler rule. Converts the tokens in the set to their Token counterparts, and then sets the precedence for the production. If the precedence declaration from the compiler rule is empty, then it'll use the last terminal from the set to check for precedence; otherwise, it'll use the precedence declaration. This is to make sure that every production has a precedence declaration.
61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/antelope/ace/grammar/productions.rb', line 61 def generate_production_for(rule, id) left = rule[:label] items = rule[:set].map { |_| find_token(_) } prec = if rule[:prec].empty? items.select(&:terminal?).last else find_token(rule[:prec]) end prec = precedence_for(prec) Production.new(Token::Nonterminal.new(left), items, rule[:block], prec, id + 1) end |
#generate_productions ⇒ Hash<(Symbol, Array<Production>)> (private)
Actually generates the productions. Uses the rules from the compiler to construct the productions. Makes two loops over the compiler's rules; the first to tell the grammar that the nonterminal does exist, and the second to actually construct the productions. The first loop is for #find_token, because otherwise it wouldn't be able to return a nonterminal properly.
34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/antelope/ace/grammar/productions.rb', line 34 def generate_productions @_productions = {} @compiler.rules.each do |rule| productions[rule[:label]] = [] end.each_with_index do |rule, id| productions[rule[:label]] << generate_production_for(rule, id) end productions[:$start] = [default_production] productions end |
#productions ⇒ Hash<(Symbol, Array<Production>)>
Returns a hash of all of the productions. The result is cached.
12 13 14 |
# File 'lib/antelope/ace/grammar/productions.rb', line 12 def productions @_productions || generate_productions end |