examples/general/SRL/lib/ast_builder.rb in rley-0.5.11 vs examples/general/SRL/lib/ast_builder.rb in rley-0.5.12
- old
+ new
@@ -12,10 +12,12 @@
class ASTBuilder < Rley::Parser::ParseTreeBuilder
include ASTBuilding
Terminal2NodeClass = { }.freeze
+ attr_reader :options
+
protected
# Overriding method.
# Factory method for creating a node object for the given
# input token.
@@ -34,37 +36,113 @@
# @param aRange [Range] Range of tokens matched by the rule
# @param theTokens [Array] The input tokens
# @param theChildren [Array] Children nodes (one per rhs symbol)
def new_parent_node(aProduction, aRange, theTokens, theChildren)
node = case aProduction.name
- when 'srl_0' # rule 'srl' => 'pattern'
+ when 'srl_0' # rule 'srl' => 'expression'
return_first_child(aRange, theTokens, theChildren)
-
- when 'pattern_0' # rule 'pattern' => %w[pattern COMMA quantifiable]
+
+ when 'expression_0' # rule 'expression' => %w[pattern separator flags]
+ reduce_expression_0(aProduction, aRange, theTokens, theChildren)
+
+ when 'expression_1' # rule 'expression' => 'pattern'
+ return_first_child(aRange, theTokens, theChildren)
+
+ when 'pattern_0' # rule 'pattern' => %w[pattern separator quantifiable]
reduce_pattern_0(aProduction, aRange, theTokens, theChildren)
- when 'pattern_1' # rule 'pattern' => %w[pattern quantifiable]
- reduce_pattern_1(aProduction, aRange, theTokens, theChildren)
-
- when 'pattern_2' # rule 'pattern' => 'quantifiable'
+ when 'pattern_1' # rule 'pattern' => 'quantifiable'
return_first_child(aRange, theTokens, theChildren)
- when 'quantifiable_0' # rule 'quantifiable' => 'term'
+ when 'separator_0' # rule 'separator' => 'COMMA'
return_first_child(aRange, theTokens, theChildren)
- when 'quantifiable_1' # rule 'quantifiable' = %w[term quantifier]
+ when 'separator_1' # rule 'separator' => []
+ nil
+
+ when 'flags_0' # rule 'flags' => %[flags separator single_flag]
+ ### NEW
+ reduce_flags_0(aProduction, aRange, theTokens, theChildren)
+
+ when 'single_flag_0' # rule 'single_flag' => %w[CASE INSENSITIVE]
+ ### NEW
+ reduce_single_flag_0(aProduction, aRange, theTokens, theChildren)
+
+ when 'single_flag_1' # rule 'single_flag' => %w[MULTI LINE]
+ ### NEW
+ reduce_single_flag_1(aProduction, aRange, theTokens, theChildren)
+
+ when 'single_flag_2' # rule 'single_flag' => %w[ALL LAZY]
+ ### NEW
+ reduce_single_flag_2(aProduction, aRange, theTokens, theChildren)
+
+ # rule 'quantifiable' => %w[begin_anchor anchorable end_anchor]
+ when 'quantifiable_0'
+ reduce_quantifiable_0(aProduction, aRange, theTokens, theChildren)
+
+ # rule 'quantifiable' => %w[begin_anchor anchorable]
+ when 'quantifiable_1'
reduce_quantifiable_1(aProduction, aRange, theTokens, theChildren)
+ # rule 'quantifiable' => %w[anchorable end_anchor]
+ when 'quantifiable_2'
+ reduce_quantifiable_2(aProduction, aRange, theTokens, theChildren)
+
+ when 'quantifiable_3' # rule 'quantifiable' => 'anchorable'
+ return_first_child(aRange, theTokens, theChildren)
+
+ # rule 'begin_anchor' => %w[STARTS WITH]
+ # rule 'begin_anchor' => %w[BEGIN WITH]
+ when 'begin_anchor_0', 'begin_anchor_1'
+ reduce_begin_anchor_0(aProduction, aRange, theTokens, theChildren)
+
+ when 'end_anchor_0' # rule 'end_anchor' => %w[MUST END]
+ reduce_end_anchor_0(aProduction, aRange, theTokens, theChildren)
+
+ when 'anchorable_0' # rule 'anchorable' => 'assertable'
+ return_first_child(aRange, theTokens, theChildren)
+
+ when 'anchorable_1' # rule 'anchorable' => %w[assertable assertion]
+ reduce_anchorable_1(aProduction, aRange, theTokens, theChildren)
+
+ when 'anchorable_1' # rule 'anchorable' => %w[assertable assertion]
+ reduce_anchorable_1(aProduction, aRange, theTokens, theChildren)
+
+ # rule 'assertion' => %w[IF FOLLOWED BY assertable]
+ when 'assertion_0'
+ reduce_assertion_0(aProduction, aRange, theTokens, theChildren)
+
+ # rule 'assertion' => %w[IF NOT FOLLOWED BY assertable]
+ when 'assertion_1'
+ reduce_assertion_1(aProduction, aRange, theTokens, theChildren)
+
+ # rule 'assertion' => %w[IF ALREADY HAD assertable]
+ when 'assertion_2'
+ reduce_assertion_2(aProduction, aRange, theTokens, theChildren)
+
+ # rule 'assertion' => %w[IF NOT ALREADY HAD assertable]
+ when 'assertion_3'
+ reduce_assertion_3(aProduction, aRange, theTokens, theChildren)
+
+ when 'assertable_0' # rule 'assertable' => 'term'
+ return_first_child(aRange, theTokens, theChildren)
+
+ when 'assertable_1' # rule 'assertable' => %w[term quantifier]
+ reduce_assertable_1(aProduction, aRange, theTokens, theChildren)
+
when 'term_0' # rule 'term' => 'atom'
return_first_child(aRange, theTokens, theChildren)
when 'term_1' # rule 'term' => 'alternation'
return_first_child(aRange, theTokens, theChildren)
-
+
when 'term_2' # rule 'term' => 'grouping'
return_first_child(aRange, theTokens, theChildren)
+ when 'term_3' # rule 'term' => 'capturing_group'
+ return_first_child(aRange, theTokens, theChildren)
+
when 'atom_0' # rule 'atom' => 'letter_range'
return_first_child(aRange, theTokens, theChildren)
when 'atom_1' # rule 'atom' => 'digit_range'
return_first_child(aRange, theTokens, theChildren)
@@ -131,23 +209,38 @@
# rule 'alternation' => %w[ANY OF LPAREN alternatives RPAREN]
when 'alternation_0'
reduce_alternation_0(aProduction, aRange, theTokens, theChildren)
- # rule 'alternatives' => %w[alternatives COMMA quantifiable]
+ # rule 'alternatives' => %w[alternatives separator quantifiable]
when 'alternatives_0'
reduce_alternatives_0(aProduction, aRange, theTokens, theChildren)
- # rule 'alternatives' => %w[alternatives quantifiable]
- when 'alternatives_1'
+ when 'alternatives_1' # rule 'alternatives' => 'quantifiable'
reduce_alternatives_1(aProduction, aRange, theTokens, theChildren)
- when 'alternatives_2' # rule 'alternatives' => 'quantifiable'
- reduce_alternatives_2(aProduction, aRange, theTokens, theChildren)
+ when 'grouping_0' # rule 'grouping' => %w[LPAREN pattern RPAREN]
+ reduce_grouping_0(aProduction, aRange, theTokens, theChildren)
+
+ # rule 'capturing_group' => %w[CAPTURE assertable]
+ when 'capturing_group_0'
+ reduce_capturing_group_0(aProduction, aRange, theTokens, theChildren)
+
+ # rule 'capturing_group' => %w[CAPTURE assertable UNTIL assertable]
+ when 'capturing_group_1'
+ reduce_capturing_group_1(aProduction, aRange, theTokens, theChildren)
+
+ # rule 'capturing_group' => %w[CAPTURE assertable AS var_name]
+ when 'capturing_group_2'
+ reduce_capturing_group_2(aProduction, aRange, theTokens, theChildren)
+
+ # rule 'capturing_group' => %w[CAPTURE assertable AS var_name UNTIL assertable]
+ when 'capturing_group_3'
+ reduce_capturing_group_3(aProduction, aRange, theTokens, theChildren)
- when 'grouping' # rule 'grouping' => %w[LPAREN pattern RPAREN]
- reduce_grouping_0(aProduction, aRange, theTokens, theChildren)
+ when 'var_name_0' # rule 'var_name' => 'STRING_LIT'
+ return_first_child(aRange, theTokens, theChildren)
when 'quantifier_0' # rule 'quantifier' => 'ONCE'
multiplicity(1, 1)
when 'quantifier_1' # rule 'quantifier' => 'TWICE'
@@ -203,15 +296,15 @@
chars << Regex::Character.new(ch)
end
result = Regex::Concatenation.new(*chars)
else
if to_escape && Regex::Character::MetaChars.include?(aString)
- result = Regex::Concatenation.new(Regex::Character.new("\\"),
+ result = Regex::Concatenation.new(Regex::Character.new("\\"),
Regex::Character.new(aString))
else
result = Regex::Character.new(aString)
- end
+ end
end
return result
end
@@ -235,25 +328,104 @@
end
def repetition(expressionToRepeat, aMultiplicity)
return Regex::Repetition.new(expressionToRepeat, aMultiplicity)
end
-
- # rule 'pattern' => %w[pattern COMMA quantifiable]
+
+ # rule 'expression' => %w[pattern separator flags]
+ def reduce_expression_0(aProduction, aRange, theTokens, theChildren)
+ @options = theChildren[2] if theChildren[2]
+ return_first_child(aRange, theTokens, theChildren)
+ end
+
+ # rule 'pattern' => %w[pattern separator quantifiable]
def reduce_pattern_0(aProduction, aRange, theTokens, theChildren)
return Regex::Concatenation.new(theChildren[0], theChildren[2])
end
- # rule 'pattern' => %w[pattern quantifiable]
- def reduce_pattern_1(aProduction, aRange, theTokens, theChildren)
- return Regex::Concatenation.new(theChildren[0], theChildren[1])
+ # rule 'flags' => %[flags separator single_flag]
+ def reduce_flags_0(aProduction, aRange, theTokens, theChildren)
+ theChildren[0] << theChildren[2]
end
- # rule 'quantifiable' => %w[term quantifier]
+ # rule 'single_flag' => %w[CASE INSENSITIVE]
+ def reduce_single_flag_0(aProduction, aRange, theTokens, theChildren)
+ return [ Regex::MatchOption.new(:IGNORECASE, true) ]
+ end
+
+ # rule 'single_flag' => %w[MULTI LINE]
+ def reduce_single_flag_1(aProduction, aRange, theTokens, theChildren)
+ return [ Regex::MatchOption.new(:MULTILINE, true) ]
+ end
+
+ # rule 'single_flag' => %w[ALL LAZY]
+ def reduce_single_flag_2(aProduction, aRange, theTokens, theChildren)
+ return [ Regex::MatchOption.new(:ALL_LAZY, true) ]
+ end
+
+ # rule 'quantifiable' => %w[begin_anchor anchorable end_anchor]
+ def reduce_quantifiable_0(aProduction, aRange, theTokens, theChildren)
+ theChildren[1].begin_anchor = theChildren[0]
+ theChildren[1].end_anchor = theChildren[2]
+ return theChildren[1]
+ end
+
+ # rule 'quantifiable' => %w[begin_anchor anchorable]
def reduce_quantifiable_1(aProduction, aRange, theTokens, theChildren)
- quantifier = theChildren.last
- term = theChildren.first
+ theChildren[1].begin_anchor = theChildren[0]
+ return theChildren[1]
+ end
+
+ # rule 'quantifiable' => %w[anchorable end_anchor]
+ def reduce_quantifiable_2(aProduction, aRange, theTokens, theChildren)
+ theChildren[0].end_anchor = theChildren[1]
+ return theChildren[0]
+ end
+
+ # rule 'begin_anchor' => %w[STARTS WITH]
+ # rule 'begin_anchor' => %w[BEGIN WITH]
+ def reduce_begin_anchor_0(aProduction, aRange, theTokens, theChildren)
+ return Regex::Anchor.new('^')
+ end
+
+ # rule 'end_anchor' => %w[MUST END]
+ def reduce_end_anchor_0(aProduction, aRange, theTokens, theChildren)
+ return Regex::Anchor.new('$')
+ end
+
+
+ # rule 'anchorable' => %w[assertable assertion]
+ def reduce_anchorable_1(aProduction, aRange, theTokens, theChildren)
+ assertion = theChildren.last
+ assertion.children.unshift(theChildren[0])
+ return assertion
+ end
+
+ # rule 'assertion' => %w[IF FOLLOWED BY assertable]
+ def reduce_assertion_0(aProduction, aRange, theTokens, theChildren)
+ return Regex::Lookaround.new(theChildren.last, :ahead, :positive)
+ end
+
+ # rule 'assertion' => %w[IF NOT FOLLOWED BY assertable]
+ def reduce_assertion_1(aProduction, aRange, theTokens, theChildren)
+ return Regex::Lookaround.new(theChildren.last, :ahead, :negative)
+ end
+
+ # rule 'assertion' => %w[IF ALREADY HAD assertable]
+ def reduce_assertion_2(aProduction, aRange, theTokens, theChildren)
+ return Regex::Lookaround.new(theChildren.last, :behind, :positive)
+ end
+
+ # rule 'assertion' => %w[IF NOT ALREADY HAD assertable]
+ def reduce_assertion_3(aProduction, aRange, theTokens, theChildren)
+ return Regex::Lookaround.new(theChildren.last, :behind, :negative)
+ end
+
+ # rule 'anchorable' => %w[term quantifier]
+ def reduce_assertable_1(aProduction, aRange, theTokens, theChildren)
+ quantifier = theChildren[1]
+ term = theChildren[0]
repetition(term, quantifier)
end
# rule 'letter_range' => %w[LETTER FROM LETTER_LIT TO LETTER_LIT]
def reduce_letter_range_0(aProduction, aRange, theTokens, theChildren)
@@ -346,40 +518,59 @@
# What if literal is empty?...
raw_literal = theChildren[-1].token.lexeme.dup
return string_literal(raw_literal)
end
-
+
# rule 'alternation' => %w[ANY OF LPAREN alternatives RPAREN]
def reduce_alternation_0(aProduction, aRange, theTokens, theChildren)
return Regex::Alternation.new(*theChildren[3])
end
- # rule 'alternatives' => %w[alternatives COMMA quantifiable]
+ # rule 'alternatives' => %w[alternatives separator quantifiable]
def reduce_alternatives_0(aProduction, aRange, theTokens, theChildren)
return theChildren[0] << theChildren[-1]
end
- # rule 'alternatives' => %w[alternatives quantifiable]
- def reduce_alternatives_1(aProduction, aRange, theTokens, theChildren)
- return theChildren[0] << theChildren[-1]
- end
-
# rule 'alternatives' => 'quantifiable'
- def reduce_alternatives_2(aProduction, aRange, theTokens, theChildren)
+ def reduce_alternatives_1(aProduction, aRange, theTokens, theChildren)
return [theChildren.last]
end
-
+
# rule 'grouping' => %w[LPAREN pattern RPAREN]
def reduce_grouping_0(aProduction, aRange, theTokens, theChildren)
- return Regex::NonCapturingGroup.new(theChildren[1])
+ return Regex::NonCapturingGroup.new(theChildren[1])
end
+ # rule 'capturing_group' => %w[CAPTURE assertable]
+ def reduce_capturing_group_0(aProduction, aRange, theTokens, theChildren)
+ return Regex::CapturingGroup.new(theChildren[1])
+ end
+
+ # rule 'capturing_group' => %w[CAPTURE assertable UNTIL assertable]
+ def reduce_capturing_group_1(aProduction, aRange, theTokens, theChildren)
+ group = Regex::CapturingGroup.new(theChildren[1])
+ return Regex::Concatenation.new(group, theChildren[3])
+ end
+
+ # rule 'capturing_group' => %w[CAPTURE assertable AS var_name]
+ def reduce_capturing_group_2(aProduction, aRange, theTokens, theChildren)
+ name = theChildren[3].token.lexeme.dup
+ return Regex::CapturingGroup.new(theChildren[1], name)
+ end
+
+ # rule 'capturing_group' => %w[CAPTURE assertable AS var_name UNTIL assertable]
+ def reduce_capturing_group_3(aProduction, aRange, theTokens, theChildren)
+ name = theChildren[3].token.lexeme.dup
+ group = Regex::CapturingGroup.new(theChildren[1], name)
+ return Regex::Concatenation.new(group, theChildren[5])
+ end
+
# rule 'quantifier' => %w[EXACTLY count TIMES]
def reduce_quantifier_2(aProduction, aRange, theTokens, theChildren)
count = theChildren[1].token.lexeme.to_i
multiplicity(count, count)
- end
+ end
# rule 'quantifier' => %w[BETWEEN count AND count times_suffix]
def reduce_quantifier_3(aProduction, aRange, theTokens, theChildren)
lower = theChildren[1].token.lexeme.to_i
upper = theChildren[3].token.lexeme.to_i