Object
Abstract base class for grammar specifications.
The following is a grammar specification for simple arithmetic. Precedences are specified as in Yacc - in ascending order of binding strength, with equal-strength symbols on the same level. Production rules are specified for each symbol by specifying the name of the production (used when encoding the Evaluator) and the expansion for that particular production. For example, the production named addition expands the symbol 'E' to the list of symbols ['E', '+', 'E'].
class ArithmeticPrecedenceGrammar < Dhaka::Grammar
precedences do
left ['+', '-']
left ['*', '/']
nonassoc ['^']
end
for_symbol(Dhaka::START_SYMBOL_NAME) do
expression ['E']
end
for_symbol('E') do
addition ['E', '+', 'E']
subtraction ['E', '-', 'E']
multiplication ['E', '*', 'E']
division ['E', '/', 'E']
power ['E', '^', 'E']
literal ['n']
parenthetized_expression ['(', 'E', ')']
negated_expression ['-', 'E'], :prec => '*'
end
end
In the above grammar, the symbols + and - are declared as being left-associative, meaning that 1 + 2 + 3 is parsed as (1 + 2) + 3 as opposed to 1 + (2 + 3) (right-associativity). The symbol ^ is declared nonassoc which means that expressions such as 2 ^ 3 ^ 4 are not allowed (non-associative). + and - are listed before ^ which means that they bind lower, and an expression such as 2 + 3 ^ 5 will be always be parsed as 2 + (3 ^ 5) and not (2 + 3) ^ 5.
Used for defining the Production-s for the symbol with name symbol. The block blk is evaluated in the context of a ProductionBuilder.
# File lib/dhaka/grammar/grammar.rb, line 103 def for_symbol symbol, &blk symbol = symbols[symbol] symbol.non_terminal = true ProductionBuilder.new(self, symbol).instance_eval(&blk) end
Returns the set of non-terminal symbols in the grammar.
# File lib/dhaka/grammar/grammar.rb, line 178 def non_terminal_symbols symbols.values.select {|symbol| symbol.non_terminal} end
Used for defining the precedences and associativities of symbols. The block blk is evaluated in the context of a PrecedenceBuilder.
# File lib/dhaka/grammar/grammar.rb, line 111 def precedences &blk PrecedenceBuilder.new(self).instance_eval(&blk) end
Returns the Production identified by name.
# File lib/dhaka/grammar/grammar.rb, line 168 def production_named(name) productions_by_name[name] end
Returns a list of all the Production-s in this grammar.
# File lib/dhaka/grammar/grammar.rb, line 125 def productions productions_by_name.values end
Returns the grammar symbol identified by name
# File lib/dhaka/grammar/grammar.rb, line 116 def symbol_for_name(name) if symbols.has_key? name symbols[name] else raise "No symbol with name #{name} found" end end
Returns the set of terminal symbols in the grammar.
# File lib/dhaka/grammar/grammar.rb, line 173 def terminal_symbols symbols.values.select {|symbol| symbol.terminal} end
Export the grammar to a BNF-like format
# File lib/dhaka/grammar/grammar.rb, line 183 def to_bnf result = [] last_symbol = nil productions.sort.each do |production| if production.symbol != last_symbol result << "" result << "#{production.symbol.name.inspect} :" last_symbol = production.symbol end result << " | #{production.expansion.collect{|symbol| symbol.name.inspect}.join(' ')}" end result.join("\n") end
Generated with the Darkfish Rdoc Generator 2.