examples/general/SRL/lib/ast_builder.rb in rley-0.5.08 vs examples/general/SRL/lib/ast_builder.rb in rley-0.5.09

- old
+ new

@@ -33,13 +33,34 @@ # @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' => 'quantifier' + when 'srl_0' # rule 'srl' => 'term' return_first_child(aRange, theTokens, theChildren) + when 'term_0' # rule 'term' => 'atom' + return_first_child(aRange, theTokens, theChildren) + + when 'term_1' # rule 'term' => %w[atom quantifier] + reduce_term_1(aProduction, aRange, theTokens, theChildren) + + when 'atom_0' #rule 'atom' => 'letter_range' + return_first_child(aRange, theTokens, theChildren) + + when 'letter_range_0' # rule 'letter_range' => %w[LETTER FROM LETTER_LIT TO LETTER_LIT] + reduce_letter_range_0(aProduction, aRange, theTokens, theChildren) + + when 'letter_range_1' #rule 'letter_range' => %w[UPPERCASE LETTER FROM LETTER_LIT TO LETTER_LIT] + reduce_letter_range_1(aProduction, aRange, theTokens, theChildren) + + when 'letter_range_2' # rule 'letter_range' => 'LETTER' + reduce_letter_range_2(aProduction, aRange, theTokens, theChildren) + + when 'letter_range_3' # rule 'letter_range' => %w[UPPERCASE LETTER] + reduce_letter_range_3(aProduction, aRange, theTokens, theChildren) + when 'quantifier_0' # rule 'quantifier' => 'ONCE' multiplicity(1, 1) when 'quantifier_1' # rule 'quantifier' => 'TWICE' multiplicity(2, 2) @@ -76,101 +97,76 @@ def multiplicity(lowerBound, upperBound) return SRL::Regex::Multiplicity.new(lowerBound, upperBound, :greedy) end + def char_range(lowerBound, upperBound) + # TODO fix module nesting + lower = Regex::Character.new(lowerBound) + upper = Regex::Character.new(upperBound) + return Regex::CharRange.new(lower, upper) + end + + def char_class(toNegate, *theChildren) + Regex::CharClass.new(toNegate, *theChildren) + end + + def repetition(expressionToRepeat, aMultiplicity) + return Regex::Repetition.new(expressionToRepeat, aMultiplicity) + end + + # rule 'term' => %w[atom quantifier] + def reduce_term_1(aProduction, aRange, theTokens, theChildren) + quantifier = theChildren.last + atom = theChildren.first + repetition(atom, quantifier) + end + + # rule 'letter_range' => %w[LETTER FROM LETTER_LIT TO LETTER_LIT] + def reduce_letter_range_0(aProduction, aRange, theTokens, theChildren) + lower = theChildren[2].token.lexeme + upper = theChildren[4].token.lexeme + ch_range = char_range(lower, upper) + char_class(false, ch_range) + end + + # rule 'letter_range' => %w[UPPERCASE LETTER FROM LETTER_LIT TO LETTER_LIT] + def reduce_letter_range_1(aProduction, aRange, theTokens, theChildren) + lower = theChildren[3].token.lexeme + upper = theChildren[5].token.lexeme + ch_range = char_range(lower.upcase, upper.upcase) + char_class(false, ch_range) + end + + # rule 'letter_range' => 'LETTER' + def reduce_letter_range_2(aProduction, aRange, theTokens, theChildren) + ch_range = char_range('a', 'z') + char_class(false, ch_range) + end + + #rule 'letter_range' => %w[UPPERCASE LETTER] + def reduce_letter_range_3(aProduction, aRange, theTokens, theChildren) + ch_range = char_range('A', 'Z') + char_class(false, ch_range) + 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 # 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 - # lower = theChildren[1].token.lexeme.to_i - multiplicity(3, upper) + multiplicity(lower, upper) end # rule 'quantifier' => %w[AT LEAST count TIMES] def reduce_quantifier_7(aProduction, aRange, theTokens, theChildren) count = theChildren[2].token.lexeme.to_i multiplicity(count, :more) end - -=begin - def reduce_binary_operator(theChildren) - operator_node = theChildren[1] - operator_node.children << theChildren[0] - operator_node.children << theChildren[2] - return operator_node - end - - # rule 'simple_expression' => %w[simple_expression add_operator term] - def reduce_simple_expression_1(_production, _range, _tokens, theChildren) - reduce_binary_operator(theChildren) - end - - # rule 'term' => %w[term mul_operator factor] - def reduce_term_1(_production, _range, _tokens, theChildren) - reduce_binary_operator(theChildren) - end - - # rule 'factor' => %w[simple_factor POWER simple_factor]] - def reduce_factor_1(aProduction, aRange, theTokens, theChildren) - result = PowerNode.new(theChildren[1].symbol, aRange) - result.children << theChildren[0] - result.children << theChildren[2] - - return result - end - - # rule 'simple_factor' => %[sign scalar] - def reduce_simple_factor_0(aProduction, aRange, theTokens, theChildren) - first_child = theChildren[0] - result = if first_child.kind_of?(CalcNegateNode) - -theChildren[1] - else - theChildren[1] - end - - return result - end - - # rule 'simple_factor' => %w[unary_function in_parenthesis] - def reduce_simple_factor_1(aProduction, aRange, theTokens, theChildren) - func = CalcUnaryFunction.new(theChildren[0].symbol, aRange.low) - func.func_name = theChildren[0].value - func.children << theChildren[1] - return func - end - - # rule 'simple_factor' => %w[MINUS in_parenthesis] - def reduce_simple_factor_2(aProduction, aRange, theTokens, theChildren) - negation = CalcNegateNode.new(theChildren[0].symbol, aRange.low) - negation.children << theChildren[1] - return negation - end - - # rule 'add_operator' => 'PLUS' - def reduce_add_operator_0(_production, aRange, _tokens, theChildren) - return CalcAddNode.new(theChildren[0].symbol, aRange) - end - - # rule 'add_operator' => 'MINUS' - def reduce_add_operator_1(_production, aRange, _tokens, theChildren) - return CalcSubtractNode.new(theChildren[0].symbol, aRange) - end - - # rule 'mul_operator' => 'STAR' - def reduce_mul_operator_0(_production, aRange, _tokens, theChildren) - return CalcMultiplyNode.new(theChildren[0].symbol, aRange) - end - - # rule 'mul_operator' => 'DIVIDE' - def reduce_mul_operator_1(_production, aRange, _tokens, theChildren) - return CalcDivideNode.new(theChildren[0].symbol, aRange) - end -=end end # class # End of file