Class: Dhaka::Evaluator
- Inherits:
-
Object
- Object
- Dhaka::Evaluator
- Defined in:
- lib/evaluator/evaluator.rb
Overview
This is the abstract base evaluator class. It is not directly instantiated. When defining an evaluator for a specific grammar, we subclass it. e.g. for FooGrammar we create a FooEvaluator that subclasses Evaluator. Note that FooEvaluator may not be further subclassed.
An evaluation rule for a given production named bar
is defined by calling for_bar
with a block that performs the evaluation. For detailed examples, see the evaluators in the test suite.
The following is an evaluator for arithmetic expressions. When a syntax tree node is encountered that corresponds to the production named addition
, the block passed to for_addition
is invoked. The evaluate
method is then recursively called on the child nodes, in this case the operands to the addition operation. The result is obtained by adding the evaluation results of the child nodes.
class ArithmeticPrecedenceEvaluator < Dhaka::Evaluator
self.grammar = ArithmeticPrecedenceGrammar
define_evaluation_rules do
for_subtraction do
evaluate(child_nodes[0]) - evaluate(child_nodes[2])
end
for_addition do
evaluate(child_nodes[0]) + evaluate(child_nodes[2])
end
for_division do
evaluate(child_nodes[0]).to_f/evaluate(child_nodes[2])
end
for_multiplication do
evaluate(child_nodes[0]) * evaluate(child_nodes[2])
end
for_literal do
child_nodes[0].token.value.to_i
end
for_parenthetized_expression do
evaluate(child_nodes[1])
end
for_negated_expression do
-evaluate(child_nodes[1])
end
for_power do
evaluate(child_nodes[0])**evaluate(child_nodes[2])
end
end
end
Class Method Summary collapse
-
.define_evaluation_rules ⇒ Object
Evaluation rules are defined within a block passed to this method.
- .inherited(evaluator) ⇒ Object
- .method_missing(method_name, *args, &blk) ⇒ Object
Instance Method Summary collapse
-
#child_nodes ⇒ Object
Returns the array of child nodes of the node being currently evaluated.
-
#evaluate(node) ⇒ Object
Evaluate a syntax tree node.
Class Method Details
.define_evaluation_rules ⇒ Object
Evaluation rules are defined within a block passed to this method.
77 78 79 80 81 |
# File 'lib/evaluator/evaluator.rb', line 77 def define_evaluation_rules self.actions = [] yield check_definitions end |
.inherited(evaluator) ⇒ Object
59 60 61 62 63 |
# File 'lib/evaluator/evaluator.rb', line 59 def inherited(evaluator) class << evaluator attr_accessor :grammar, :actions end end |
.method_missing(method_name, *args, &blk) ⇒ Object
65 66 67 68 69 70 71 72 73 74 |
# File 'lib/evaluator/evaluator.rb', line 65 def method_missing(method_name, *args, &blk) name = method_name.to_s if name =~ /^for_(.+)$/ rule_name = $1 actions << rule_name send(:define_method, rule_name, &blk) else super end end |
Instance Method Details
#child_nodes ⇒ Object
Returns the array of child nodes of the node being currently evaluated.
108 109 110 |
# File 'lib/evaluator/evaluator.rb', line 108 def child_nodes @node_stack.last end |
#evaluate(node) ⇒ Object
Evaluate a syntax tree node.
99 100 101 102 103 104 105 |
# File 'lib/evaluator/evaluator.rb', line 99 def evaluate node @node_stack ||= [] @node_stack << node.child_nodes result = send(node.production.name) @node_stack.pop result end |