Class: Semantic::Functions
- Inherits:
-
Hash
- Object
- Hash
- Semantic::Functions
- Defined in:
- ../lib/semantic_functions.rb
Overview
Parsing and storing of the syntactic functions. The Functions class subclasses the Hash class. It maps nonterminal symbols to its expansion hashes of the semantic functions:
{
"symbol1" => { "expansion1_1"=>[ AttrFn, AttrFn ... ], "expansion1_2"=>[ AttrFn, AttrFn ... ], ... },
"symbol2" => { "expansion2_1"=>[ AttrFn, AttrFn ... ], "expansion2_2"=>[ AttrFn, AttrFn ... ], ... },
...
}
Instance Attribute Summary (collapse)
-
- (Object) attributes
readonly
Attribute identifier array.
Class Method Summary (collapse)
-
+ (Object) extract_args(text)
Extract all arguments from the body of the semantic function.
-
+ (Object) make_proc(text)
Compile the semantic function previously processed by the extract_args and replace_args.
-
+ (Object) match_key(rulealt)
Convert the Mapper::RuleAlt into the representing string (the expansion key).
-
+ (Object) replace_args(text_orig, args)
Replace argument identifiers in the source of the semantic function by the _[i] notation.
Instance Method Summary (collapse)
-
- (Functions) initialize(semantic = nil)
constructor
Load the semantic file.
-
- (Object) new_attr_ref(text)
Convert the textual representation of the attribute to the AttrRef (the inversion is done by the render_attr method).
-
- (Object) node_expansion(symbol, expansion)
Search for the appropriate semantic functions by the particular nonterminal symbol and the RuleAlt expansion.
-
- (Object) render_attr(ref)
Convert the AttrRef to the textual representation of the attribute (the inversion is done by the new_attr_ref).
Constructor Details
- (Functions) initialize(semantic = nil)
Load the semantic file. The file has to follow this form:
symbol1:
expansion1:
result1_1 : function1_1
result1_2 : function1_2
...
result1_N1 : function1_N1
expansion2:
result2_1 : function2_1
...
result2_N2 : function2_N2
...
expansionM:
...
symbol2:
...
symbolP:
...
where:
* symbol ... a nonterminal symbol defined by the ABNF grammar (see Mapper::Grammar)
* expansion ... the expansion of the symbol defined by the grammar.
All terminal symbols are matched by the '$' character.
For instance, the ABNF rule:
if-statement = "if(" condition ") {" block "} else {" block "}"
is represented by:
if-statement:
$ condition $ block $ block $:
There is another special character '*' which matches all expansions.
* result ... the semantic attribute of some symbol defined by the semantic function.
It has the form:
node.attribute
where attribute is the identifier of the attribute and node is either
p (parent node) or ci (child node, i is the index of the child beginning from 0).
There are reserved attribute identifiers:
_text .. represents the text of the terminal symbol or the symbol identifier
of the nonterminal symbol
_valid .. the boolean attribute which restricts the usage of the expansion
(see AttrGrDepthFirst class for details)
* function ... the semantic function using node.attribute arguments, using the Ruby syntax.
Notes: The ‘_’ identifier is reserved and cannot be used as the attribute name or another variable name. If the attribute’s ‘nil’ value means ‘not defined’. Do not use ‘nil’ as a result of a semantic function.
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File '../lib/semantic_functions.rb', line 69 def initialize semantic=nil super() @attributes = AttrIndices.clone # default ctor return if semantic.nil? # parsing ctor yaml = YAML::load( semantic ) yaml.keys.sort.each do |symbol| rules = yaml[symbol] newrules = {} rules.each_pair do |expansion,funcs| batch = [] funcs.each_pair do |dest,body| target = new_attr_ref dest args = Functions.extract_args( body ) inputs = args.map { |arg| new_attr_ref arg } fn = Functions.make_proc( Functions.replace_args(body,args) ) batch << AttrFn.new( fn, target, inputs, body ) end newrules[expansion] = batch end store( symbol, newrules ) end end |
Instance Attribute Details
- (Object) attributes (readonly)
Attribute identifier array. It contains all attribute identifiers appearing on both the left and right sides of semantic fuctions. For example:
[ '_text', '_valid', 'cont', 'def', 'span' ]
Note that reserved identifiers beginning with ‘_’ are always present.
112 113 114 |
# File '../lib/semantic_functions.rb', line 112 def attributes @attributes end |
Class Method Details
+ (Object) extract_args(text)
Extract all arguments from the body of the semantic function.
132 133 134 |
# File '../lib/semantic_functions.rb', line 132 def Functions.extract_args text text.scan( /[\w]+\.[\w]+/ ).uniq end |
+ (Object) make_proc(text)
Compile the semantic function previously processed by the extract_args and replace_args.
144 145 146 |
# File '../lib/semantic_functions.rb', line 144 def Functions.make_proc text eval( "proc { |_| #{text} }" ) end |
+ (Object) match_key(rulealt)
Convert the Mapper::RuleAlt into the representing string (the expansion key).
116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
# File '../lib/semantic_functions.rb', line 116 def Functions.match_key rulealt result = rulealt.map do |token| case token.type when :literal '$' when :symbol token.data else raise 'Semantic::Functions wrong token type' end end result.join ' ' end |
+ (Object) replace_args(text_orig, args)
Replace argument identifiers in the source of the semantic function by the _[i] notation.
137 138 139 140 141 |
# File '../lib/semantic_functions.rb', line 137 def Functions.replace_args( text_orig, args ) text = text_orig.clone args.each_with_index { |a,i| text.gsub!( a, "_[#{i}]" ) } text end |
Instance Method Details
- (Object) new_attr_ref(text)
Convert the textual representation of the attribute to the AttrRef (the inversion is done by the render_attr method). For instance: ‘c1._text’ -> AttrRef.new( 2, 0 ). Note it modifies @attributes if given a new attribute identifier.
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
# File '../lib/semantic_functions.rb', line 159 def new_attr_ref text all,node,attr = /^([^.]*)\.([^.].*)$/.match( text ).to_a raise "Semantic::Functions wrong node/attribute '#{text}'" if all.nil? idx = @attributes.index attr if idx.nil? idx = @attributes.size @attributes.push attr end return AttrRef.new( 0, idx ) if node == 'p' raise "Semantic::Functions wrong node '#{text}'" unless node.size > 1 and /^c/ =~ node return AttrRef.new( node[1,node.size-1].to_i+1, idx ) end |
- (Object) node_expansion(symbol, expansion)
Search for the appropriate semantic functions by the particular nonterminal symbol and the RuleAlt expansion.
149 150 151 152 153 154 |
# File '../lib/semantic_functions.rb', line 149 def node_expansion( symbol, expansion ) node = fetch(symbol.data, nil) return [] if node.nil? batch = deep_copy( node.fetch( Functions.match_key(expansion), [] ) ) return batch.concat( deep_copy( node.fetch( '*', [] ) ) ) end |
- (Object) render_attr(ref)
Convert the AttrRef to the textual representation of the attribute (the inversion is done by the new_attr_ref). For example: AttrRef.new( 0, 1 ) -> ‘p._valid’.
177 178 179 |
# File '../lib/semantic_functions.rb', line 177 def render_attr ref "#{ ref.node_idx==0 ? 'p' : 'c'+(ref.node_idx-1).to_s }.#{ @attributes[ ref.attr_idx ] }" end |