Parent

Dhaka::Grammar

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.

Public Class Methods

for_symbol(symbol, &blk) click to toggle source

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
non_terminal_symbols() click to toggle source

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
precedences(&blk) click to toggle source

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
production_named(name) click to toggle source

Returns the Production identified by name.

# File lib/dhaka/grammar/grammar.rb, line 168
def production_named(name)
  productions_by_name[name]
end
productions() click to toggle source

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
symbol_for_name(name) click to toggle source

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
terminal_symbols() click to toggle source

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
to_bnf() click to toggle source

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

[Validate]

Generated with the Darkfish Rdoc Generator 2.