Class: Rattler::Parsers::DispatchAction
- Inherits:
-
Parser
- Object
- Util::Node
- Parser
- Rattler::Parsers::DispatchAction
- Includes:
- Combining
- Defined in:
- lib/rattler/parsers/dispatch_action.rb
Overview
DispatchAction
decorates a parser to peform a symantic action on success by dispatching to a method.
Constant Summary collapse
- @@node_defaults =
{ :target => 'Rattler::Runtime::ParseNode', :method => 'parsed' }
Instance Attribute Summary collapse
-
#method_name ⇒ Object
readonly
the name of the method used as the symantic action.
-
#target_attrs ⇒ Object
readonly
the name of the method used as the symantic action.
Class Method Summary collapse
Instance Method Summary collapse
- #bind(scope, bind_args) ⇒ Object
- #bindable_code ⇒ Object
-
#initialize(children, attrs_arg = {}) ⇒ DispatchAction
constructor
Create a new parser that decorates a parser to peform a symantic on success.
-
#parse(scanner, rules, scope = {}) ⇒ Object
If the wrapped parser matches at the parse position, return the result of applying the symantic action, otherwise return a false value.
Methods included from Combining
Methods inherited from Parser
#&, #capturing?, #labeled?, #one_or_more, #optional, #skip, #variable_capture_count?, #with_ws, #zero_or_more, #|
Methods inherited from Util::Node
#==, #[], [], #attrs, #can_equal?, #child, #children, #each, #empty?, #eql?, #inspect, #method_missing, #name, #respond_to?, #same_contents?, #to_graphviz, #with_attrs, #with_attrs!, #with_children
Constructor Details
#initialize(parser, opts = {}) ⇒ DispatchAction #initialize(method_spec) ⇒ DispatchAction
Create a new parser that decorates a parser to peform a symantic on success.
64 65 66 67 68 69 |
# File 'lib/rattler/parsers/dispatch_action.rb', line 64 def initialize(children, attrs_arg={}) super(children, self.class.parse_attrs_arg(attrs_arg)) @@node_defaults.each {|k, v| attrs[k] ||= v } unless attrs[:code] @method_name = attrs[:method] @target_attrs = attrs[:target_attrs] || {} end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method in the class Rattler::Util::Node
Instance Attribute Details
#method_name ⇒ Object (readonly)
the name of the method used as the symantic action
72 73 74 |
# File 'lib/rattler/parsers/dispatch_action.rb', line 72 def method_name @method_name end |
#target_attrs ⇒ Object (readonly)
the name of the method used as the symantic action
72 73 74 |
# File 'lib/rattler/parsers/dispatch_action.rb', line 72 def target_attrs @target_attrs end |
Class Method Details
.parse_attrs_arg(arg) ⇒ Object
39 40 41 42 43 44 45 46 47 48 |
# File 'lib/rattler/parsers/dispatch_action.rb', line 39 def self.parse_attrs_arg(arg) #:nodoc: case arg when Hash arg when /^\s*(.+?)\s*\.\s*(.+?)\s*$/ { :target => $1, :method => $2 } else { :target => arg.to_s.strip } end end |
.parsed(results, *_) ⇒ Object
27 28 29 30 31 32 33 34 35 36 |
# File 'lib/rattler/parsers/dispatch_action.rb', line 27 def self.parsed(results, *_) #:nodoc: optional_expr, optional_attribute, optional_name = results expr = optional_expr.first || ESymbol[] a = self[expr, optional_attribute.first || @@node_defaults[:target]] unless optional_name.empty? a.with_attrs(:target_attrs => {:name => eval(optional_name.first, TOPLEVEL_BINDING)}) else a end end |
Instance Method Details
#bind(scope, bind_args) ⇒ Object
97 98 99 |
# File 'lib/rattler/parsers/dispatch_action.rb', line 97 def bind(scope, bind_args) bindable_code.bind(scope, bind_args) end |
#bindable_code ⇒ Object
93 94 95 |
# File 'lib/rattler/parsers/dispatch_action.rb', line 93 def bindable_code @bindable_code ||= NodeCode.new(target, method_name, target_attrs) end |
#parse(scanner, rules, scope = {}) ⇒ Object
If the wrapped parser matches at the parse position, return the result of applying the symantic action, otherwise return a false value.
81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/rattler/parsers/dispatch_action.rb', line 81 def parse(scanner, rules, scope = {}) if result = parse_child(child, scanner, rules, scope) {|_| scope = _ } if not capturing? apply([]) elsif result.respond_to?(:to_ary) apply(result, scope) else apply([result], scope) end end end |