Class: Dhaka::Grammar

Inherits:
Object
  • Object
show all
Defined in:
lib/grammar/grammar.rb

Overview

This class is subclassed when specifying a grammar. Note that subclasses of this class may not be further subclassed.

The following is a grammar specification for simple arithmetic. Familiarity with Yacc helps, but the short version is that precedences for symbols are specified 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

Class Method Summary collapse

Class Method Details

.for_symbol(symbol, &blk) ⇒ Object

Used for defining the productions for the symbol with name symbol. The block blk is evaluated in the context of a ProductionBuilder.



97
98
99
100
101
# File 'lib/grammar/grammar.rb', line 97

def self.for_symbol symbol, &blk
  symbol = symbols[symbol]
  symbol.non_terminal = true
  ProductionBuilder.new(self, symbol).instance_eval(&blk)
end

.precedences(&blk) ⇒ Object

Used for defining the precedences and associativities of symbols. The block blk is evaluated in the context of a PrecedenceBuilder.



105
106
107
# File 'lib/grammar/grammar.rb', line 105

def self.precedences &blk
  PrecedenceBuilder.new(self).instance_eval(&blk)
end

.symbol_for_name(name) ⇒ Object

Returns the grammar symbol identified by name



110
111
112
113
114
115
116
# File 'lib/grammar/grammar.rb', line 110

def self.symbol_for_name(name)
  if symbols.has_key? name
    symbols[name]
  else
    raise "No symbol with name #{name} found"
  end
end