diff options
Diffstat (limited to 'test/racc/assets')
52 files changed, 0 insertions, 24903 deletions
diff --git a/test/racc/assets/cadenza.y b/test/racc/assets/cadenza.y deleted file mode 100644 index 1940ead225..0000000000 --- a/test/racc/assets/cadenza.y +++ /dev/null @@ -1,170 +0,0 @@ -# This grammar is released under an MIT license -# Author: William Howard (http://github.com/whoward) -# Source: https://github.com/whoward/cadenza/blob/master/src/cadenza.y - -class Cadenza::RaccParser - -/* expect this many shift/reduce conflicts */ -expect 37 - -rule - target - : document - | /* none */ { result = nil } - ; - - parameter_list - : logical_expression { result = [val[0]] } - | parameter_list ',' logical_expression { result = val[0].push(val[2]) } - ; - - /* this has a shift/reduce conflict but since Racc will shift in this case it is the correct behavior */ - primary_expression - : IDENTIFIER { result = VariableNode.new(val[0].value) } - | IDENTIFIER parameter_list { result = VariableNode.new(val[0].value, val[1]) } - | INTEGER { result = ConstantNode.new(val[0].value) } - | REAL { result = ConstantNode.new(val[0].value) } - | STRING { result = ConstantNode.new(val[0].value) } - | '(' filtered_expression ')' { result = val[1] } - ; - - multiplicative_expression - : primary_expression - | multiplicative_expression '*' primary_expression { result = OperationNode.new(val[0], "*", val[2]) } - | multiplicative_expression '/' primary_expression { result = OperationNode.new(val[0], "/", val[2]) } - ; - - additive_expression - : multiplicative_expression - | additive_expression '+' multiplicative_expression { result = OperationNode.new(val[0], "+", val[2]) } - | additive_expression '-' multiplicative_expression { result = OperationNode.new(val[0], "-", val[2]) } - ; - - boolean_expression - : additive_expression - | boolean_expression OP_EQ additive_expression { result = OperationNode.new(val[0], "==", val[2]) } - | boolean_expression OP_NEQ additive_expression { result = OperationNode.new(val[0], "!=", val[2]) } - | boolean_expression OP_LEQ additive_expression { result = OperationNode.new(val[0], "<=", val[2]) } - | boolean_expression OP_GEQ additive_expression { result = OperationNode.new(val[0], ">=", val[2]) } - | boolean_expression '>' additive_expression { result = OperationNode.new(val[0], ">", val[2]) } - | boolean_expression '<' additive_expression { result = OperationNode.new(val[0], "<", val[2]) } - ; - - inverse_expression - : boolean_expression - | NOT boolean_expression { result = BooleanInverseNode.new(val[1]) } - ; - - logical_expression - : inverse_expression - | logical_expression AND inverse_expression { result = OperationNode.new(val[0], "and", val[2]) } - | logical_expression OR inverse_expression { result = OperationNode.new(val[0], "or", val[2]) } - ; - - filter - : IDENTIFIER { result = FilterNode.new(val[0].value) } - | IDENTIFIER ':' parameter_list { result = FilterNode.new(val[0].value, val[2]) } - ; - - filter_list - : filter { result = [val[0]] } - | filter_list '|' filter { result = val[0].push(val[2]) } - ; - - filtered_expression - : logical_expression - | logical_expression '|' filter_list { result = FilteredValueNode.new(val[0], val[2]) } - ; - - inject_statement - : VAR_OPEN filtered_expression VAR_CLOSE { result = val[1] } - ; - - if_tag - : STMT_OPEN IF logical_expression STMT_CLOSE { open_scope!; result = val[2] } - | STMT_OPEN UNLESS logical_expression STMT_CLOSE { open_scope!; result = BooleanInverseNode.new(val[2]) } - ; - - else_tag - : STMT_OPEN ELSE STMT_CLOSE { result = close_scope!; open_scope! } - ; - - end_if_tag - : STMT_OPEN ENDIF STMT_CLOSE { result = close_scope! } - | STMT_OPEN ENDUNLESS STMT_CLOSE { result = close_scope! } - ; - - if_block - : if_tag end_if_tag { result = IfNode.new(val[0], val[1]) } - | if_tag document end_if_tag { result = IfNode.new(val[0], val[2]) } - | if_tag else_tag document end_if_tag { result = IfNode.new(val[0], val[1], val[3]) } - | if_tag document else_tag end_if_tag { result = IfNode.new(val[0], val[2], val[3]) } - | if_tag document else_tag document end_if_tag { result = IfNode.new(val[0], val[2], val[4]) } - ; - - for_tag - : STMT_OPEN FOR IDENTIFIER IN filtered_expression STMT_CLOSE { open_scope!; result = [val[2].value, val[4]] } - ; - - end_for_tag - : STMT_OPEN ENDFOR STMT_CLOSE { result = close_scope! } - ; - - /* this has a shift/reduce conflict but since Racc will shift in this case it is the correct behavior */ - for_block - : for_tag end_for_tag { result = ForNode.new(VariableNode.new(val[0].first), val[0].last, val[1]) } - | for_tag document end_for_tag { result = ForNode.new(VariableNode.new(val[0].first), val[0].last, val[2]) } - ; - - block_tag - : STMT_OPEN BLOCK IDENTIFIER STMT_CLOSE { result = open_block_scope!(val[2].value) } - ; - - end_block_tag - : STMT_OPEN ENDBLOCK STMT_CLOSE { result = close_block_scope! } - ; - - /* this has a shift/reduce conflict but since Racc will shift in this case it is the correct behavior */ - block_block - : block_tag end_block_tag { result = BlockNode.new(val[0], val[1]) } - | block_tag document end_block_tag { result = BlockNode.new(val[0], val[2]) } - ; - - generic_block_tag - : STMT_OPEN IDENTIFIER STMT_CLOSE { open_scope!; result = [val[1].value, []] } - | STMT_OPEN IDENTIFIER parameter_list STMT_CLOSE { open_scope!; result = [val[1].value, val[2]] } - ; - - end_generic_block_tag - : STMT_OPEN END STMT_CLOSE { result = close_scope! } - ; - - generic_block - : generic_block_tag document end_generic_block_tag { result = GenericBlockNode.new(val[0].first, val[2], val[0].last) } - ; - - extends_statement - : STMT_OPEN EXTENDS STRING STMT_CLOSE { result = val[2].value } - | STMT_OPEN EXTENDS IDENTIFIER STMT_CLOSE { result = VariableNode.new(val[2].value) } - ; - - document_component - : TEXT_BLOCK { result = TextNode.new(val[0].value) } - | inject_statement - | if_block - | for_block - | generic_block - | block_block - ; - - document - : document_component { push val[0] } - | document document_component { push val[1] } - | extends_statement { document.extends = val[0] } - | document extends_statement { document.extends = val[1] } - ; - ----- header ---- -# racc_parser.rb : generated by racc - ----- inner ---- diff --git a/test/racc/assets/cast.y b/test/racc/assets/cast.y deleted file mode 100644 index d180c09e14..0000000000 --- a/test/racc/assets/cast.y +++ /dev/null @@ -1,926 +0,0 @@ -# The MIT License -# -# Copyright (c) George Ogata -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -class C::Parser -# shift/reduce conflict on "if (c) if (c) ; else ; else ;" -expect 1 -rule - -# A.2.4 External definitions - -# Returns TranslationUnit -translation_unit - : external_declaration {result = TranslationUnit.new_at(val[0].pos, NodeChain[val[0]])} - | translation_unit external_declaration {result = val[0]; result.entities << val[1]} - -# Returns Declaration|FunctionDef -external_declaration - : function_definition {result = val[0]} - | declaration {result = val[0]} - -# Returns FunctionDef -function_definition - : declaration_specifiers declarator declaration_list compound_statement {result = make_function_def(val[0][0], val[0][1], val[1], val[2], val[3])} - | declaration_specifiers declarator compound_statement {result = make_function_def(val[0][0], val[0][1], val[1], nil , val[2])} - -# Returns [Declaration] -declaration_list - : declaration {result = [val[0]]} - | declaration_list declaration {result = val[0] << val[1]} - -# A.2.3 Statements - -# Returns Statement -statement - : labeled_statement {result = val[0]} - | compound_statement {result = val[0]} - | expression_statement {result = val[0]} - | selection_statement {result = val[0]} - | iteration_statement {result = val[0]} - | jump_statement {result = val[0]} - -# Returns Statement -labeled_statement - : identifier COLON statement {val[2].labels.unshift(PlainLabel.new_at(val[0].pos, val[0].val)); result = val[2]} - | CASE constant_expression COLON statement {val[3].labels.unshift(Case .new_at(val[0].pos, val[1] )); result = val[3]} - | DEFAULT COLON statement {val[2].labels.unshift(Default .new_at(val[0].pos )); result = val[2]} - # type names can also be used as labels - | typedef_name COLON statement {val[2].labels.unshift(PlainLabel.new_at(val[0].pos, val[0].name)); result = val[2]} - -# Returns Block -compound_statement - : LBRACE block_item_list RBRACE {result = Block.new_at(val[0].pos, val[1])} - | LBRACE RBRACE {result = Block.new_at(val[0].pos )} - -# Returns NodeChain[Declaration|Statement] -block_item_list - : block_item {result = NodeChain[val[0]]} - | block_item_list block_item {result = val[0] << val[1]} - -# Returns Declaration|Statement -block_item - : declaration {result = val[0]} - | statement {result = val[0]} - -# Returns ExpressionStatement -expression_statement - : expression SEMICOLON {result = ExpressionStatement.new_at(val[0].pos, val[0])} - | SEMICOLON {result = ExpressionStatement.new_at(val[0].pos )} - -# Returns Statement -selection_statement - : IF LPAREN expression RPAREN statement {result = If .new_at(val[0].pos, val[2], val[4] )} - | IF LPAREN expression RPAREN statement ELSE statement {result = If .new_at(val[0].pos, val[2], val[4], val[6])} - | SWITCH LPAREN expression RPAREN statement {result = Switch.new_at(val[0].pos, val[2], val[4] )} - -# Returns Statement -iteration_statement - : WHILE LPAREN expression RPAREN statement {result = While.new_at(val[0].pos, val[2], val[4] )} - | DO statement WHILE LPAREN expression RPAREN SEMICOLON {result = While.new_at(val[0].pos, val[4], val[1], :do => true )} - | FOR LPAREN expression SEMICOLON expression SEMICOLON expression RPAREN statement {result = For.new_at(val[0].pos, val[2], val[4], val[6], val[8])} - | FOR LPAREN expression SEMICOLON expression SEMICOLON RPAREN statement {result = For.new_at(val[0].pos, val[2], val[4], nil , val[7])} - | FOR LPAREN expression SEMICOLON SEMICOLON expression RPAREN statement {result = For.new_at(val[0].pos, val[2], nil , val[5], val[7])} - | FOR LPAREN expression SEMICOLON SEMICOLON RPAREN statement {result = For.new_at(val[0].pos, val[2], nil , nil , val[6])} - | FOR LPAREN SEMICOLON expression SEMICOLON expression RPAREN statement {result = For.new_at(val[0].pos, nil , val[3], val[5], val[7])} - | FOR LPAREN SEMICOLON expression SEMICOLON RPAREN statement {result = For.new_at(val[0].pos, nil , val[3], nil , val[6])} - | FOR LPAREN SEMICOLON SEMICOLON expression RPAREN statement {result = For.new_at(val[0].pos, nil , nil , val[4], val[6])} - | FOR LPAREN SEMICOLON SEMICOLON RPAREN statement {result = For.new_at(val[0].pos, nil , nil , nil , val[5])} - | FOR LPAREN declaration expression SEMICOLON expression RPAREN statement {result = For.new_at(val[0].pos, val[2], val[3], val[5], val[7])} - | FOR LPAREN declaration expression SEMICOLON RPAREN statement {result = For.new_at(val[0].pos, val[2], val[3], nil , val[6])} - | FOR LPAREN declaration SEMICOLON expression RPAREN statement {result = For.new_at(val[0].pos, val[2], nil , val[4], val[6])} - | FOR LPAREN declaration SEMICOLON RPAREN statement {result = For.new_at(val[0].pos, val[2], nil , nil , val[5])} - -# Returns Statement -jump_statement - : GOTO identifier SEMICOLON {result = Goto .new_at(val[0].pos, val[1].val)} - | CONTINUE SEMICOLON {result = Continue.new_at(val[0].pos )} - | BREAK SEMICOLON {result = Break .new_at(val[0].pos )} - | RETURN expression SEMICOLON {result = Return .new_at(val[0].pos, val[1] )} - | RETURN SEMICOLON {result = Return .new_at(val[0].pos )} - # type names can also be used as labels - | GOTO typedef_name SEMICOLON {result = Goto .new_at(val[0].pos, val[1].name)} - -# A.2.2 Declarations - -# Returns Declaration -declaration - : declaration_specifiers init_declarator_list SEMICOLON {result = make_declaration(val[0][0], val[0][1], val[1])} - | declaration_specifiers SEMICOLON {result = make_declaration(val[0][0], val[0][1], NodeArray[])} - -# Returns {Pos, [Symbol]} -declaration_specifiers - : storage_class_specifier declaration_specifiers {val[1][1] << val[0][1]; result = val[1]} - | storage_class_specifier {result = [val[0][0], [val[0][1]]]} - | type_specifier declaration_specifiers {val[1][1] << val[0][1]; result = val[1]} - | type_specifier {result = [val[0][0], [val[0][1]]]} - | type_qualifier declaration_specifiers {val[1][1] << val[0][1]; result = val[1]} - | type_qualifier {result = [val[0][0], [val[0][1]]]} - | function_specifier declaration_specifiers {val[1][1] << val[0][1]; result = val[1]} - | function_specifier {result = [val[0][0], [val[0][1]]]} - -# Returns NodeArray[Declarator] -init_declarator_list - : init_declarator {result = NodeArray[val[0]]} - | init_declarator_list COMMA init_declarator {result = val[0] << val[2]} - -# Returns Declarator -init_declarator - : declarator {result = val[0]} - | declarator EQ initializer {val[0].init = val[2]; result = val[0]} - -# Returns [Pos, Symbol] -storage_class_specifier - : TYPEDEF {result = [val[0].pos, :typedef ]} - | EXTERN {result = [val[0].pos, :extern ]} - | STATIC {result = [val[0].pos, :static ]} - | AUTO {result = [val[0].pos, :auto ]} - | REGISTER {result = [val[0].pos, :register]} - -# Returns [Pos, Type|Symbol] -type_specifier - : VOID {result = [val[0].pos, :void ]} - | CHAR {result = [val[0].pos, :char ]} - | SHORT {result = [val[0].pos, :short ]} - | INT {result = [val[0].pos, :int ]} - | LONG {result = [val[0].pos, :long ]} - | FLOAT {result = [val[0].pos, :float ]} - | DOUBLE {result = [val[0].pos, :double ]} - | SIGNED {result = [val[0].pos, :signed ]} - | UNSIGNED {result = [val[0].pos, :unsigned ]} - | BOOL {result = [val[0].pos, :_Bool ]} - | COMPLEX {result = [val[0].pos, :_Complex ]} - | IMAGINARY {result = [val[0].pos, :_Imaginary]} - | struct_or_union_specifier {result = [val[0].pos, val[0] ]} - | enum_specifier {result = [val[0].pos, val[0] ]} - | typedef_name {result = [val[0].pos, val[0] ]} - -# Returns Struct|Union -struct_or_union_specifier - : struct_or_union identifier LBRACE struct_declaration_list RBRACE {result = val[0][1].new_at(val[0][0], val[1].val, val[3])} - | struct_or_union LBRACE struct_declaration_list RBRACE {result = val[0][1].new_at(val[0][0], nil , val[2])} - | struct_or_union identifier {result = val[0][1].new_at(val[0][0], val[1].val, nil )} - # type names can also be used as struct identifiers - | struct_or_union typedef_name LBRACE struct_declaration_list RBRACE {result = val[0][1].new_at(val[0][0], val[1].name, val[3])} - | struct_or_union typedef_name {result = val[0][1].new_at(val[0][0], val[1].name, nil )} - -# Returns [Pos, Class] -struct_or_union - : STRUCT {result = [val[0].pos, Struct]} - | UNION {result = [val[0].pos, Union ]} - -# Returns NodeArray[Declaration] -struct_declaration_list - : struct_declaration {result = NodeArray[val[0]]} - | struct_declaration_list struct_declaration {val[0] << val[1]; result = val[0]} - -# Returns Declaration -struct_declaration - : specifier_qualifier_list struct_declarator_list SEMICOLON {result = make_declaration(val[0][0], val[0][1], val[1])} - -# Returns {Pos, [Symbol]} -specifier_qualifier_list - : type_specifier specifier_qualifier_list {val[1][1] << val[0][1]; result = val[1]} - | type_specifier {result = [val[0][0], [val[0][1]]]} - | type_qualifier specifier_qualifier_list {val[1][1] << val[0][1]; result = val[1]} - | type_qualifier {result = [val[0][0], [val[0][1]]]} - -# Returns NodeArray[Declarator] -struct_declarator_list - : struct_declarator {result = NodeArray[val[0]]} - | struct_declarator_list COMMA struct_declarator {result = val[0] << val[2]} - -# Returns Declarator -struct_declarator - : declarator {result = val[0]} - | declarator COLON constant_expression {result = val[0]; val[0].num_bits = val[2]} - | COLON constant_expression {result = Declarator.new_at(val[0].pos, :num_bits => val[1])} - -# Returns Enum -enum_specifier - : ENUM identifier LBRACE enumerator_list RBRACE {result = Enum.new_at(val[0].pos, val[1].val, val[3])} - | ENUM LBRACE enumerator_list RBRACE {result = Enum.new_at(val[0].pos, nil , val[2])} - | ENUM identifier LBRACE enumerator_list COMMA RBRACE {result = Enum.new_at(val[0].pos, val[1].val, val[3])} - | ENUM LBRACE enumerator_list COMMA RBRACE {result = Enum.new_at(val[0].pos, nil , val[2])} - | ENUM identifier {result = Enum.new_at(val[0].pos, val[1].val, nil )} - # type names can also be used as enum names - | ENUM typedef_name LBRACE enumerator_list RBRACE {result = Enum.new_at(val[0].pos, val[1].name, val[3])} - | ENUM typedef_name LBRACE enumerator_list COMMA RBRACE {result = Enum.new_at(val[0].pos, val[1].name, val[3])} - | ENUM typedef_name {result = Enum.new_at(val[0].pos, val[1].name, nil )} - -# Returns NodeArray[Enumerator] -enumerator_list - : enumerator {result = NodeArray[val[0]]} - | enumerator_list COMMA enumerator {result = val[0] << val[2]} - -# Returns Enumerator -enumerator - : enumeration_constant {result = Enumerator.new_at(val[0].pos, val[0].val, nil )} - | enumeration_constant EQ constant_expression {result = Enumerator.new_at(val[0].pos, val[0].val, val[2])} - -# Returns [Pos, Symbol] -type_qualifier - : CONST {result = [val[0].pos, :const ]} - | RESTRICT {result = [val[0].pos, :restrict]} - | VOLATILE {result = [val[0].pos, :volatile]} - -# Returns [Pos, Symbol] -function_specifier - : INLINE {result = [val[0].pos, :inline]} - -# Returns Declarator -declarator - : pointer direct_declarator {result = add_decl_type(val[1], val[0])} - | direct_declarator {result = val[0]} - -# Returns Declarator -direct_declarator - : identifier {result = Declarator.new_at(val[0].pos, nil, val[0].val)} - | LPAREN declarator RPAREN {result = val[1]} - | direct_declarator LBRACKET type_qualifier_list assignment_expression RBRACKET {result = add_decl_type(val[0], Array.new_at(val[0].pos ))} # TODO - | direct_declarator LBRACKET type_qualifier_list RBRACKET {result = add_decl_type(val[0], Array.new_at(val[0].pos ))} # TODO - | direct_declarator LBRACKET assignment_expression RBRACKET {result = add_decl_type(val[0], Array.new_at(val[0].pos, nil, val[2]))} - | direct_declarator LBRACKET RBRACKET {result = add_decl_type(val[0], Array.new_at(val[0].pos ))} - | direct_declarator LBRACKET STATIC type_qualifier_list assignment_expression RBRACKET {result = add_decl_type(val[0], Array.new_at(val[0].pos ))} # TODO - | direct_declarator LBRACKET STATIC assignment_expression RBRACKET {result = add_decl_type(val[0], Array.new_at(val[0].pos ))} # TODO - | direct_declarator LBRACKET type_qualifier_list STATIC assignment_expression RBRACKET {result = add_decl_type(val[0], Array.new_at(val[0].pos ))} # TODO - | direct_declarator LBRACKET type_qualifier_list MUL RBRACKET {result = add_decl_type(val[0], Array.new_at(val[0].pos ))} # TODO - | direct_declarator LBRACKET MUL RBRACKET {result = add_decl_type(val[0], Array.new_at(val[0].pos ))} # TODO - | direct_declarator LPAREN parameter_type_list RPAREN {result = add_decl_type(val[0], Function.new_at(val[0].pos, nil, param_list(*val[2]), :var_args => val[2][1]))} - | direct_declarator LPAREN identifier_list RPAREN {result = add_decl_type(val[0], Function.new_at(val[0].pos, nil, val[2]))} - | direct_declarator LPAREN RPAREN {result = add_decl_type(val[0], Function.new_at(val[0].pos ))} - -# Returns Pointer -pointer - : MUL type_qualifier_list {result = add_type_quals(Pointer.new_at(val[0].pos), val[1][1]) } - | MUL {result = Pointer.new_at(val[0].pos) } - | MUL type_qualifier_list pointer {p = add_type_quals(Pointer.new_at(val[0].pos), val[1][1]); val[2].direct_type = p; result = val[2]} - | MUL pointer {p = Pointer.new_at(val[0].pos) ; val[1].direct_type = p; result = val[1]} - -# Returns {Pos, [Symbol]} -type_qualifier_list - : type_qualifier {result = [val[0][0], [val[0][1]]]} - | type_qualifier_list type_qualifier {val[0][1] << val[1][1]; result = val[0]} - -# Returns [NodeArray[Parameter], var_args?] -parameter_type_list - : parameter_list {result = [val[0], false]} - | parameter_list COMMA ELLIPSIS {result = [val[0], true ]} - -# Returns NodeArray[Parameter] -parameter_list - : parameter_declaration {result = NodeArray[val[0]]} - | parameter_list COMMA parameter_declaration {result = val[0] << val[2]} - -# Returns Parameter -parameter_declaration - : declaration_specifiers declarator {ind_type = val[1].indirect_type and ind_type.detach - result = make_parameter(val[0][0], val[0][1], ind_type, val[1].name)} - | declaration_specifiers abstract_declarator {result = make_parameter(val[0][0], val[0][1], val[1] , nil )} - | declaration_specifiers {result = make_parameter(val[0][0], val[0][1], nil , nil )} - -# Returns NodeArray[Parameter] -identifier_list - : identifier {result = NodeArray[Parameter.new_at(val[0].pos, nil, val[0].val)]} - | identifier_list COMMA identifier {result = val[0] << Parameter.new_at(val[2].pos, nil, val[2].val)} - -# Returns Type -type_name - : specifier_qualifier_list abstract_declarator {val[1].direct_type = make_direct_type(val[0][0], val[0][1]); result = val[1]} - | specifier_qualifier_list {result = make_direct_type(val[0][0], val[0][1]) } - -# Returns Type -abstract_declarator - : pointer {result = val[0]} - | pointer direct_abstract_declarator {val[1].direct_type = val[0]; result = val[1]} - | direct_abstract_declarator {result = val[0]} - -# Returns Type -direct_abstract_declarator - : LPAREN abstract_declarator RPAREN {result = val[1]} - | direct_abstract_declarator LBRACKET assignment_expression RBRACKET {val[0].direct_type = Array.new_at(val[0].pos, nil, val[2]); result = val[0]} - | direct_abstract_declarator LBRACKET RBRACKET {val[0].direct_type = Array.new_at(val[0].pos, nil, nil ); result = val[0]} - | LBRACKET assignment_expression RBRACKET {result = Array.new_at(val[0].pos, nil, val[1])} - | LBRACKET RBRACKET {result = Array.new_at(val[0].pos )} - | direct_abstract_declarator LBRACKET MUL RBRACKET {val[0].direct_type = Array.new_at(val[0].pos); result = val[0]} # TODO - | LBRACKET MUL RBRACKET {result = Array.new_at(val[0].pos)} # TODO - | direct_abstract_declarator LPAREN parameter_type_list RPAREN {val[0].direct_type = Function.new_at(val[0].pos, nil, param_list(*val[2]), val[2][1]); result = val[0]} - | direct_abstract_declarator LPAREN RPAREN {val[0].direct_type = Function.new_at(val[0].pos ); result = val[0]} - | LPAREN parameter_type_list RPAREN {result = Function.new_at(val[0].pos, nil, param_list(*val[1]), val[1][1])} - | LPAREN RPAREN {result = Function.new_at(val[0].pos )} - -# Returns CustomType -typedef_name - #: identifier -- insufficient since we must distinguish between type - # names and var names (otherwise we have a conflict) - : TYPENAME {result = CustomType.new_at(val[0].pos, val[0].val)} - -# Returns Expression -initializer - : assignment_expression {result = val[0]} - | LBRACE initializer_list RBRACE {result = CompoundLiteral.new_at(val[0].pos, nil, val[1])} - | LBRACE initializer_list COMMA RBRACE {result = CompoundLiteral.new_at(val[0].pos, nil, val[1])} - -# Returns NodeArray[MemberInit] -initializer_list - : designation initializer {result = NodeArray[MemberInit.new_at(val[0][0] , val[0][1], val[1])]} - | initializer {result = NodeArray[MemberInit.new_at(val[0].pos, nil , val[0])]} - | initializer_list COMMA designation initializer {result = val[0] << MemberInit.new_at(val[2][0] , val[2][1], val[3])} - | initializer_list COMMA initializer {result = val[0] << MemberInit.new_at(val[2].pos, nil , val[2])} - -# Returns {Pos, NodeArray[Expression|Token]} -designation - : designator_list EQ {result = val[0]} - -# Returns {Pos, NodeArray[Expression|Token]} -designator_list - : designator {result = val[0]; val[0][1] = NodeArray[val[0][1]]} - | designator_list designator {result = val[0]; val[0][1] << val[1][1]} - -# Returns {Pos, Expression|Member} -designator - : LBRACKET constant_expression RBRACKET {result = [val[1].pos, val[1] ]} - | DOT identifier {result = [val[1].pos, Member.new_at(val[1].pos, val[1].val)]} - -# A.2.1 Expressions - -# Returns Expression -primary_expression - : identifier {result = Variable.new_at(val[0].pos, val[0].val)} - | constant {result = val[0]} - | string_literal {result = val[0]} - # GCC EXTENSION: allow a compound statement in parentheses as an expression - | LPAREN expression RPAREN {result = val[1]} - | LPAREN compound_statement RPAREN {block_expressions_enabled? or parse_error val[0].pos, "compound statement found where expression expected" - result = BlockExpression.new(val[1]); result.pos = val[0].pos} - -# Returns Expression -postfix_expression - : primary_expression {result = val[0]} - | postfix_expression LBRACKET expression RBRACKET {result = Index .new_at(val[0].pos, val[0], val[2])} - | postfix_expression LPAREN argument_expression_list RPAREN {result = Call .new_at(val[0].pos, val[0], val[2] )} - | postfix_expression LPAREN RPAREN {result = Call .new_at(val[0].pos, val[0], NodeArray[])} - | postfix_expression DOT identifier {result = Dot .new_at(val[0].pos, val[0], Member.new(val[2].val))} - | postfix_expression ARROW identifier {result = Arrow .new_at(val[0].pos, val[0], Member.new(val[2].val))} - | postfix_expression INC {result = PostInc .new_at(val[0].pos, val[0] )} - | postfix_expression DEC {result = PostDec .new_at(val[0].pos, val[0] )} - | LPAREN type_name RPAREN LBRACE initializer_list RBRACE {result = CompoundLiteral.new_at(val[0].pos, val[1], val[4])} - | LPAREN type_name RPAREN LBRACE initializer_list COMMA RBRACE {result = CompoundLiteral.new_at(val[0].pos, val[1], val[4])} - -# Returns [Expression|Type] -argument_expression_list - : argument_expression {result = NodeArray[val[0]]} - | argument_expression_list COMMA argument_expression {result = val[0] << val[2]} - -# Returns Expression|Type -- EXTENSION: allow type names here too, to support some standard library macros (e.g., va_arg [7.15.1.1]) -argument_expression - : assignment_expression {result = val[0]} - | type_name {result = val[0]} - -# Returns Expression -unary_expression - : postfix_expression {result = val[0]} - | INC unary_expression {result = PreInc.new_at(val[0].pos, val[1])} - | DEC unary_expression {result = PreDec.new_at(val[0].pos, val[1])} - | unary_operator cast_expression {result = val[0][0].new_at(val[0][1], val[1])} - | SIZEOF unary_expression {result = Sizeof.new_at(val[0].pos, val[1])} - | SIZEOF LPAREN type_name RPAREN {result = Sizeof.new_at(val[0].pos, val[2])} - -# Returns [Class, Pos] -unary_operator - : AND {result = [Address , val[0].pos]} - | MUL {result = [Dereference, val[0].pos]} - | ADD {result = [Positive , val[0].pos]} - | SUB {result = [Negative , val[0].pos]} - | NOT {result = [BitNot , val[0].pos]} - | BANG {result = [Not , val[0].pos]} - -# Returns Expression -cast_expression - : unary_expression {result = val[0]} - | LPAREN type_name RPAREN cast_expression {result = Cast.new_at(val[0].pos, val[1], val[3])} - -# Returns Expression -multiplicative_expression - : cast_expression {result = val[0]} - | multiplicative_expression MUL cast_expression {result = Multiply.new_at(val[0].pos, val[0], val[2])} - | multiplicative_expression DIV cast_expression {result = Divide .new_at(val[0].pos, val[0], val[2])} - | multiplicative_expression MOD cast_expression {result = Mod .new_at(val[0].pos, val[0], val[2])} - -# Returns Expression -additive_expression - : multiplicative_expression {result = val[0]} - | additive_expression ADD multiplicative_expression {result = Add .new_at(val[0].pos, val[0], val[2])} - | additive_expression SUB multiplicative_expression {result = Subtract.new_at(val[0].pos, val[0], val[2])} - -# Returns Expression -shift_expression - : additive_expression {result = val[0]} - | shift_expression LSHIFT additive_expression {result = ShiftLeft .new_at(val[0].pos, val[0], val[2])} - | shift_expression RSHIFT additive_expression {result = ShiftRight.new_at(val[0].pos, val[0], val[2])} - -# Returns Expression -relational_expression - : shift_expression {result = val[0]} - | relational_expression LT shift_expression {result = Less.new_at(val[0].pos, val[0], val[2])} - | relational_expression GT shift_expression {result = More.new_at(val[0].pos, val[0], val[2])} - | relational_expression LEQ shift_expression {result = LessOrEqual.new_at(val[0].pos, val[0], val[2])} - | relational_expression GEQ shift_expression {result = MoreOrEqual.new_at(val[0].pos, val[0], val[2])} - -# Returns Expression -equality_expression - : relational_expression {result = val[0]} - | equality_expression EQEQ relational_expression {result = Equal .new_at(val[0].pos, val[0], val[2])} - | equality_expression NEQ relational_expression {result = NotEqual.new_at(val[0].pos, val[0], val[2])} - -# Returns Expression -and_expression - : equality_expression {result = val[0]} - | and_expression AND equality_expression {result = BitAnd.new_at(val[0].pos, val[0], val[2])} - -# Returns Expression -exclusive_or_expression - : and_expression {result = val[0]} - | exclusive_or_expression XOR and_expression {result = BitXor.new_at(val[0].pos, val[0], val[2])} - -# Returns Expression -inclusive_or_expression - : exclusive_or_expression {result = val[0]} - | inclusive_or_expression OR exclusive_or_expression {result = BitOr.new_at(val[0].pos, val[0], val[2])} - -# Returns Expression -logical_and_expression - : inclusive_or_expression {result = val[0]} - | logical_and_expression ANDAND inclusive_or_expression {result = And.new_at(val[0].pos, val[0], val[2])} - -# Returns Expression -logical_or_expression - : logical_and_expression {result = val[0]} - | logical_or_expression OROR logical_and_expression {result = Or.new_at(val[0].pos, val[0], val[2])} - -# Returns Expression -conditional_expression - : logical_or_expression {result = val[0]} - | logical_or_expression QUESTION expression COLON conditional_expression {result = Conditional.new_at(val[0].pos, val[0], val[2], val[4])} - -# Returns Expression -assignment_expression - : conditional_expression {result = val[0]} - | unary_expression assignment_operator assignment_expression {result = val[1].new_at(val[0].pos, val[0], val[2])} - -# Returns Class -assignment_operator - : EQ {result = Assign} - | MULEQ {result = MultiplyAssign} - | DIVEQ {result = DivideAssign} - | MODEQ {result = ModAssign} - | ADDEQ {result = AddAssign} - | SUBEQ {result = SubtractAssign} - | LSHIFTEQ {result = ShiftLeftAssign} - | RSHIFTEQ {result = ShiftRightAssign} - | ANDEQ {result = BitAndAssign} - | XOREQ {result = BitXorAssign} - | OREQ {result = BitOrAssign} - -# Returns Expression -expression - : assignment_expression {result = val[0]} - | expression COMMA assignment_expression { - if val[0].is_a? Comma - if val[2].is_a? Comma - val[0].exprs.push(*val[2].exprs) - else - val[0].exprs << val[2] - end - result = val[0] - else - if val[2].is_a? Comma - val[2].exprs.unshift(val[0]) - val[2].pos = val[0].pos - result = val[2] - else - result = Comma.new_at(val[0].pos, NodeArray[val[0], val[2]]) - end - end - } - -# Returns Expression -constant_expression - : conditional_expression {result = val[0]} - -# A.1.1 -- Lexical elements -# -# token -# : keyword (raw string) -# | identifier expanded below -# | constant expanded below -# | string_literal expanded below -# | punctuator (raw string) -# -# preprocessing-token (skip) - -# Returns Token -identifier - : ID {result = val[0]} - -# Returns Literal -constant - : ICON {result = val[0].val; result.pos = val[0].pos} - | FCON {result = val[0].val; result.pos = val[0].pos} - #| enumeration_constant -- these are parsed as identifiers at all - # places the `constant' nonterminal appears - | CCON {result = val[0].val; result.pos = val[0].pos} - -# Returns Token -enumeration_constant - : ID {result = val[0]} - -# Returns StringLiteral -# Also handles string literal concatenation (6.4.5.4) -string_literal - : string_literal SCON {val[0].val << val[1].val.val; result = val[0]} - | SCON { result = val[0].val; result.pos = val[0].pos } - ----- inner - # A.1.9 -- Preprocessing numbers -- skip - # A.1.8 -- Header names -- skip - - # A.1.7 -- Puncuators -- we don't bother with {##,#,%:,%:%:} since - # we don't do preprocessing - @@punctuators = %r'\+\+|-[->]|&&|\|\||\.\.\.|(?:<<|>>|[<>=!*/%+\-&^|])=?|[\[\](){}.~?:;,]' - @@digraphs = %r'<[:%]|[:%]>' - - # A.1.6 -- String Literals -- simple for us because we don't decode - # the string (and indeed accept some illegal strings) - @@string_literal = %r'L?"(?:[^\\]|\\.)*?"'m - - # A.1.5 -- Constants - @@decimal_floating_constant = %r'(?:(?:\d*\.\d+|\d+\.)(?:e[-+]?\d+)?|\d+e[-+]?\d+)[fl]?'i - @@hexadecimal_floating_constant = %r'0x(?:(?:[0-9a-f]*\.[0-9a-f]+|[0-9a-f]+\.)|[0-9a-f]+)p[-+]?\d+[fl]?'i - - @@integer_constant = %r'(?:[1-9][0-9]*|0x[0-9a-f]+|0[0-7]*)(?:ul?l?|ll?u?)?'i - @@floating_constant = %r'#{@@decimal_floating_constant}|#{@@hexadecimal_floating_constant}' - @@enumeration_constant = %r'[a-zA-Z_\\][a-zA-Z_\\0-9]*' - @@character_constant = %r"L?'(?:[^\\]|\\.)+?'" - # (note that as with string-literals, we accept some illegal - # character-constants) - - # A.1.4 -- Universal character names -- skip - - # A.1.3 -- Identifiers -- skip, since an identifier is lexically - # identical to an enumeration constant - - # A.1.2 Keywords - keywords = %w'auto break case char const continue default do -double else enum extern float for goto if inline int long register -restrict return short signed sizeof static struct switch typedef union - unsigned void volatile while _Bool _Complex _Imaginary' - @@keywords = %r"#{keywords.join('|')}" - - def initialize - @type_names = ::Set.new - - @warning_proc = lambda{} - @pos = C::Node::Pos.new(nil, 1, 0) - end - def initialize_copy(x) - @pos = x.pos.dup - @type_names = x.type_names.dup - end - attr_accessor :pos, :type_names - - def parse(str) - if str.respond_to? :read - str = str.read - end - @str = str - begin - prepare_lexer(str) - return do_parse - rescue ParseError => e - e.set_backtrace(caller) - raise - end - end - - # - # Error handler, as used by racc. - # - def on_error(error_token_id, error_value, value_stack) - if error_value == '$' - parse_error @pos, "unexpected EOF" - else - parse_error(error_value.pos, - "parse error on #{token_to_str(error_token_id)} (#{error_value.val})") - end - end - - def self.feature(name) - attr_writer "#{name}_enabled" - class_eval <<-EOS - def enable_#{name} - @#{name}_enabled = true - end - def #{name}_enabled? - @#{name}_enabled - end - EOS - end - private_class_method :feature - - # - # Allow blocks in parentheses as expressions, as per the gcc - # extension. [http://rubyurl.com/iB7] - # - feature :block_expressions - - private # --------------------------------------------------------- - - class Token - attr_accessor :pos, :val - def initialize(pos, val) - @pos = pos - @val = val - end - end - def eat(str) - lines = str.split(/\r\n|[\r\n]/, -1) - if lines.length == 1 - @pos.col_num += lines[0].length - else - @pos.line_num += lines.length - 1 - @pos.col_num = lines[-1].length - end - end - - # - # Make a Declaration from the given specs and declarators. - # - def make_declaration(pos, specs, declarators) - specs.all?{|x| x.is_a?(Symbol) || x.is_a?(Type)} or raise specs.map{|x| x.class}.inspect - decl = Declaration.new_at(pos, nil, declarators) - - # set storage class - storage_classes = specs.find_all do |x| - [:typedef, :extern, :static, :auto, :register].include? x - end - # 6.7.1p2: at most, one storage-class specifier may be given in - # the declaration specifiers in a declaration - storage_classes.length <= 1 or - begin - if declarators.length == 0 - for_name = '' - else - for_name = "for `#{declarators[0].name}'" - end - parse_error pos, "multiple or duplicate storage classes given #{for_name}'" - end - decl.storage = storage_classes[0] - - # set type (specifiers, qualifiers) - decl.type = make_direct_type(pos, specs) - - # set function specifiers - decl.inline = specs.include?(:inline) - - # look for new type names - if decl.typedef? - decl.declarators.each do |d| - if d.name - @type_names << d.name - end - end - end - - return decl - end - - def make_function_def(pos, specs, func_declarator, decl_list, defn) - add_decl_type(func_declarator, make_direct_type(pos, specs)) - - # get types from decl_list if necessary - function = func_declarator.indirect_type - function.is_a? Function or - parse_error pos, "non function type for function `#{func_declarator.name}'" - params = function.params - if decl_list - params.all?{|p| p.type.nil?} or - parse_error pos, "both prototype and declaration list given for `#{func_declarator.name}'" - decl_list.each do |declaration| - declaration.declarators.each do |declarator| - param = params.find{|p| p.name == declarator.name} or - parse_error pos, "no parameter named #{declarator.name}" - if declarator.indirect_type - param.type = declarator.indirect_type - param.type.direct_type = declaration.type.dup - else - param.type = declaration.type.dup - end - end - end - params.all?{|p| p.type} or - begin - s = params.find_all{|p| p.type.nil?}.map{|p| "`#{p.name}'"}.join(' and ') - parse_error pos, "types missing for parameters #{s}" - end - end - - fd = FunctionDef.new_at(pos, - function.detach, - func_declarator.name, - defn, - :no_prototype => !decl_list.nil?) - - # set storage class - # 6.9.1p4: only extern or static allowed - specs.each do |s| - [:typedef, :auto, :register].include?(s) and - "`#{s}' illegal for function" - end - storage_classes = specs.find_all do |s| - s == :extern || s == :static - end - # 6.7.1p2: at most, one storage-class specifier may be given in - # the declaration specifiers in a declaration - storage_classes.length <= 1 or - "multiple or duplicate storage classes given for `#{func_declarator.name}'" - fd.storage = storage_classes[0] if storage_classes[0] - - # set function specifiers - # 6.7.4p5 'inline' can be repeated - fd.inline = specs.include?(:inline) - - return fd - end - - # - # Make a direct type from the list of type specifiers and type - # qualifiers. - # - def make_direct_type(pos, specs) - specs_order = [:signed, :unsigned, :short, :long, :double, :void, - :char, :int, :float, :_Bool, :_Complex, :_Imaginary] - - type_specs = specs.find_all do |x| - specs_order.include?(x) || !x.is_a?(Symbol) - end - type_specs.sort! do |a, b| - (specs_order.index(a)||100) <=> (specs_order.index(b)||100) - end - - # set type specifiers - # 6.7.2p2: the specifier list should be one of these - type = - case type_specs - when [:void] - Void.new - when [:char] - Char.new - when [:signed, :char] - Char.new :signed => true - when [:unsigned, :char] - Char.new :signed => false - when [:short], [:signed, :short], [:short, :int], - [:signed, :short, :int] - Int.new :longness => -1 - when [:unsigned, :short], [:unsigned, :short, :int] - Int.new :unsigned => true, :longness => -1 - when [:int], [:signed], [:signed, :int] - Int.new - when [:unsigned], [:unsigned, :int] - Int.new :unsigned => true - when [:long], [:signed, :long], [:long, :int], - [:signed, :long, :int] - Int.new :longness => 1 - when [:unsigned, :long], [:unsigned, :long, :int] - Int.new :longness => 1, :unsigned => true - when [:long, :long], [:signed, :long, :long], - [:long, :long, :int], [:signed, :long, :long, :int] - Int.new :longness => 2 - when [:unsigned, :long, :long], [:unsigned, :long, :long, :int] - Int.new :longness => 2, :unsigned => true - when [:float] - Float.new - when [:double] - Float.new :longness => 1 - when [:long, :double] - Float.new :longness => 2 - when [:_Bool] - Bool.new - when [:float, :_Complex] - Complex.new - when [:double, :_Complex] - Complex.new :longness => 1 - when [:long, :double, :_Complex] - Complex.new :longness => 2 - when [:float, :_Imaginary] - Imaginary.new - when [:double, :_Imaginary] - Imaginary.new :longness => 1 - when [:long, :double, :_Imaginary] - Imaginary.new :longness => 2 - else - if type_specs.length == 1 && - [CustomType, Struct, Union, Enum].any?{|c| type_specs[0].is_a? c} - type_specs[0] - else - if type_specs == [] - parse_error pos, "no type specifiers given" - else - parse_error pos, "invalid type specifier combination: #{type_specs.join(' ')}" - end - end - end - type.pos ||= pos - - # set type qualifiers - # 6.7.3p4: type qualifiers can be repeated - type.const = specs.any?{|x| x.equal? :const } - type.restrict = specs.any?{|x| x.equal? :restrict} - type.volatile = specs.any?{|x| x.equal? :volatile} - - return type - end - - def make_parameter(pos, specs, indirect_type, name) - type = indirect_type - if type - type.direct_type = make_direct_type(pos, specs) - else - type = make_direct_type(pos, specs) - end - [:typedef, :extern, :static, :auto, :inline].each do |sym| - specs.include? sym and - parse_error pos, "parameter `#{declarator.name}' declared `#{sym}'" - end - return Parameter.new_at(pos, type, name, - :register => specs.include?(:register)) - end - - def add_type_quals(type, quals) - type.const = quals.include?(:const ) - type.restrict = quals.include?(:restrict) - type.volatile = quals.include?(:volatile) - return type - end - - # - # Add te given type as the "most direct" type to the given - # declarator. Return the declarator. - # - def add_decl_type(declarator, type) - if declarator.indirect_type - declarator.indirect_type.direct_type = type - else - declarator.indirect_type = type - end - return declarator - end - - def param_list(params, var_args) - if params.length == 1 && - params[0].type.is_a?(Void) && - params[0].name.nil? - return NodeArray[] - elsif params.empty? - return nil - else - return params - end - end - - def parse_error(pos, str) - raise ParseError, "#{pos}: #{str}" - end - ----- header - -require 'set' - -# Error classes -module C - class ParseError < StandardError; end -end - -# Local variables: -# mode: ruby -# end: diff --git a/test/racc/assets/chk.y b/test/racc/assets/chk.y deleted file mode 100644 index 7e0ee20f1e..0000000000 --- a/test/racc/assets/chk.y +++ /dev/null @@ -1,126 +0,0 @@ -# -# racc tester -# - -class Calcp - - prechigh - left '*' '/' - left '+' '-' - preclow - - convert - NUMBER 'Number' - end - -rule - - target : exp | /* none */ { result = 0 } ; - - exp : exp '+' exp { result += val[2]; @plus = 'plus' } - | exp '-' exp { result -= val[2]; @str = "string test" } - | exp '*' exp { result *= val[2] } - | exp '/' exp { result /= val[2] } - | '(' { $emb = true } exp ')' - { - raise 'must not happen' unless $emb - result = val[2] - } - | '-' NUMBER { result = -val[1] } - | NUMBER - ; - -end - -----header - -class Number; end - -----inner - - def parse( src ) - $emb = false - @plus = nil - @str = nil - @src = src - result = do_parse - if @plus - raise 'string parse failed' unless @plus == 'plus' - end - if @str - raise 'string parse failed' unless @str == 'string test' - end - result - end - - def next_token - @src.shift - end - - def initialize - @yydebug = true - end - -----footer - -$parser = Calcp.new -$test_number = 1 - -def chk( src, ans ) - result = $parser.parse(src) - raise "test #{$test_number} fail" unless result == ans - $test_number += 1 -end - -chk( - [ [Number, 9], - [false, false], - [false, false] ], 9 -) - -chk( - [ [Number, 5], - ['*', nil], - [Number, 1], - ['-', nil], - [Number, 1], - ['*', nil], - [Number, 8], - [false, false], - [false, false] ], -3 -) - -chk( - [ [Number, 5], - ['+', nil], - [Number, 2], - ['-', nil], - [Number, 5], - ['+', nil], - [Number, 2], - ['-', nil], - [Number, 5], - [false, false], - [false, false] ], -1 -) - -chk( - [ ['-', nil], - [Number, 4], - [false, false], - [false, false] ], -4 -) - -chk( - [ [Number, 7], - ['*', nil], - ['(', nil], - [Number, 4], - ['+', nil], - [Number, 3], - [')', nil], - ['-', nil], - [Number, 9], - [false, false], - [false, false] ], 40 -) diff --git a/test/racc/assets/conf.y b/test/racc/assets/conf.y deleted file mode 100644 index de9de71d28..0000000000 --- a/test/racc/assets/conf.y +++ /dev/null @@ -1,16 +0,0 @@ - -class A -rule - -a: A c C expr; - -b: A B; # useless - -c: A; -c: A; - -expr: expr '+' expr -expr: expr '-' expr -expr: NUMBER - -end diff --git a/test/racc/assets/csspool.y b/test/racc/assets/csspool.y deleted file mode 100644 index 3d6af25d85..0000000000 --- a/test/racc/assets/csspool.y +++ /dev/null @@ -1,729 +0,0 @@ -class CSSPool::CSS::Parser - -token CHARSET_SYM IMPORT_SYM STRING SEMI IDENT S COMMA LBRACE RBRACE STAR HASH -token LSQUARE RSQUARE EQUAL INCLUDES DASHMATCH LPAREN RPAREN FUNCTION GREATER PLUS -token SLASH NUMBER MINUS LENGTH PERCENTAGE ANGLE TIME FREQ URI -token IMPORTANT_SYM MEDIA_SYM NOT ONLY AND NTH_PSEUDO_CLASS -token DOCUMENT_QUERY_SYM FUNCTION_NO_QUOTE -token TILDE -token PREFIXMATCH SUFFIXMATCH SUBSTRINGMATCH -token NOT_PSEUDO_CLASS -token KEYFRAMES_SYM -token MATCHES_PSEUDO_CLASS -token NAMESPACE_SYM -token MOZ_PSEUDO_ELEMENT -token RESOLUTION -token COLON -token SUPPORTS_SYM -token OR -token VARIABLE_NAME -token CALC_SYM -token FONTFACE_SYM -token UNICODE_RANGE -token RATIO - -rule - document - : { @handler.start_document } - stylesheet - { @handler.end_document } - ; - stylesheet - : charset stylesheet - | import stylesheet - | namespace stylesheet - | charset - | import - | namespace - | body - | - ; - charset - : CHARSET_SYM STRING SEMI { @handler.charset interpret_string(val[1]), {} } - ; - import - : IMPORT_SYM import_location medium SEMI { - @handler.import_style val[2], val[1] - } - | IMPORT_SYM import_location SEMI { - @handler.import_style [], val[1] - } - ; - import_location - : import_location S - | STRING { result = Terms::String.new interpret_string val.first } - | URI { result = Terms::URI.new interpret_uri val.first } - ; - namespace - : NAMESPACE_SYM ident import_location SEMI { - @handler.namespace val[1], val[2] - } - | NAMESPACE_SYM import_location SEMI { - @handler.namespace nil, val[1] - } - ; - medium - : medium COMMA IDENT { - result = val[0] << MediaType.new(val[2]) - } - | IDENT { - result = [MediaType.new(val[0])] - } - ; - media_query_list - : media_query { result = MediaQueryList.new([ val[0] ]) } - | media_query_list COMMA media_query { result = val[0] << val[2] } - | { result = MediaQueryList.new } - ; - media_query - : optional_only_or_not media_type optional_and_exprs { result = MediaQuery.new(val[0], val[1], val[2]) } - | media_expr optional_and_exprs { result = MediaQuery.new(nil, val[0], val[1]) } - ; - optional_only_or_not - : ONLY { result = :only } - | NOT { result = :not } - | { result = nil } - ; - media_type - : IDENT { result = MediaType.new(val[0]) } - ; - media_expr - : LPAREN optional_space IDENT optional_space RPAREN { result = MediaType.new(val[2]) } - | LPAREN optional_space IDENT optional_space COLON optional_space expr RPAREN { result = MediaFeature.new(val[2], val[6][0]) } - ; - optional_space - : S { result = val[0] } - | { result = nil } - ; - optional_and_exprs - : optional_and_exprs AND media_expr { result = val[0] << val[2] } - | { result = [] } - ; - resolution - : RESOLUTION { - unit = val.first.gsub(/[\s\d.]/, '') - number = numeric(val.first) - result = Terms::Resolution.new(number, unit) - } - ; - body - : ruleset body - | conditional_rule body - | keyframes_rule body - | fontface_rule body - | ruleset - | conditional_rule - | keyframes_rule - | fontface_rule - ; - conditional_rule - : media - | document_query - | supports - ; - body_in_media - : body - | empty_ruleset - ; - media - : start_media body_in_media RBRACE { @handler.end_media val.first } - ; - start_media - : MEDIA_SYM media_query_list LBRACE { - result = val[1] - @handler.start_media result - } - ; - document_query - : start_document_query body RBRACE { @handler.end_document_query(before_pos(val), after_pos(val)) } - | start_document_query RBRACE { @handler.end_document_query(before_pos(val), after_pos(val)) } - ; - start_document_query - : start_document_query_pos url_match_fns LBRACE { - @handler.start_document_query(val[1], after_pos(val)) - } - ; - start_document_query_pos - : DOCUMENT_QUERY_SYM { - @handler.node_start_pos = before_pos(val) - } - ; - url_match_fns - : url_match_fn COMMA url_match_fns { - result = [val[0], val[2]].flatten - } - | url_match_fn { - result = val - } - ; - url_match_fn - : function_no_quote - | function - | uri - ; - supports - : start_supports body RBRACE { @handler.end_supports } - | start_supports RBRACE { @handler.end_supports } - ; - start_supports - : SUPPORTS_SYM supports_condition_root LBRACE { - @handler.start_supports val[1] - } - ; - supports_condition_root - : supports_negation { result = val.join('') } - | supports_conjunction_or_disjunction { result = val.join('') } - | supports_condition_in_parens { result = val.join('') } - ; - supports_condition - : supports_negation { result = val.join('') } - | supports_conjunction_or_disjunction { result = val.join('') } - | supports_condition_in_parens { result = val.join('') } - ; - supports_condition_in_parens - : LPAREN supports_condition RPAREN { result = val.join('') } - | supports_declaration_condition { result = val.join('') } - ; - supports_negation - : NOT supports_condition_in_parens { result = val.join('') } - ; - supports_conjunction_or_disjunction - : supports_conjunction - | supports_disjunction - ; - supports_conjunction - : supports_condition_in_parens AND supports_condition_in_parens { result = val.join('') } - | supports_conjunction_or_disjunction AND supports_condition_in_parens { result = val.join('') } - ; - supports_disjunction - : supports_condition_in_parens OR supports_condition_in_parens { result = val.join('') } - | supports_conjunction_or_disjunction OR supports_condition_in_parens { result = val.join('') } - ; - supports_declaration_condition - : LPAREN declaration_internal RPAREN { result = val.join('') } - | LPAREN S declaration_internal RPAREN { result = val.join('') } - ; - keyframes_rule - : start_keyframes_rule keyframes_blocks RBRACE - | start_keyframes_rule RBRACE - ; - start_keyframes_rule - : KEYFRAMES_SYM IDENT LBRACE { - @handler.start_keyframes_rule val[1] - } - ; - keyframes_blocks - : keyframes_block keyframes_blocks - | keyframes_block - ; - keyframes_block - : start_keyframes_block declarations RBRACE { @handler.end_keyframes_block } - | start_keyframes_block RBRACE { @handler.end_keyframes_block } - ; - start_keyframes_block - : keyframes_selectors LBRACE { - @handler.start_keyframes_block val[0] - } - ; - keyframes_selectors - | keyframes_selector COMMA keyframes_selectors { - result = val[0] + ', ' + val[2] - } - | keyframes_selector - ; - keyframes_selector - : IDENT - | PERCENTAGE { result = val[0].strip } - ; - fontface_rule - : start_fontface_rule declarations RBRACE { @handler.end_fontface_rule } - | start_fontface_rule RBRACE { @handler.end_fontface_rule } - ; - start_fontface_rule - : FONTFACE_SYM LBRACE { - @handler.start_fontface_rule - } - ; - ruleset - : start_selector declarations RBRACE { - @handler.end_selector val.first - } - | start_selector RBRACE { - @handler.end_selector val.first - } - ; - empty_ruleset - : optional_space { - start = @handler.start_selector([]) - @handler.end_selector(start) - } - ; - start_selector - : S start_selector { result = val.last } - | selectors LBRACE { - @handler.start_selector val.first - } - ; - selectors - : selector COMMA selectors - { - sel = Selector.new(val.first, {}) - result = [sel].concat(val[2]) - } - | selector - { - result = [Selector.new(val.first, {})] - } - ; - selector - : simple_selector combinator selector - { - val.flatten! - val[2].combinator = val.delete_at 1 - result = val - } - | simple_selector - ; - combinator - : S { result = :s } - | GREATER { result = :> } - | PLUS { result = :+ } - | TILDE { result = :~ } - ; - simple_selector - : element_name hcap { - selector = val.first - selector.additional_selectors = val.last - result = [selector] - } - | element_name { result = val } - | hcap - { - ss = Selectors::Simple.new nil, nil - ss.additional_selectors = val.flatten - result = [ss] - } - ; - simple_selectors - : simple_selector COMMA simple_selectors { result = [val[0], val[2]].flatten } - | simple_selector - ; - ident_with_namespace - : IDENT { result = [interpret_identifier(val[0]), nil] } - | IDENT '|' IDENT { result = [interpret_identifier(val[2]), interpret_identifier(val[0])] } - | '|' IDENT { result = [interpret_identifier(val[1]), nil] } - | STAR '|' IDENT { result = [interpret_identifier(val[2]), '*'] } - ; - element_name - : ident_with_namespace { result = Selectors::Type.new val.first[0], nil, val.first[1] } - | STAR { result = Selectors::Universal.new val.first } - | '|' STAR { result = Selectors::Universal.new val[1] } - | STAR '|' STAR { result = Selectors::Universal.new val[2], nil, val[0] } - | IDENT '|' STAR { result = Selectors::Universal.new val[2], nil, interpret_identifier(val[0]) } - ; - hcap - : hash { result = val } - | class { result = val } - | attrib { result = val } - | pseudo { result = val } - | hash hcap { result = val.flatten } - | class hcap { result = val.flatten } - | attrib hcap { result = val.flatten } - | pseudo hcap { result = val.flatten } - ; - hash - : HASH { - result = Selectors::Id.new interpret_identifier val.first.sub(/^#/, '') - } - class - : '.' IDENT { - result = Selectors::Class.new interpret_identifier val.last - } - ; - attrib - : LSQUARE ident_with_namespace EQUAL IDENT RSQUARE { - result = Selectors::Attribute.new( - val[1][0], - interpret_identifier(val[3]), - Selectors::Attribute::EQUALS, - val[1][1] - ) - } - | LSQUARE ident_with_namespace EQUAL STRING RSQUARE { - result = Selectors::Attribute.new( - val[1][0], - interpret_string(val[3]), - Selectors::Attribute::EQUALS, - val[1][1] - ) - } - | LSQUARE ident_with_namespace INCLUDES STRING RSQUARE { - result = Selectors::Attribute.new( - val[1][0], - interpret_string(val[3]), - Selectors::Attribute::INCLUDES, - val[1][1] - ) - } - | LSQUARE ident_with_namespace INCLUDES IDENT RSQUARE { - result = Selectors::Attribute.new( - val[1][0], - interpret_identifier(val[3]), - Selectors::Attribute::INCLUDES, - val[1][1] - ) - } - | LSQUARE ident_with_namespace DASHMATCH IDENT RSQUARE { - result = Selectors::Attribute.new( - val[1][0], - interpret_identifier(val[3]), - Selectors::Attribute::DASHMATCH, - val[1][1] - ) - } - | LSQUARE ident_with_namespace DASHMATCH STRING RSQUARE { - result = Selectors::Attribute.new( - val[1][0], - interpret_string(val[3]), - Selectors::Attribute::DASHMATCH, - val[1][1] - ) - } - | LSQUARE ident_with_namespace PREFIXMATCH IDENT RSQUARE { - result = Selectors::Attribute.new( - val[1][0], - interpret_identifier(val[3]), - Selectors::Attribute::PREFIXMATCH, - val[1][1] - ) - } - | LSQUARE ident_with_namespace PREFIXMATCH STRING RSQUARE { - result = Selectors::Attribute.new( - val[1][0], - interpret_string(val[3]), - Selectors::Attribute::PREFIXMATCH, - val[1][1] - ) - } - | LSQUARE ident_with_namespace SUFFIXMATCH IDENT RSQUARE { - result = Selectors::Attribute.new( - val[1][0], - interpret_identifier(val[3]), - Selectors::Attribute::SUFFIXMATCH, - val[1][1] - ) - } - | LSQUARE ident_with_namespace SUFFIXMATCH STRING RSQUARE { - result = Selectors::Attribute.new( - val[1][0], - interpret_string(val[3]), - Selectors::Attribute::SUFFIXMATCH, - val[1][1] - ) - } - | LSQUARE ident_with_namespace SUBSTRINGMATCH IDENT RSQUARE { - result = Selectors::Attribute.new( - val[1][0], - interpret_identifier(val[3]), - Selectors::Attribute::SUBSTRINGMATCH, - val[1][1] - ) - } - | LSQUARE ident_with_namespace SUBSTRINGMATCH STRING RSQUARE { - result = Selectors::Attribute.new( - val[1][0], - interpret_string(val[3]), - Selectors::Attribute::SUBSTRINGMATCH, - val[1][1] - ) - } - | LSQUARE ident_with_namespace RSQUARE { - result = Selectors::Attribute.new( - val[1][0], - nil, - Selectors::Attribute::SET, - val[1][1] - ) - } - ; - pseudo - : COLON IDENT { - result = Selectors::pseudo interpret_identifier(val[1]) - } - | COLON COLON IDENT { - result = Selectors::PseudoElement.new( - interpret_identifier(val[2]) - ) - } - | COLON FUNCTION RPAREN { - result = Selectors::PseudoClass.new( - interpret_identifier(val[1].sub(/\($/, '')), - '' - ) - } - | COLON FUNCTION IDENT RPAREN { - result = Selectors::PseudoClass.new( - interpret_identifier(val[1].sub(/\($/, '')), - interpret_identifier(val[2]) - ) - } - | COLON NOT_PSEUDO_CLASS simple_selector RPAREN { - result = Selectors::PseudoClass.new( - 'not', - val[2].first.to_s - ) - } - | COLON NTH_PSEUDO_CLASS { - result = Selectors::PseudoClass.new( - interpret_identifier(val[1].sub(/\(.*/, '')), - interpret_identifier(val[1].sub(/.*\(/, '').sub(/\).*/, '')) - ) - } - | COLON MATCHES_PSEUDO_CLASS simple_selectors RPAREN { - result = Selectors::PseudoClass.new( - val[1].split('(').first.strip, - val[2].join(', ') - ) - } - | COLON MOZ_PSEUDO_ELEMENT optional_space any_number_of_idents optional_space RPAREN { - result = Selectors::PseudoElement.new( - interpret_identifier(val[1].sub(/\($/, '')) - ) - } - | COLON COLON MOZ_PSEUDO_ELEMENT optional_space any_number_of_idents optional_space RPAREN { - result = Selectors::PseudoElement.new( - interpret_identifier(val[2].sub(/\($/, '')) - ) - } - ; - any_number_of_idents - : - | multiple_idents - ; - multiple_idents - : IDENT - | IDENT COMMA multiple_idents - ; - # declarations can be separated by one *or more* semicolons. semi-colons at the start or end of a ruleset are also allowed - one_or_more_semis - : SEMI - | SEMI one_or_more_semis - ; - declarations - : declaration one_or_more_semis declarations - | one_or_more_semis declarations - | declaration one_or_more_semis - | declaration - | one_or_more_semis - ; - declaration - : declaration_internal { @handler.property val.first } - ; - declaration_internal - : property COLON expr prio - { result = Declaration.new(val.first, val[2], val[3]) } - | property COLON S expr prio - { result = Declaration.new(val.first, val[3], val[4]) } - | property S COLON expr prio - { result = Declaration.new(val.first, val[3], val[4]) } - | property S COLON S expr prio - { result = Declaration.new(val.first, val[4], val[5]) } - ; - prio - : IMPORTANT_SYM { result = true } - | { result = false } - ; - property - : IDENT { result = interpret_identifier val[0] } - | STAR IDENT { result = interpret_identifier val.join } - | VARIABLE_NAME { result = interpret_identifier val[0] } - ; - operator - : COMMA - | SLASH - | EQUAL - ; - expr - : term operator expr { - result = [val.first, val.last].flatten - val.last.first.operator = val[1] - } - | term expr { result = val.flatten } - | term { result = val } - ; - term - : ident - | ratio - | numeric - | string - | uri - | hexcolor - | calc - | function - | resolution - | VARIABLE_NAME - | uranges - ; - function - : function S { result = val.first } - | FUNCTION expr RPAREN { - name = interpret_identifier val.first.sub(/\($/, '') - if name == 'rgb' - result = Terms::Rgb.new(*val[1]) - else - result = Terms::Function.new name, val[1] - end - } - | FUNCTION RPAREN { - name = interpret_identifier val.first.sub(/\($/, '') - result = Terms::Function.new name - } - ; - function_no_quote - : function_no_quote S { result = val.first } - | FUNCTION_NO_QUOTE { - parts = val.first.split('(') - name = interpret_identifier parts.first - result = Terms::Function.new(name, [Terms::String.new(interpret_string_no_quote(parts.last))]) - } - ; - uranges - : UNICODE_RANGE COMMA uranges - | UNICODE_RANGE - ; - calc - : CALC_SYM calc_sum RPAREN optional_space { - result = Terms::Math.new(val.first.split('(').first, val[1]) - } - ; - # plus and minus are supposed to have whitespace around them, per http://dev.w3.org/csswg/css-values/#calc-syntax, but the numbers are eating trailing whitespace, so we inject it back in - calc_sum - : calc_product - | calc_product PLUS calc_sum { val.insert(1, ' '); result = val.join('') } - | calc_product MINUS calc_sum { val.insert(1, ' '); result = val.join('') } - ; - calc_product - : calc_value - | calc_value optional_space STAR calc_value { result = val.join('') } - | calc_value optional_space SLASH calc_value { result = val.join('') } - ; - calc_value - : numeric { result = val.join('') } - | function { result = val.join('') } # for var() variable references - | LPAREN calc_sum RPAREN { result = val.join('') } - ; - hexcolor - : hexcolor S { result = val.first } - | HASH { result = Terms::Hash.new val.first.sub(/^#/, '') } - ; - uri - : uri S { result = val.first } - | URI { result = Terms::URI.new interpret_uri val.first } - ; - string - : string S { result = val.first } - | STRING { result = Terms::String.new interpret_string val.first } - ; - numeric - : unary_operator numeric { - result = val[1] - val[1].unary_operator = val.first - } - | NUMBER { - result = Terms::Number.new numeric val.first - } - | PERCENTAGE { - result = Terms::Number.new numeric(val.first), nil, '%' - } - | LENGTH { - unit = val.first.gsub(/[\s\d.]/, '') - result = Terms::Number.new numeric(val.first), nil, unit - } - | ANGLE { - unit = val.first.gsub(/[\s\d.]/, '') - result = Terms::Number.new numeric(val.first), nil, unit - } - | TIME { - unit = val.first.gsub(/[\s\d.]/, '') - result = Terms::Number.new numeric(val.first), nil, unit - } - | FREQ { - unit = val.first.gsub(/[\s\d.]/, '') - result = Terms::Number.new numeric(val.first), nil, unit - } - ; - ratio - : RATIO { - result = Terms::Ratio.new(val[0], val[1]) - } - ; - unary_operator - : MINUS { result = :minus } - | PLUS { result = :plus } - ; - ident - : ident S { result = val.first } - | IDENT { result = Terms::Ident.new interpret_identifier val.first } - ; - ----- inner - -def numeric thing - thing = thing.gsub(/[^\d.]/, '') - Integer(thing) rescue Float(thing) -end - -def interpret_identifier s - interpret_escapes s -end - -def interpret_uri s - interpret_escapes s.match(/^url\((.*)\)$/mui)[1].strip.match(/^(['"]?)((?:\\.|.)*)\1$/mu)[2] -end - -def interpret_string_no_quote s - interpret_escapes s.match(/^(.*)\)$/mu)[1].strip.match(/^(['"]?)((?:\\.|.)*)\1$/mu)[2] -end - -def interpret_string s - interpret_escapes s.match(/^(['"])((?:\\.|.)*)\1$/mu)[2] -end - -def interpret_escapes s - token_exp = /\\(?:([0-9a-fA-F]{1,6}(?:\r\n|\s)?)|(.))/mu - return s.gsub(token_exp) do |escape_sequence| - if !$1.nil? - code = $1.chomp.to_i 16 - code = 0xFFFD if code > 0x10FFFF - next [code].pack('U') - end - next '' if $2 == "\n" - next $2 - end -end - -# override racc's on_error so we can have context in our error messages -def on_error(t, val, vstack) - errcontext = (@ss.pre_match[-10..-1] || @ss.pre_match) + - @ss.matched + @ss.post_match[0..9] - line_number = @ss.pre_match.lines.count - raise ParseError, sprintf("parse error on value %s (%s) " + - "on line %s around \"%s\"", - val.inspect, token_to_str(t) || '?', - line_number, errcontext) -end - -def before_pos(val) - # don't include leading whitespace - return current_pos - val.last.length + val.last[/\A\s*/].size -end - -def after_pos(val) - # don't include trailing whitespace - return current_pos - val.last[/\s*\z/].size -end - -# charpos will work with multibyte strings but is not available until ruby 2 -def current_pos - @ss.respond_to?('charpos') ? @ss.charpos : @ss.pos -end diff --git a/test/racc/assets/digraph.y b/test/racc/assets/digraph.y deleted file mode 100644 index 17a034ee54..0000000000 --- a/test/racc/assets/digraph.y +++ /dev/null @@ -1,29 +0,0 @@ -# ? detect digraph bug - -class P - token A B C D -rule - target : a b c d - a : A - | - b : B - | - c : C - | - d : D - | -end - ----- inner - - def parse - do_parse - end - - def next_token - [false, '$'] - end - ----- footer - -P.new.parse diff --git a/test/racc/assets/echk.y b/test/racc/assets/echk.y deleted file mode 100644 index 0fda2685aa..0000000000 --- a/test/racc/assets/echk.y +++ /dev/null @@ -1,118 +0,0 @@ -# -# racc tester -# - -class Calcp - - prechigh - left '*' '/' - left '+' '-' - preclow - - convert - NUMBER 'Number' - end - -rule - - target : exp | /* none */ { result = 0 } ; - - exp : exp '+' exp { result += val[2]; a = 'plus' } - | exp '-' exp { result -= val[2]; "string test" } - | exp '*' exp { result *= val[2] } - | exp '/' exp { result /= val[2] } - | '(' { $emb = true } exp ')' - { - raise 'must not happen' unless $emb - result = val[2] - } - | '-' NUMBER { result = -val[1] } - | NUMBER - ; - -end - -----header - -class Number ; end - -----inner - - def parse( src ) - @src = src - do_parse - end - - def next_token - @src.shift - end - - def initialize - @yydebug = true - end - -----footer - -$parser = Calcp.new -$tidx = 1 - -def chk( src, ans ) - ret = $parser.parse( src ) - unless ret == ans then - bug! "test #{$tidx} fail" - end - $tidx += 1 -end - -chk( - [ [Number, 9], - [false, false], - [false, false] ], 9 -) - -chk( - [ [Number, 5], - ['*', nil], - [Number, 1], - ['-', nil], - [Number, 1], - ['*', nil], - [Number, 8], - [false, false], - [false, false] ], -3 -) - -chk( - [ [Number, 5], - ['+', nil], - [Number, 2], - ['-', nil], - [Number, 5], - ['+', nil], - [Number, 2], - ['-', nil], - [Number, 5], - [false, false], - [false, false] ], -1 -) - -chk( - [ ['-', nil], - [Number, 4], - [false, false], - [false, false] ], -4 -) - -chk( - [ [Number, 7], - ['*', nil], - ['(', nil], - [Number, 4], - ['+', nil], - [Number, 3], - [')', nil], - ['-', nil], - [Number, 9], - [false, false], - [false, false] ], 40 -) diff --git a/test/racc/assets/edtf.y b/test/racc/assets/edtf.y deleted file mode 100644 index 4f5f6bb4fd..0000000000 --- a/test/racc/assets/edtf.y +++ /dev/null @@ -1,583 +0,0 @@ -# -*- racc -*- - -# Copyright 2011 Sylvester Keil. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY EXPRESS OR -# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO -# EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY -# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# The views and conclusions contained in the software and documentation are -# those of the authors and should not be interpreted as representing official -# policies, either expressed or implied, of the copyright holder. - -class EDTF::Parser - -token T Z E X U UNKNOWN OPEN LONGYEAR UNMATCHED DOTS UA PUA - -expect 0 - -rule - - edtf : level_0_expression - | level_1_expression - | level_2_expression - ; - - # ---- Level 0 / ISO 8601 Rules ---- - - # NB: level 0 intervals are covered by the level 1 interval rules - level_0_expression : date - | date_time - ; - - date : positive_date - | negative_date - ; - - positive_date : - year { result = Date.new(val[0]).year_precision! } - | year_month { result = Date.new(*val.flatten).month_precision! } - | year_month_day { result = Date.new(*val.flatten).day_precision! } - ; - - negative_date : '-' positive_date { result = -val[1] } - - - date_time : date T time { - result = DateTime.new(val[0].year, val[0].month, val[0].day, *val[2]) - result.skip_timezone = (val[2].length == 3) - } - - time : base_time - | base_time zone_offset { result = val.flatten } - - base_time : hour ':' minute ':' second { result = val.values_at(0, 2, 4) } - | midnight - - midnight : '2' '4' ':' '0' '0' ':' '0' '0' { result = [24, 0, 0] } - - zone_offset : Z { result = 0 } - | '-' zone_offset_hour { result = -1 * val[1] } - | '+' positive_zone_offset { result = val[1] } - ; - - positive_zone_offset : zone_offset_hour - | '0' '0' ':' '0' '0' { result = 0 } - ; - - - zone_offset_hour : d01_13 ':' minute { result = Rational(val[0] * 60 + val[2], 1440) } - | '1' '4' ':' '0' '0' { result = Rational(840, 1440) } - | '0' '0' ':' d01_59 { result = Rational(val[3], 1440) } - ; - - year : digit digit digit digit { - result = val.zip([1000,100,10,1]).reduce(0) { |s,(a,b)| s += a * b } - } - - month : d01_12 - day : d01_31 - - year_month : year '-' month { result = [val[0], val[2]] } - - # We raise an exception if there are two many days for the month, but - # do not consider leap years, as the EDTF BNF did not either. - # NB: an exception will be raised regardless, because the Ruby Date - # implementation calculates leap years. - year_month_day : year_month '-' day { - result = val[0] << val[2] - if result[2] > 31 || (result[2] > 30 && [2,4,6,9,11].include?(result[1])) || (result[2] > 29 && result[1] == 2) - raise ArgumentError, "invalid date (invalid days #{result[2]} for month #{result[1]})" - end - } - - hour : d00_23 - minute : d00_59 - second : d00_59 - - # Completely covered by level_1_interval - # level_0_interval : date '/' date { result = Interval.new(val[0], val[1]) } - - - # ---- Level 1 Extension Rules ---- - - # NB: Uncertain/approximate Dates are covered by the Level 2 rules - level_1_expression : unspecified | level_1_interval | long_year_simple | season - - # uncertain_or_approximate_date : date UA { result = uoa(val[0], val[1]) } - - unspecified : unspecified_year - { - result = Date.new(val[0][0]).year_precision! - result.unspecified.year[2,2] = val[0][1] - } - | unspecified_month - | unspecified_day - | unspecified_day_and_month - ; - - unspecified_year : - digit digit digit U - { - result = [val[0,3].zip([1000,100,10]).reduce(0) { |s,(a,b)| s += a * b }, [false,true]] - } - | digit digit U U - { - result = [val[0,2].zip([1000,100]).reduce(0) { |s,(a,b)| s += a * b }, [true, true]] - } - - unspecified_month : year '-' U U { - result = Date.new(val[0]).unspecified!(:month) - result.precision = :month - } - - unspecified_day : year_month '-' U U { - result = Date.new(*val[0]).unspecified!(:day) - } - - unspecified_day_and_month : year '-' U U '-' U U { - result = Date.new(val[0]).unspecified!([:day,:month]) - } - - - level_1_interval : level_1_start '/' level_1_end { - result = Interval.new(val[0], val[2]) - } - - level_1_start : date | partial_uncertain_or_approximate | unspecified | partial_unspecified | UNKNOWN - - level_1_end : level_1_start | OPEN - - - long_year_simple : - LONGYEAR long_year - { - result = Date.new(val[1]) - result.precision = :year - } - | LONGYEAR '-' long_year - { - result = Date.new(-1 * val[2]) - result.precision = :year - } - ; - - long_year : - positive_digit digit digit digit digit { - result = val.zip([10000,1000,100,10,1]).reduce(0) { |s,(a,b)| s += a * b } - } - | long_year digit { result = 10 * val[0] + val[1] } - ; - - - season : year '-' season_number ua { - result = Season.new(val[0], val[2]) - val[3].each { |ua| result.send(ua) } - } - - season_number : '2' '1' { result = 21 } - | '2' '2' { result = 22 } - | '2' '3' { result = 23 } - | '2' '4' { result = 24 } - ; - - - # ---- Level 2 Extension Rules ---- - - # NB: Level 2 Intervals are covered by the Level 1 Interval rules. - level_2_expression : season_qualified - | partial_uncertain_or_approximate - | partial_unspecified - | choice_list - | inclusive_list - | masked_precision - | date_and_calendar - | long_year_scientific - ; - - - season_qualified : season '^' { result = val[0]; result.qualifier = val[1] } - - - long_year_scientific : - long_year_simple E integer - { - result = Date.new(val[0].year * 10 ** val[2]).year_precision! - } - | LONGYEAR int1_4 E integer - { - result = Date.new(val[1] * 10 ** val[3]).year_precision! - } - | LONGYEAR '-' int1_4 E integer - { - result = Date.new(-1 * val[2] * 10 ** val[4]).year_precision! - } - ; - - - date_and_calendar : date '^' { result = val[0]; result.calendar = val[1] } - - - masked_precision : - digit digit digit X - { - d = val[0,3].zip([1000,100,10]).reduce(0) { |s,(a,b)| s += a * b } - result = EDTF::Decade.new(d) - } - | digit digit X X - { - d = val[0,2].zip([1000,100]).reduce(0) { |s,(a,b)| s += a * b } - result = EDTF::Century.new(d) - } - ; - - - choice_list : '[' list ']' { result = val[1].choice! } - - inclusive_list : '{' list '}' { result = val[1] } - - list : earlier { result = EDTF::Set.new(val[0]).earlier! } - | earlier ',' list_elements ',' later { result = EDTF::Set.new([val[0]] + val[2] + [val[4]]).earlier!.later! } - | earlier ',' list_elements { result = EDTF::Set.new([val[0]] + val[2]).earlier! } - | earlier ',' later { result = EDTF::Set.new([val[0]] + [val[2]]).earlier!.later! } - | list_elements ',' later { result = EDTF::Set.new(val[0] + [val[2]]).later! } - | list_elements { result = EDTF::Set.new(*val[0]) } - | later { result = EDTF::Set.new(val[0]).later! } - ; - - list_elements : list_element { result = [val[0]].flatten } - | list_elements ',' list_element { result = val[0] + [val[2]].flatten } - ; - - list_element : atomic - | consecutives - ; - - atomic : date - | partial_uncertain_or_approximate - | unspecified - ; - - earlier : DOTS date { result = val[1] } - - later : year_month_day DOTS { result = Date.new(*val[0]).year_precision! } - | year_month DOTS { result = Date.new(*val[0]).month_precision! } - | year DOTS { result = Date.new(val[0]).year_precision! } - ; - - consecutives : year_month_day DOTS year_month_day { result = (Date.new(val[0]).day_precision! .. Date.new(val[2]).day_precision!) } - | year_month DOTS year_month { result = (Date.new(val[0]).month_precision! .. Date.new(val[2]).month_precision!) } - | year DOTS year { result = (Date.new(val[0]).year_precision! .. Date.new(val[2]).year_precision!) } - ; - - partial_unspecified : - unspecified_year '-' month '-' day - { - result = Date.new(val[0][0], val[2], val[4]) - result.unspecified.year[2,2] = val[0][1] - } - | unspecified_year '-' U U '-' day - { - result = Date.new(val[0][0], 1, val[5]) - result.unspecified.year[2,2] = val[0][1] - result.unspecified!(:month) - } - | unspecified_year '-' U U '-' U U - { - result = Date.new(val[0][0], 1, 1) - result.unspecified.year[2,2] = val[0][1] - result.unspecified!([:month, :day]) - } - | unspecified_year '-' month '-' U U - { - result = Date.new(val[0][0], val[2], 1) - result.unspecified.year[2,2] = val[0][1] - result.unspecified!(:day) - } - | year '-' U U '-' day - { - result = Date.new(val[0], 1, val[5]) - result.unspecified!(:month) - } - ; - - - partial_uncertain_or_approximate : pua_base - | '(' pua_base ')' UA { result = uoa(val[1], val[3]) } - - pua_base : - pua_year { result = val[0].year_precision! } - | pua_year_month { result = val[0][0].month_precision! } - | pua_year_month_day { result = val[0].day_precision! } - - pua_year : year UA { result = uoa(Date.new(val[0]), val[1], :year) } - - pua_year_month : - pua_year '-' month ua { - result = [uoa(val[0].change(:month => val[2]), val[3], [:month, :year])] - } - | year '-' month UA { - result = [uoa(Date.new(val[0], val[2]), val[3], [:year, :month])] - } - | year '-(' month ')' UA { - result = [uoa(Date.new(val[0], val[2]), val[4], [:month]), true] - } - | pua_year '-(' month ')' UA { - result = [uoa(val[0].change(:month => val[2]), val[4], [:month]), true] - } - ; - - pua_year_month_day : - pua_year_month '-' day ua { - result = uoa(val[0][0].change(:day => val[2]), val[3], val[0][1] ? [:day] : nil) - } - | pua_year_month '-(' day ')' UA { - result = uoa(val[0][0].change(:day => val[2]), val[4], [:day]) - } - | year '-(' month ')' UA day ua { - result = uoa(uoa(Date.new(val[0], val[2], val[5]), val[4], :month), val[6], :day) - } - | year_month '-' day UA { - result = uoa(Date.new(val[0][0], val[0][1], val[2]), val[3]) - } - | year_month '-(' day ')' UA { - result = uoa(Date.new(val[0][0], val[0][1], val[2]), val[4], [:day]) - } - | year '-(' month '-' day ')' UA { - result = uoa(Date.new(val[0], val[2], val[4]), val[6], [:month, :day]) - } - | year '-(' month '-(' day ')' UA ')' UA { - result = Date.new(val[0], val[2], val[4]) - result = uoa(result, val[6], [:day]) - result = uoa(result, val[8], [:month, :day]) - } - | pua_year '-(' month '-' day ')' UA { - result = val[0].change(:month => val[2], :day => val[4]) - result = uoa(result, val[6], [:month, :day]) - } - | pua_year '-(' month '-(' day ')' UA ')' UA { - result = val[0].change(:month => val[2], :day => val[4]) - result = uoa(result, val[6], [:day]) - result = uoa(result, val[8], [:month, :day]) - } - # | '(' pua_year '-(' month ')' UA ')' UA '-' day ua { - # result = val[1].change(:month => val[3], :day => val[9]) - # result = uoa(result, val[5], [:month]) - # result = [uoa(result, val[7], [:year]), true] - # } - ; - - ua : { result = [] } | UA - - # ---- Auxiliary Rules ---- - - digit : '0' { result = 0 } - | positive_digit - ; - - positive_digit : '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' - - d01_12 : '0' positive_digit { result = val[1] } - | '1' '0' { result = 10 } - | '1' '1' { result = 11 } - | '1' '2' { result = 12 } - ; - - d01_13 : d01_12 - | '1' '3' { result = 13 } - ; - - d01_23 : '0' positive_digit { result = val[1] } - | '1' digit { result = 10 + val[1] } - | '2' '0' { result = 20 } - | '2' '1' { result = 21 } - | '2' '2' { result = 22 } - | '2' '3' { result = 23 } - ; - - d00_23 : '0' '0' - | d01_23 - ; - - d01_29 : d01_23 - | '2' '4' { result = 24 } - | '2' '5' { result = 25 } - | '2' '6' { result = 26 } - | '2' '7' { result = 27 } - | '2' '8' { result = 28 } - | '2' '9' { result = 29 } - ; - - d01_30 : d01_29 - | '3' '0' { result = 30 } - ; - - d01_31 : d01_30 - | '3' '1' { result = 31 } - ; - - d01_59 : d01_29 - | '3' digit { result = 30 + val[1] } - | '4' digit { result = 40 + val[1] } - | '5' digit { result = 50 + val[1] } - ; - - d00_59 : '0' '0' - | d01_59 - ; - - int1_4 : positive_digit { result = val[0] } - | positive_digit digit { result = 10 * val[0] + val[1] } - | positive_digit digit digit - { - result = val.zip([100,10,1]).reduce(0) { |s,(a,b)| s += a * b } - } - | positive_digit digit digit digit - { - result = val.zip([1000,100,10,1]).reduce(0) { |s,(a,b)| s += a * b } - } - ; - - integer : positive_digit { result = val[0] } - | integer digit { result = 10 * val[0] + val[1] } - ; - - - ----- header -require 'strscan' - ----- inner - - @defaults = { - :level => 2, - :debug => false - }.freeze - - class << self; attr_reader :defaults; end - - attr_reader :options - - def initialize(options = {}) - @options = Parser.defaults.merge(options) - end - - def debug? - !!(options[:debug] || ENV['DEBUG']) - end - - def parse(input) - parse!(input) - rescue => e - warn e.message if debug? - nil - end - - def parse!(input) - @yydebug = debug? - @src = StringScanner.new(input) - do_parse - end - - def on_error(tid, value, stack) - raise ArgumentError, - "failed to parse date: unexpected '#{value}' at #{stack.inspect}" - end - - def apply_uncertainty(date, uncertainty, scope = nil) - uncertainty.each do |u| - scope.nil? ? date.send(u) : date.send(u, scope) - end - date - end - - alias uoa apply_uncertainty - - def next_token - case - when @src.eos? - nil - # when @src.scan(/\s+/) - # ignore whitespace - when @src.scan(/\(/) - ['(', @src.matched] - # when @src.scan(/\)\?~-/) - # [:PUA, [:uncertain!, :approximate!]] - # when @src.scan(/\)\?-/) - # [:PUA, [:uncertain!]] - # when @src.scan(/\)~-/) - # [:PUA, [:approximate!]] - when @src.scan(/\)/) - [')', @src.matched] - when @src.scan(/\[/) - ['[', @src.matched] - when @src.scan(/\]/) - [']', @src.matched] - when @src.scan(/\{/) - ['{', @src.matched] - when @src.scan(/\}/) - ['}', @src.matched] - when @src.scan(/T/) - [:T, @src.matched] - when @src.scan(/Z/) - [:Z, @src.matched] - when @src.scan(/\?~/) - [:UA, [:uncertain!, :approximate!]] - when @src.scan(/\?/) - [:UA, [:uncertain!]] - when @src.scan(/~/) - [:UA, [:approximate!]] - when @src.scan(/open/i) - [:OPEN, :open] - when @src.scan(/unkn?own/i) # matches 'unkown' typo too - [:UNKNOWN, :unknown] - when @src.scan(/u/) - [:U, @src.matched] - when @src.scan(/x/i) - [:X, @src.matched] - when @src.scan(/y/) - [:LONGYEAR, @src.matched] - when @src.scan(/e/) - [:E, @src.matched] - when @src.scan(/\+/) - ['+', @src.matched] - when @src.scan(/-\(/) - ['-(', @src.matched] - when @src.scan(/-/) - ['-', @src.matched] - when @src.scan(/:/) - [':', @src.matched] - when @src.scan(/\//) - ['/', @src.matched] - when @src.scan(/\s*\.\.\s*/) - [:DOTS, '..'] - when @src.scan(/\s*,\s*/) - [',', ','] - when @src.scan(/\^\w+/) - ['^', @src.matched[1..-1]] - when @src.scan(/\d/) - [@src.matched, @src.matched.to_i] - else @src.scan(/./) - [:UNMATCHED, @src.rest] - end - end - - -# -*- racc -*- diff --git a/test/racc/assets/err.y b/test/racc/assets/err.y deleted file mode 100644 index ae280957cc..0000000000 --- a/test/racc/assets/err.y +++ /dev/null @@ -1,60 +0,0 @@ - -class ErrTestp - -rule - -target: lines - ; - -lines: line - | lines line - ; - -line: A B C D E - | error E - ; - -end - ----- inner - -def initialize - @yydebug = false - @q = [ - [:A, 'a'], - # [:B, 'b'], - [:C, 'c'], - [:D, 'd'], - [:E, 'e'], - - [:A, 'a'], - [:B, 'b'], - [:C, 'c'], - [:D, 'd'], - [:E, 'e'], - - [:A, 'a'], - [:B, 'b'], - # [:C, 'c'], - [:D, 'd'], - [:E, 'e'], - [false, nil] - ] -end - -def next_token - @q.shift -end - -def on_error( t, val, values ) - $stderr.puts "error on token '#{val}'(#{t})" -end - -def parse - do_parse -end - ----- footer - -p = ErrTestp.new -p.parse diff --git a/test/racc/assets/error_recovery.y b/test/racc/assets/error_recovery.y deleted file mode 100644 index 1fd21ac7d0..0000000000 --- a/test/racc/assets/error_recovery.y +++ /dev/null @@ -1,35 +0,0 @@ -# Regression test case for the bug discussed here: -# https://github.com/whitequark/parser/issues/93 -# In short, a Racc-generated parser could go into an infinite loop when -# attempting error recovery at EOF - -class InfiniteLoop - -rule - - stmts: stmt - | error stmt - - stmt: '%' stmt - -end - ----- inner - - def parse - @errors = [] - do_parse - end - - def next_token - nil - end - - def on_error(error_token, error_value, value_stack) - # oh my, an error - @errors << [error_token, error_value] - end - ----- footer - -InfiniteLoop.new.parse
\ No newline at end of file diff --git a/test/racc/assets/expect.y b/test/racc/assets/expect.y deleted file mode 100644 index 24c27443e2..0000000000 --- a/test/racc/assets/expect.y +++ /dev/null @@ -1,7 +0,0 @@ -class E - expect 1 -rule - list: inlist inlist - inlist: - | A -end diff --git a/test/racc/assets/firstline.y b/test/racc/assets/firstline.y deleted file mode 100644 index ab0692e543..0000000000 --- a/test/racc/assets/firstline.y +++ /dev/null @@ -1,4 +0,0 @@ -class T -rule - a: A B C -end diff --git a/test/racc/assets/huia.y b/test/racc/assets/huia.y deleted file mode 100644 index de9d45150c..0000000000 --- a/test/racc/assets/huia.y +++ /dev/null @@ -1,318 +0,0 @@ -# Copyright (c) 2014 James Harton -# -# MIT License -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -class Huia::Parser - - token - IDENTIFIER EQUAL PLUS MINUS ASTERISK FWD_SLASH COLON FLOAT INTEGER STRING - EXPO INDENT OUTDENT OPAREN CPAREN DOT SIGNATURE NL EOF PIPE COMMA NIL TRUE - FALSE EQUALITY CALL SELF CONSTANT CHAR DOUBLE_TICK_STRING - DOUBLE_TICK_STRING_END INTERPOLATE_START INTERPOLATE_END BOX LSQUARE - RSQUARE FACES LFACE RFACE BANG TILDE RETURN NOT_EQUALITY OR AND GT LT - GTE LTE AT - - prechigh - left EXPO - left BANG TILDE - left ASTERISK FWD_SLASH PERCENT - left PLUS MINUS - - right EQUAL - preclow - - rule - statements: statement - | statements statement { return scope } - - statement: expr eol { return scope.append val[0] } - | expr { return scope.append val[0] } - | eol { return scope } - - eol: NL | EOF - nlq: NL | - - expr: literal - | grouped_expr - | binary_op - | unary_op - | method_call - | constant - | variable - | array - | hash - | return - - return: return_expr - | return_nil - return_expr: RETURN expr { return n(:Return, val[1]) } - return_nil: RETURN { return n(:Return, n(:Nil)) } - - array: empty_array - | array_list - - empty_array: BOX { return n :Array } - - array_list: LSQUARE array_items RSQUARE { return val[1] } - array_items: expr { return n :Array, [val[0]] } - | array_items COMMA expr { val[0].append(val[2]); return val[0] } - - hash: empty_hash - | hash_list - empty_hash: FACES { return n :Hash } - hash_list: LFACE hash_items RFACE { return val[1] } - hash_items: hash_item { return n :Hash, val[0] } - | hash_items COMMA hash_item { val[0].append(val[2]); return val[0] } - hash_item: expr COLON expr { return n :HashItem, val[0], val[2] } - - constant: CONSTANT { return constant val[0] } - - indented: indented_w_stmts - | indented_w_expr - | indented_wo_stmts - indented_w_stmts: indent statements outdent { return val[0] } - indented_w_expr: indent expr outdent { return val[0].append(val[1]) } - indented_wo_stmts: indent outdent { return val[0] } - outdent: OUTDENT { return pop_scope } - - - indent_w_args: indent_pipe indent_args PIPE nlq INDENT { return val[0] } - indent_pipe: PIPE { return push_scope } - indent_wo_args: INDENT { return push_scope } - indent: indent_w_args - | indent_wo_args - - indent_args: indent_arg - | indent_args COMMA indent_arg - indent_arg: arg_var { return scope.add_argument val[0] } - | arg_var EQUAL expr { return n :Assignment, val[0], val[2] } - arg_var: IDENTIFIER { return n :Variable, val[0] } - - method_call: method_call_on_object - | method_call_on_self - | method_call_on_closure - method_call_on_object: expr DOT call_signature { return n :MethodCall, val[0], val[2] } - | expr DOT IDENTIFIER { return n :MethodCall, val[0], n(:CallSignature, val[2]) } - method_call_on_self: call_signature { return n :MethodCall, scope_instance, val[0] } - - method_call_on_closure: AT call_signature { return n :MethodCall, this_closure, val[1] } - | AT IDENTIFIER { return n :MethodCall, this_closure, n(:CallSignature, val[1]) } - - call_signature: call_arguments - | call_simple_name - call_simple_name: CALL { return n :CallSignature, val[0] } - call_argument: SIGNATURE call_passed_arg { return n :CallSignature, val[0], [val[1]] } - call_passed_arg: call_passed_simple - | call_passed_indented - call_passed_simple: expr - | expr NL - call_passed_indented: indented - | indented NL - call_arguments: call_argument { return val[0] } - | call_arguments call_argument { return val[0].concat_signature val[1] } - - grouped_expr: OPAREN expr CPAREN { return n :Expression, val[1] } - - variable: IDENTIFIER { return allocate_local val[0] } - - binary_op: assignment - | addition - | subtraction - | multiplication - | division - | exponentiation - | modulo - | equality - | not_equality - | logical_or - | logical_and - | greater_than - | less_than - | greater_or_eq - | less_or_eq - - assignment: IDENTIFIER EQUAL expr { return allocate_local_assignment val[0], val[2] } - addition: expr PLUS expr { return binary val[0], val[2], 'plus:' } - subtraction: expr MINUS expr { return binary val[0], val[2], 'minus:' } - multiplication: expr ASTERISK expr { return binary val[0], val[2], 'multiplyBy:' } - division: expr FWD_SLASH expr { return binary val[0], val[2], 'divideBy:' } - exponentiation: expr EXPO expr { return binary val[0], val[2], 'toThePowerOf:' } - modulo: expr PERCENT expr { return binary val[0], val[2], 'moduloOf:' } - equality: expr EQUALITY expr { return binary val[0], val[2], 'isEqualTo:' } - not_equality: expr NOT_EQUALITY expr { return binary val[0], val[2], 'isNotEqualTo:' } - logical_or: expr OR expr { return binary val[0], val[2], 'logicalOr:' } - logical_and: expr AND expr { return binary val[0], val[2], 'logicalAnd:' } - greater_than: expr GT expr { return binary val[0], val[2], 'isGreaterThan:' } - less_than: expr LT expr { return binary val[0], val[2], 'isLessThan:' } - greater_or_eq: expr GTE expr { return binary val[0], val[2], 'isGreaterOrEqualTo:' } - less_or_eq: expr LTE expr { return binary val[0], val[2], 'isLessOrEqualTo:' } - - unary_op: unary_not - | unary_plus - | unary_minus - | unary_complement - - unary_not: BANG expr { return unary val[1], 'unaryNot' } - unary_plus: PLUS expr { return unary val[1], 'unaryPlus' } - unary_minus: MINUS expr { return unary val[1], 'unaryMinus' } - unary_complement: TILDE expr { return unary val[1], 'unaryComplement' } - - literal: integer - | float - | string - | nil - | true - | false - | self - - float: FLOAT { return n :Float, val[0] } - integer: INTEGER { return n :Integer, val[0] } - nil: NIL { return n :Nil } - true: TRUE { return n :True } - false: FALSE { return n :False } - self: SELF { return n :Self } - - string: STRING { return n :String, val[0] } - | interpolated_string - | empty_string - - interpolated_string: DOUBLE_TICK_STRING interpolated_string_contents DOUBLE_TICK_STRING_END { return val[1] } - interpolation: INTERPOLATE_START expr INTERPOLATE_END { return val[1] } - interpolated_string_contents: interpolated_string_chunk { return n :InterpolatedString, val[0] } - | interpolated_string_contents interpolated_string_chunk { val[0].append(val[1]); return val[0] } - interpolated_string_chunk: chars { return val[0] } - | interpolation { return to_string(val[0]) } - empty_string: DOUBLE_TICK_STRING DOUBLE_TICK_STRING_END { return n :String, '' } - - chars: CHAR { return n :String, val[0] } - | chars CHAR { val[0].append(val[1]); return val[0] } -end - ----- inner - -attr_accessor :lexer, :scopes, :state - -def initialize lexer - @lexer = lexer - @state = [] - @scopes = [] - push_scope -end - -def ast - @ast ||= do_parse - @scopes.first -end - -def on_error t, val, vstack - line = lexer.line - col = lexer.column - message = "Unexpected #{token_to_str t} at #{lexer.filename} line #{line}:#{col}:\n\n" - - start = line - 5 > 0 ? line - 5 : 0 - i_size = line.to_s.size - (start..(start + 5)).each do |i| - message << sprintf("\t%#{i_size}d: %s\n", i, lexer.get_line(i)) - message << "\t#{' ' * i_size} #{'-' * (col - 1)}^\n" if i == line - end - - raise SyntaxError, message -end - -def next_token - nt = lexer.next_computed_token - # just use a state stack for now, we'll have to do something - # more sophisticated soon. - if nt && nt.first == :state - if nt.last - state.push << nt.last - else - state.pop - end - next_token - else - nt - end -end - -def push_scope - new_scope = Huia::AST::Scope.new scope - new_scope.file = lexer.filename - new_scope.line = lexer.line - new_scope.column = lexer.column - scopes.push new_scope - new_scope -end - -def pop_scope - scopes.pop -end - -def scope - scopes.last -end - -def binary left, right, method - node(:MethodCall, left, node(:CallSignature, method, [right])) -end - -def unary left, method - node(:MethodCall, left, node(:CallSignature, method)) -end - -def node type, *args - Huia::AST.const_get(type).new(*args).tap do |n| - n.file = lexer.filename - n.line = lexer.line - n.column = lexer.column - end -end -alias n node - -def allocate_local name - node(:Variable, name).tap do |n| - scope.allocate_local n - end -end - -def allocate_local_assignment name, value - node(:Assignment, name, value).tap do |n| - scope.allocate_local n - end -end - -def this_closure - allocate_local('@') -end - -def scope_instance - node(:ScopeInstance, scope) -end - -def constant name - return scope_instance if name == 'self' - node(:Constant, name) -end - -def to_string expr - node(:MethodCall, expr, node(:CallSignature, 'toString')) -end diff --git a/test/racc/assets/ichk.y b/test/racc/assets/ichk.y deleted file mode 100644 index 1d359df83e..0000000000 --- a/test/racc/assets/ichk.y +++ /dev/null @@ -1,102 +0,0 @@ -class Calculator - - prechigh - left '*' '/' - left '+' '-' - preclow - - convert - NUMBER 'Number' - end - -rule - - target : exp - | /* none */ { result = 0 } - - exp : exp '+' exp { result += val[2]; a = 'plus' } - | exp '-' exp { result -= val[2]; a = "string test" } - | exp '*' exp { result *= val[2] } - | exp '/' exp { result /= val[2] } - | '(' { $emb = true } exp ')' - { - raise 'must not happen' unless $emb - result = val[2] - } - | '-' NUMBER { result = -val[1] } - | NUMBER - -----header - -class Number -end - -----inner - - def initialize - @racc_debug_out = $stdout - @yydebug = false - end - - def validate(expected, src) - result = parse(src) - unless result == expected - raise "test #{@test_number} fail" - end - @test_number += 1 - end - - def parse(src) - @src = src - @test_number = 1 - yyparse self, :scan - end - - def scan(&block) - @src.each(&block) - end - -----footer - -calc = Calculator.new - -calc.validate(9, [[Number, 9], nil]) - -calc.validate(-3, - [[Number, 5], - ['*', '*'], - [Number, 1], - ['-', '*'], - [Number, 1], - ['*', '*'], - [Number, 8], - nil]) - -calc.validate(-1, - [[Number, 5], - ['+', '+'], - [Number, 2], - ['-', '-'], - [Number, 5], - ['+', '+'], - [Number, 2], - ['-', '-'], - [Number, 5], - nil]) - -calc.validate(-4, - [['-', 'UMINUS'], - [Number, 4], - nil]) - -calc.validate(40, - [[Number, 7], - ['*', '*'], - ['(', '('], - [Number, 4], - ['+', '+'], - [Number, 3], - [')', ')'], - ['-', '-'], - [Number, 9], - nil]) diff --git a/test/racc/assets/ifelse.y b/test/racc/assets/ifelse.y deleted file mode 100644 index 18dbe4b1a7..0000000000 --- a/test/racc/assets/ifelse.y +++ /dev/null @@ -1,14 +0,0 @@ -class C::Parser -token tSOMETHING -rule - statement - : tSOMETHING - | 'if' statement 'then' statement - | 'if' statement 'then' statement 'else' statement - ; - - dummy - : tSOMETHING '+' tSOMETHING - | tSOMETHING '-' tSOMETHING - ; - diff --git a/test/racc/assets/intp.y b/test/racc/assets/intp.y deleted file mode 100644 index 39e42afd74..0000000000 --- a/test/racc/assets/intp.y +++ /dev/null @@ -1,546 +0,0 @@ -# -# intp -# - -class Intp::Parser - -prechigh - nonassoc UMINUS - left '*' '/' - left '+' '-' - nonassoc EQ -preclow - -rule - - program : stmt_list - { - result = RootNode.new( val[0] ) - } - - stmt_list : - { - result = [] - } - | stmt_list stmt EOL - { - result.push val[1] - } - | stmt_list EOL - - stmt : expr - | assign - | IDENT realprim - { - result = FuncallNode.new( @fname, val[0][0], - val[0][1], [val[1]] ) - } - | if_stmt - | while_stmt - | defun - - if_stmt : IF stmt THEN EOL stmt_list else_stmt END - { - result = IfNode.new( @fname, val[0][0], - val[1], val[4], val[5] ) - } - - else_stmt : ELSE EOL stmt_list - { - result = val[2] - } - | - { - result = nil - } - - while_stmt: WHILE stmt DO EOL stmt_list END - { - result = WhileNode.new(@fname, val[0][0], - val[1], val[4]) - } - - defun : DEF IDENT param EOL stmt_list END - { - result = DefNode.new(@fname, val[0][0], val[1][1], - Function.new(@fname, val[0][0], val[2], val[4])) - } - - param : '(' name_list ')' - { - result = val[1] - } - | '(' ')' - { - result = [] - } - | - { - result = [] - } - - name_list : IDENT - { - result = [ val[0][1] ] - } - | name_list ',' IDENT - { - result.push val[2][1] - } - - assign : IDENT '=' expr - { - result = AssignNode.new(@fname, val[0][0], val[0][1], val[2]) - } - - expr : expr '+' expr - { - result = FuncallNode.new(@fname, val[0].lineno, '+', [val[0], val[2]]) - } - | expr '-' expr - { - result = FuncallNode.new(@fname, val[0].lineno, '-', [val[0], val[2]]) - } - | expr '*' expr - { - result = FuncallNode.new(@fname, val[0].lineno, '*', [val[0], val[2]]) - } - | expr '/' expr - { - result = FuncallNode.new(@fname, val[0].lineno, - '/', [val[0], val[2]]) - } - | expr EQ expr - { - result = FuncallNode.new(@fname, val[0].lineno, '==', [val[0], val[2]]) - } - | primary - - primary : realprim - | '(' expr ')' - { - result = val[1] - } - | '-' expr =UMINUS - { - result = FuncallNode.new(@fname, val[0][0], '-@', [val[1]]) - } - - realprim : IDENT - { - result = VarRefNode.new(@fname, val[0][0], - val[0][1]) - } - | NUMBER - { - result = LiteralNode.new(@fname, *val[0]) - } - | STRING - { - result = StringNode.new(@fname, *val[0]) - } - | TRUE - { - result = LiteralNode.new(@fname, *val[0]) - } - | FALSE - { - result = LiteralNode.new(@fname, *val[0]) - } - | NIL - { - result = LiteralNode.new(@fname, *val[0]) - } - | funcall - - funcall : IDENT '(' args ')' - { - result = FuncallNode.new(@fname, val[0][0], val[0][1], val[2]) - } - | IDENT '(' ')' - { - result = FuncallNode.new(@fname, val[0][0], val[0][1], []) - } - - args : expr - { - result = val - } - | args ',' expr - { - result.push val[2] - } - -end - ----- header -# -# intp/parser.rb -# - ----- inner - - def initialize - @scope = {} - end - - RESERVED = { - 'if' => :IF, - 'else' => :ELSE, - 'while' => :WHILE, - 'then' => :THEN, - 'do' => :DO, - 'def' => :DEF, - 'true' => :TRUE, - 'false' => :FALSE, - 'nil' => :NIL, - 'end' => :END - } - - RESERVED_V = { - 'true' => true, - 'false' => false, - 'nil' => nil - } - - def parse(f, fname) - @q = [] - @fname = fname - lineno = 1 - f.each do |line| - line.strip! - until line.empty? - case line - when /\A\s+/, /\A\#.*/ - ; - when /\A[a-zA-Z_]\w*/ - word = $& - @q.push [(RESERVED[word] || :IDENT), - [lineno, RESERVED_V.key?(word) ? RESERVED_V[word] : word.intern]] - when /\A\d+/ - @q.push [:NUMBER, [lineno, $&.to_i]] - when /\A"(?:[^"\\]+|\\.)*"/, /\A'(?:[^'\\]+|\\.)*'/ - @q.push [:STRING, [lineno, eval($&)]] - when /\A==/ - @q.push [:EQ, [lineno, '==']] - when /\A./ - @q.push [$&, [lineno, $&]] - else - raise RuntimeError, 'must not happen' - end - line = $' - end - @q.push [:EOL, [lineno, nil]] - lineno += 1 - end - @q.push [false, '$'] - do_parse - end - - def next_token - @q.shift - end - - def on_error(t, v, values) - if v - line = v[0] - v = v[1] - else - line = 'last' - end - raise Racc::ParseError, "#{@fname}:#{line}: syntax error on #{v.inspect}" - end - ----- footer -# intp/node.rb - -module Intp - - class IntpError < StandardError; end - class IntpArgumentError < IntpError; end - - class Core - - def initialize - @ftab = {} - @obj = Object.new - @stack = [] - @stack.push Frame.new '(toplevel)' - end - - def frame - @stack[-1] - end - - def define_function(fname, node) - raise IntpError, "function #{fname} defined twice" if @ftab.key?(fname) - @ftab[fname] = node - end - - def call_function_or(fname, args) - call_intp_function_or(fname, args) { - call_ruby_toplevel_or(fname, args) { - yield - } - } - end - - def call_intp_function_or(fname, args) - if func = @ftab[fname] - frame = Frame.new(fname) - @stack.push frame - func.call self, frame, args - @stack.pop - else - yield - end - end - - def call_ruby_toplevel_or(fname, args) - if @obj.respond_to? fname, true - @obj.send fname, *args - else - yield - end - end - - end - - class Frame - - def initialize(fname) - @fname = fname - @lvars = {} - end - - attr :fname - - def lvar?(name) - @lvars.key? name - end - - def [](key) - @lvars[key] - end - - def []=(key, val) - @lvars[key] = val - end - - end - - - class Node - - def initialize(fname, lineno) - @filename = fname - @lineno = lineno - end - - attr_reader :filename - attr_reader :lineno - - def exec_list(intp, nodes) - v = nil - nodes.each {|i| v = i.evaluate(intp) } - v - end - - def intp_error!(msg) - raise IntpError, "in #{filename}:#{lineno}: #{msg}" - end - - def inspect - "#{self.class.name}/#{lineno}" - end - - end - - - class RootNode < Node - - def initialize(tree) - super nil, nil - @tree = tree - end - - def evaluate - exec_list Core.new, @tree - end - - end - - - class DefNode < Node - - def initialize(file, lineno, fname, func) - super file, lineno - @funcname = fname - @funcobj = func - end - - def evaluate(intp) - intp.define_function @funcname, @funcobj - end - - end - - class FuncallNode < Node - - def initialize(file, lineno, func, args) - super file, lineno - @funcname = func - @args = args - end - - def evaluate(intp) - args = @args.map {|i| i.evaluate intp } - begin - intp.call_intp_function_or(@funcname, args) { - if args.empty? or not args[0].respond_to?(@funcname) - intp.call_ruby_toplevel_or(@funcname, args) { - intp_error! "undefined function #{@funcname.id2name}" - } - else - recv = args.shift - recv.send @funcname, *args - end - } - rescue IntpArgumentError, ArgumentError - intp_error! $!.message - end - end - - end - - class Function < Node - - def initialize(file, lineno, params, body) - super file, lineno - @params = params - @body = body - end - - def call(intp, frame, args) - unless args.size == @params.size - raise IntpArgumentError, - "wrong # of arg for #{frame.fname}() (#{args.size} for #{@params.size})" - end - args.each_with_index do |v,i| - frame[@params[i]] = v - end - exec_list intp, @body - end - - end - - - class IfNode < Node - - def initialize(fname, lineno, cond, tstmt, fstmt) - super fname, lineno - @condition = cond - @tstmt = tstmt - @fstmt = fstmt - end - - def evaluate(intp) - if @condition.evaluate(intp) - exec_list intp, @tstmt - else - exec_list intp, @fstmt if @fstmt - end - end - - end - - class WhileNode < Node - - def initialize(fname, lineno, cond, body) - super fname, lineno - @condition = cond - @body = body - end - - def evaluate(intp) - while @condition.evaluate(intp) - exec_list intp, @body - end - end - - end - - - class AssignNode < Node - - def initialize(fname, lineno, vname, val) - super fname, lineno - @vname = vname - @val = val - end - - def evaluate(intp) - intp.frame[@vname] = @val.evaluate(intp) - end - - end - - class VarRefNode < Node - - def initialize(fname, lineno, vname) - super fname, lineno - @vname = vname - end - - def evaluate(intp) - if intp.frame.lvar?(@vname) - intp.frame[@vname] - else - intp.call_function_or(@vname, []) { - intp_error! "unknown method or local variable #{@vname.id2name}" - } - end - end - - end - - class StringNode < Node - - def initialize(fname, lineno, str) - super fname, lineno - @val = str - end - - def evaluate(intp) - @val.dup - end - - end - - class LiteralNode < Node - - def initialize(fname, lineno, val) - super fname, lineno - @val = val - end - - def evaluate(intp) - @val - end - - end - -end # module Intp - -begin - tree = nil - fname = 'src.intp' - File.open(fname) {|f| - tree = Intp::Parser.new.parse(f, fname) - } - tree.evaluate -rescue Racc::ParseError, Intp::IntpError, Errno::ENOENT - raise #### - $stderr.puts "#{File.basename $0}: #{$!}" - exit 1 -end diff --git a/test/racc/assets/journey.y b/test/racc/assets/journey.y deleted file mode 100644 index c2640f3339..0000000000 --- a/test/racc/assets/journey.y +++ /dev/null @@ -1,47 +0,0 @@ -class Journey::Parser - -token SLASH LITERAL SYMBOL LPAREN RPAREN DOT STAR OR - -rule - expressions - : expressions expression { result = Cat.new(val.first, val.last) } - | expression { result = val.first } - | or - ; - expression - : terminal - | group - | star - ; - group - : LPAREN expressions RPAREN { result = Group.new(val[1]) } - ; - or - : expressions OR expression { result = Or.new([val.first, val.last]) } - ; - star - : STAR { result = Star.new(Symbol.new(val.last)) } - ; - terminal - : symbol - | literal - | slash - | dot - ; - slash - : SLASH { result = Slash.new('/') } - ; - symbol - : SYMBOL { result = Symbol.new(val.first) } - ; - literal - : LITERAL { result = Literal.new(val.first) } - dot - : DOT { result = Dot.new(val.first) } - ; - -end - ----- header - -require 'journey/parser_extras' diff --git a/test/racc/assets/liquor.y b/test/racc/assets/liquor.y deleted file mode 100644 index 8045a072a4..0000000000 --- a/test/racc/assets/liquor.y +++ /dev/null @@ -1,313 +0,0 @@ -# Copyright (c) 2012-2013 Peter Zotov <whitequark@whitequark.org> -# 2012 Yaroslav Markin <yaroslav@markin.net> -# 2012 Nate Gadgibalaev <nat@xnsv.ru> -# -# MIT License -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -class Liquor::Parser - token comma dot endtag ident integer keyword lblock lblock2 lbracket - linterp lparen op_div op_eq op_gt op_geq op_lt op_leq op_minus - op_mod op_mul op_neq op_not op_plus pipe plaintext rblock - rbracket rinterp rparen string tag_ident - - prechigh - left dot - nonassoc op_uminus op_not - left op_mul op_div op_mod - left op_plus op_minus - left op_eq op_neq op_lt op_leq op_gt op_geq - left op_and - left op_or - preclow - - expect 15 - - start block - -rule - block: /* empty */ - { result = [] } - | plaintext block - { result = [ val[0], *val[1] ] } - | interp block - { result = [ val[0], *val[1] ] } - | tag block - { result = [ val[0], *val[1] ] } - - interp: - linterp expr rinterp - { result = [ :interp, retag(val), val[1] ] } - | linterp filter_chain rinterp - { result = [ :interp, retag(val), val[1] ] } - - primary_expr: - ident - | lparen expr rparen - { result = [ val[1][0], retag(val), *val[1][2..-1] ] } - - expr: - integer - | string - | tuple - | ident function_args - { result = [ :call, retag(val), val[0], val[1] ] } - | expr lbracket expr rbracket - { result = [ :index, retag(val), val[0], val[2] ] } - | expr dot ident function_args - { result = [ :external, retag(val), val[0], val[2], val[3] ] } - | expr dot ident - { result = [ :external, retag(val), val[0], val[2], nil ] } - | op_minus expr =op_uminus - { result = [ :uminus, retag(val), val[1] ] } - | op_not expr - { result = [ :not, retag(val), val[1] ] } - | expr op_mul expr - { result = [ :mul, retag(val), val[0], val[2] ] } - | expr op_div expr - { result = [ :div, retag(val), val[0], val[2] ] } - | expr op_mod expr - { result = [ :mod, retag(val), val[0], val[2] ] } - | expr op_plus expr - { result = [ :plus, retag(val), val[0], val[2] ] } - | expr op_minus expr - { result = [ :minus, retag(val), val[0], val[2] ] } - | expr op_eq expr - { result = [ :eq, retag(val), val[0], val[2] ] } - | expr op_neq expr - { result = [ :neq, retag(val), val[0], val[2] ] } - | expr op_lt expr - { result = [ :lt, retag(val), val[0], val[2] ] } - | expr op_leq expr - { result = [ :leq, retag(val), val[0], val[2] ] } - | expr op_gt expr - { result = [ :gt, retag(val), val[0], val[2] ] } - | expr op_geq expr - { result = [ :geq, retag(val), val[0], val[2] ] } - | expr op_and expr - { result = [ :and, retag(val), val[0], val[2] ] } - | expr op_or expr - { result = [ :or, retag(val), val[0], val[2] ] } - | primary_expr - - tuple: - lbracket tuple_content rbracket - { result = [ :tuple, retag(val), val[1].compact ] } - - tuple_content: - expr comma tuple_content - { result = [ val[0], *val[2] ] } - | expr - { result = [ val[0] ] } - | /* empty */ - { result = [ ] } - - function_args: - lparen function_args_inside rparen - { result = [ :args, retag(val), *val[1] ] } - - function_args_inside: - expr function_keywords - { result = [ val[0], val[1][2] ] } - | function_keywords - { result = [ nil, val[0][2] ] } - - function_keywords: - keyword expr function_keywords - { name = val[0][2].to_sym - tail = val[2][2] - loc = retag([ val[0], val[1] ]) - - if tail.include? name - @errors << SyntaxError.new("duplicate keyword argument `#{val[0][2]}'", - tail[name][1]) - end - - hash = { - name => [ val[1][0], loc, *val[1][2..-1] ] - }.merge(tail) - - result = [ :keywords, retag([ loc, val[2] ]), hash ] - } - | /* empty */ - { result = [ :keywords, nil, {} ] } - - filter_chain: - expr pipe filter_chain_cont - { result = [ val[0], *val[2] ]. - reduce { |tree, node| node[3][2] = tree; node } - } - - filter_chain_cont: - filter_call pipe filter_chain_cont - { result = [ val[0], *val[2] ] } - | filter_call - { result = [ val[0] ] } - - filter_call: - ident function_keywords - { ident_loc = val[0][1] - empty_args_loc = { line: ident_loc[:line], - start: ident_loc[:end] + 1, - end: ident_loc[:end] + 1, } - result = [ :call, val[0][1], val[0], - [ :args, val[1][1] || empty_args_loc, nil, val[1][2] ] ] - } - - tag: - lblock ident expr tag_first_cont - { result = [ :tag, retag(val), val[1], val[2], *reduce_tag_args(val[3][2]) ] } - | lblock ident tag_first_cont - { result = [ :tag, retag(val), val[1], nil, *reduce_tag_args(val[2][2]) ] } - - # Racc cannot do lookahead across rules. I had to add states - # explicitly to avoid S/R conflicts. You are not expected to - # understand this. - - tag_first_cont: - rblock - { result = [ :cont, retag(val), [] ] } - | keyword tag_first_cont2 - { result = [ :cont, retag(val), [ val[0], *val[1][2] ] ] } - - tag_first_cont2: - rblock block lblock2 tag_next_cont - { result = [ :cont2, val[0][1], [ [:block, val[0][1], val[1] ], *val[3] ] ] } - | expr tag_first_cont - { result = [ :cont2, retag(val), [ val[0], *val[1][2] ] ] } - - tag_next_cont: - endtag rblock - { result = [] } - | keyword tag_next_cont2 - { result = [ val[0], *val[1] ] } - - tag_next_cont2: - rblock block lblock2 tag_next_cont - { result = [ [:block, val[0][1], val[1] ], *val[3] ] } - | expr keyword tag_next_cont3 - { result = [ val[0], val[1], *val[2] ] } - - tag_next_cont3: - rblock block lblock2 tag_next_cont - { result = [ [:block, val[0][1], val[1] ], *val[3] ] } - | expr tag_next_cont - { result = [ val[0], *val[1] ] } - ----- inner - attr_reader :errors, :ast - - def initialize(tags={}) - super() - - @errors = [] - @ast = nil - @tags = tags - end - - def success? - @errors.empty? - end - - def parse(string, name='(code)') - @errors.clear - @name = name - @ast = nil - - begin - @stream = Lexer.lex(string, @name, @tags) - @ast = do_parse - rescue Liquor::SyntaxError => e - @errors << e - end - - success? - end - - def next_token - tok = @stream.shift - [ tok[0], tok ] if tok - end - - TOKEN_NAME_MAP = { - :comma => ',', - :dot => '.', - :lblock => '{%', - :rblock => '%}', - :linterp => '{{', - :rinterp => '}}', - :lbracket => '[', - :rbracket => ']', - :lparen => '(', - :rparen => ')', - :pipe => '|', - :op_not => '!', - :op_mul => '*', - :op_div => '/', - :op_mod => '%', - :op_plus => '+', - :op_minus => '-', - :op_eq => '==', - :op_neq => '!=', - :op_lt => '<', - :op_leq => '<=', - :op_gt => '>', - :op_geq => '>=', - :keyword => 'keyword argument name', - :kwarg => 'keyword argument', - :ident => 'identifier', - } - - def on_error(error_token_id, error_token, value_stack) - if token_to_str(error_token_id) == "$end" - raise Liquor::SyntaxError.new("unexpected end of program", { - file: @name - }) - else - type, (loc, value) = error_token - type = TOKEN_NAME_MAP[type] || type - - raise Liquor::SyntaxError.new("unexpected token `#{type}'", loc) - end - end - - def retag(nodes) - loc = nodes.map { |node| node[1] }.compact - first, *, last = loc - return first if last.nil? - - { - file: first[:file], - line: first[:line], - start: first[:start], - end: last[:end], - } - end - - def reduce_tag_args(list) - list.each_slice(2).reduce([]) { |args, (k, v)| - if v[0] == :block - args << [ :blockarg, retag([ k, v ]), k, v[2] || [] ] - else - args << [ :kwarg, retag([ k, v ]), k, v ] - end - } - end
\ No newline at end of file diff --git a/test/racc/assets/machete.y b/test/racc/assets/machete.y deleted file mode 100644 index ea92d47a69..0000000000 --- a/test/racc/assets/machete.y +++ /dev/null @@ -1,423 +0,0 @@ -# Copyright (c) 2011 SUSE -# -# Permission is hereby granted, free of charge, to any person -# obtaining a copy of this software and associated documentation -# files (the "Software"), to deal in the Software without -# restriction, including without limitation the rights to use, -# copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the -# Software is furnished to do so, subject to the following -# conditions: -# -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -# OTHER DEALINGS IN THE SOFTWARE. - -class Machete::Parser - -token NIL -token TRUE -token FALSE -token INTEGER -token SYMBOL -token STRING -token REGEXP -token ANY -token EVEN -token ODD -token METHOD_NAME -token CLASS_NAME - -start expression - -rule - -expression : primary - | expression "|" primary { - result = if val[0].is_a?(ChoiceMatcher) - ChoiceMatcher.new(val[0].alternatives << val[2]) - else - ChoiceMatcher.new([val[0], val[2]]) - end - } - -primary : node - | array - | literal - | any - -node : CLASS_NAME { - result = NodeMatcher.new(val[0].to_sym) - } - | CLASS_NAME "<" attrs ">" { - result = NodeMatcher.new(val[0].to_sym, val[2]) - } - -attrs : attr - | attrs "," attr { result = val[0].merge(val[2]) } - -attr : method_name "=" expression { result = { val[0].to_sym => val[2] } } - | method_name "^=" SYMBOL { - result = { - val[0].to_sym => SymbolRegexpMatcher.new( - Regexp.new("^" + Regexp.escape(symbol_value(val[2]).to_s)) - ) - } - } - | method_name "$=" SYMBOL { - result = { - val[0].to_sym => SymbolRegexpMatcher.new( - Regexp.new(Regexp.escape(symbol_value(val[2]).to_s) + "$") - ) - } - } - | method_name "*=" SYMBOL { - result = { - val[0].to_sym => SymbolRegexpMatcher.new( - Regexp.new(Regexp.escape(symbol_value(val[2]).to_s)) - ) - } - } - | method_name "^=" STRING { - result = { - val[0].to_sym => StringRegexpMatcher.new( - Regexp.new("^" + Regexp.escape(string_value(val[2]))) - ) - } - } - | method_name "$=" STRING { - result = { - val[0].to_sym => StringRegexpMatcher.new( - Regexp.new(Regexp.escape(string_value(val[2])) + "$") - ) - } - } - | method_name "*=" STRING { - result = { - val[0].to_sym => StringRegexpMatcher.new( - Regexp.new(Regexp.escape(string_value(val[2]))) - ) - } - } - | method_name "*=" REGEXP { - result = { - val[0].to_sym => IndifferentRegexpMatcher.new( - Regexp.new(regexp_value(val[2])) - ) - } - } - -# Hack to overcome the fact that some tokens will lex as simple tokens, not -# METHOD_NAME tokens, and that "reserved words" will lex as separate kinds of -# tokens. -method_name : METHOD_NAME - | NIL - | TRUE - | FALSE - | ANY - | EVEN - | ODD - | "*" - | "+" - | "<" - | ">" - | "^" - | "|" - -array : "[" items_opt "]" { result = ArrayMatcher.new(val[1]) } - -items_opt : /* empty */ { result = [] } - | items - -items : item { result = [val[0]] } - | items "," item { result = val[0] << val[2] } - -item : expression - | expression quantifier { result = Quantifier.new(val[0], *val[1]) } - -quantifier : "*" { result = [0, nil, 1] } - | "+" { result = [1, nil, 1] } - | "?" { result = [0, 1, 1] } - | "{" INTEGER "}" { - result = [integer_value(val[1]), integer_value(val[1]), 1] - } - | "{" INTEGER "," "}" { - result = [integer_value(val[1]), nil, 1] - } - | "{" "," INTEGER "}" { - result = [0, integer_value(val[2]), 1] - } - | "{" INTEGER "," INTEGER "}" { - result = [integer_value(val[1]), integer_value(val[3]), 1] - } - | "{" EVEN "}" { result = [0, nil, 2] } - | "{" ODD "}" { result = [1, nil, 2] } - -literal : NIL { result = LiteralMatcher.new(nil) } - | TRUE { result = LiteralMatcher.new(true) } - | FALSE { result = LiteralMatcher.new(false) } - | INTEGER { result = LiteralMatcher.new(integer_value(val[0])) } - | SYMBOL { result = LiteralMatcher.new(symbol_value(val[0])) } - | STRING { result = LiteralMatcher.new(string_value(val[0])) } - | REGEXP { result = LiteralMatcher.new(regexp_value(val[0])) } - -any : ANY { result = AnyMatcher.new } - ----- inner - -include Matchers - -class SyntaxError < StandardError; end - -def parse(input) - @input = input - @pos = 0 - - do_parse -end - -private - -def integer_value(value) - if value =~ /^0[bB]/ - value[2..-1].to_i(2) - elsif value =~ /^0[oO]/ - value[2..-1].to_i(8) - elsif value =~ /^0[dD]/ - value[2..-1].to_i(10) - elsif value =~ /^0[xX]/ - value[2..-1].to_i(16) - elsif value =~ /^0/ - value.to_i(8) - else - value.to_i - end -end - -def symbol_value(value) - value[1..-1].to_sym -end - -def string_value(value) - quote = value[0..0] - if quote == "'" - value[1..-2].gsub("\\\\", "\\").gsub("\\'", "'") - elsif quote == '"' - value[1..-2]. - gsub("\\\\", "\\"). - gsub('\\"', '"'). - gsub("\\n", "\n"). - gsub("\\t", "\t"). - gsub("\\r", "\r"). - gsub("\\f", "\f"). - gsub("\\v", "\v"). - gsub("\\a", "\a"). - gsub("\\e", "\e"). - gsub("\\b", "\b"). - gsub("\\s", "\s"). - gsub(/\\([0-7]{1,3})/) { $1.to_i(8).chr }. - gsub(/\\x([0-9a-fA-F]{1,2})/) { $1.to_i(16).chr } - else - raise "Unknown quote: #{quote.inspect}." - end -end - -REGEXP_OPTIONS = { - 'i' => Regexp::IGNORECASE, - 'm' => Regexp::MULTILINE, - 'x' => Regexp::EXTENDED -} - -def regexp_value(value) - /\A\/(.*)\/([imx]*)\z/ =~ value - pattern, options = $1, $2 - - Regexp.new(pattern, options.chars.map { |ch| REGEXP_OPTIONS[ch] }.inject(:|)) -end - -# "^" needs to be here because if it were among operators recognized by -# METHOD_NAME, "^=" would be recognized as two tokens. -SIMPLE_TOKENS = [ - "|", - "<", - ">", - ",", - "=", - "^=", - "^", - "$=", - "[", - "]", - "*=", - "*", - "+", - "?", - "{", - "}" -] - -COMPLEX_TOKENS = [ - [:NIL, /^nil/], - [:TRUE, /^true/], - [:FALSE, /^false/], - # INTEGER needs to be before METHOD_NAME, otherwise e.g. "+1" would be - # recognized as two tokens. - [ - :INTEGER, - /^ - [+-]? # sign - ( - 0[bB][01]+(_[01]+)* # binary (prefixed) - | - 0[oO][0-7]+(_[0-7]+)* # octal (prefixed) - | - 0[dD]\d+(_\d+)* # decimal (prefixed) - | - 0[xX][0-9a-fA-F]+(_[0-9a-fA-F]+)* # hexadecimal (prefixed) - | - 0[0-7]*(_[0-7]+)* # octal (unprefixed) - | - [1-9]\d*(_\d+)* # decimal (unprefixed) - ) - /x - ], - [ - :SYMBOL, - /^ - : - ( - # class name - [A-Z][a-zA-Z0-9_]* - | - # regular method name - [a-z_][a-zA-Z0-9_]*[?!=]? - | - # instance variable name - @[a-zA-Z_][a-zA-Z0-9_]* - | - # class variable name - @@[a-zA-Z_][a-zA-Z0-9_]* - | - # operator (sorted by length, then alphabetically) - (<=>|===|\[\]=|\*\*|\+@|-@|<<|<=|==|=~|>=|>>|\[\]|[%&*+\-\/<>^`|~]) - ) - /x - ], - [ - :STRING, - /^ - ( - ' # sinqle-quoted string - ( - \\[\\'] # escape - | - [^'] # regular character - )* - ' - | - " # double-quoted string - ( - \\ # escape - ( - [\\"ntrfvaebs] # one-character escape - | - [0-7]{1,3} # octal number escape - | - x[0-9a-fA-F]{1,2} # hexadecimal number escape - ) - | - [^"] # regular character - )* - " - ) - /x - ], - [ - :REGEXP, - /^ - \/ - ( - \\ # escape - ( - [\\\/ntrfvaebs\(\)\[\]\{\}\-\.\?\*\+\|\^\$] # one-character escape - | - [0-7]{2,3} # octal number escape - | - x[0-9a-fA-F]{1,2} # hexadecimal number escape - ) - | - [^\/] # regular character - )* - \/ - [imx]* - /x - ], - # ANY, EVEN and ODD need to be before METHOD_NAME, otherwise they would be - # recognized as method names. - [:ANY, /^any/], - [:EVEN, /^even/], - [:ODD, /^odd/], - # We exclude "*", "+", "<", ">", "^" and "|" from method names since they are - # lexed as simple tokens. This is because they have also other meanings in - # Machette patterns beside Ruby method names. - [ - :METHOD_NAME, - /^ - ( - # regular name - [a-z_][a-zA-Z0-9_]*[?!=]? - | - # operator (sorted by length, then alphabetically) - (<=>|===|\[\]=|\*\*|\+@|-@|<<|<=|==|=~|>=|>>|\[\]|[%&\-\/`~]) - ) - /x - ], - [:CLASS_NAME, /^[A-Z][a-zA-Z0-9_]*/] -] - -def next_token - skip_whitespace - - return false if remaining_input.empty? - - # Complex tokens need to be before simple tokens, otherwise e.g. "<<" would be - # recognized as two tokens. - - COMPLEX_TOKENS.each do |type, regexp| - if remaining_input =~ regexp - @pos += $&.length - return [type, $&] - end - end - - SIMPLE_TOKENS.each do |token| - if remaining_input[0...token.length] == token - @pos += token.length - return [token, token] - end - end - - raise SyntaxError, "Unexpected character: #{remaining_input[0..0].inspect}." -end - -def skip_whitespace - if remaining_input =~ /\A^[ \t\r\n]+/ - @pos += $&.length - end -end - -def remaining_input - @input[@pos..-1] -end - -def on_error(error_token_id, error_value, value_stack) - raise SyntaxError, "Unexpected token: #{error_value.inspect}." -end diff --git a/test/racc/assets/macruby.y b/test/racc/assets/macruby.y deleted file mode 100644 index 5ede008308..0000000000 --- a/test/racc/assets/macruby.y +++ /dev/null @@ -1,2197 +0,0 @@ -# Copyright (c) 2013 Peter Zotov <whitequark@whitequark.org> -# -# Parts of the source are derived from ruby_parser: -# Copyright (c) Ryan Davis, seattle.rb -# -# MIT License -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -class Parser::MacRuby - -token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS - kTHEN kELSIF kELSE kCASE kWHEN kWHILE kUNTIL kFOR kBREAK kNEXT - kREDO kRETRY kIN kDO kDO_COND kDO_BLOCK kDO_LAMBDA kRETURN kYIELD kSUPER - kSELF kNIL kTRUE kFALSE kAND kOR kNOT kIF_MOD kUNLESS_MOD kWHILE_MOD - kUNTIL_MOD kRESCUE_MOD kALIAS kDEFINED klBEGIN klEND k__LINE__ - k__FILE__ k__ENCODING__ tIDENTIFIER tFID tGVAR tIVAR tCONSTANT - tLABEL tCVAR tNTH_REF tBACK_REF tSTRING_CONTENT tINTEGER tFLOAT - tREGEXP_END tUPLUS tUMINUS tUMINUS_NUM tPOW tCMP tEQ tEQQ tNEQ - tGEQ tLEQ tANDOP tOROP tMATCH tNMATCH tDOT tDOT2 tDOT3 tAREF - tASET tLSHFT tRSHFT tCOLON2 tCOLON3 tOP_ASGN tASSOC tLPAREN - tLPAREN2 tRPAREN tLPAREN_ARG tLBRACK tLBRACK2 tRBRACK tLBRACE - tLBRACE_ARG tSTAR tSTAR2 tAMPER tAMPER2 tTILDE tPERCENT tDIVIDE - tPLUS tMINUS tLT tGT tPIPE tBANG tCARET tLCURLY tRCURLY - tBACK_REF2 tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG tREGEXP_OPT - tWORDS_BEG tQWORDS_BEG tSTRING_DBEG tSTRING_DVAR tSTRING_END - tSTRING tSYMBOL tNL tEH tCOLON tCOMMA tSPACE tSEMI tLAMBDA tLAMBEG - tCHARACTER - -prechigh - right tBANG tTILDE tUPLUS - right tPOW - right tUMINUS_NUM tUMINUS - left tSTAR2 tDIVIDE tPERCENT - left tPLUS tMINUS - left tLSHFT tRSHFT - left tAMPER2 - left tPIPE tCARET - left tGT tGEQ tLT tLEQ - nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH - left tANDOP - left tOROP - nonassoc tDOT2 tDOT3 - right tEH tCOLON - left kRESCUE_MOD - right tEQL tOP_ASGN - nonassoc kDEFINED - right kNOT - left kOR kAND - nonassoc kIF_MOD kUNLESS_MOD kWHILE_MOD kUNTIL_MOD - nonassoc tLBRACE_ARG - nonassoc tLOWEST -preclow - -rule - - program: top_compstmt - - top_compstmt: top_stmts opt_terms - { - result = @builder.compstmt(val[0]) - } - - top_stmts: # nothing - { - result = [] - } - | top_stmt - { - result = [ val[0] ] - } - | top_stmts terms top_stmt - { - result = val[0] << val[2] - } - | error top_stmt - { - result = [ val[1] ] - } - - top_stmt: stmt - | klBEGIN tLCURLY top_compstmt tRCURLY - { - result = @builder.preexe(val[0], val[1], val[2], val[3]) - } - - bodystmt: compstmt opt_rescue opt_else opt_ensure - { - rescue_bodies = val[1] - else_t, else_ = val[2] - ensure_t, ensure_ = val[3] - - if rescue_bodies.empty? && !else_.nil? - diagnostic :warning, :useless_else, nil, else_t - end - - result = @builder.begin_body(val[0], - rescue_bodies, - else_t, else_, - ensure_t, ensure_) - } - - compstmt: stmts opt_terms - { - result = @builder.compstmt(val[0]) - } - - stmts: # nothing - { - result = [] - } - | stmt - { - result = [ val[0] ] - } - | stmts terms stmt - { - result = val[0] << val[2] - } - | error stmt - { - result = [ val[1] ] - } - - stmt: kALIAS fitem - { - @lexer.state = :expr_fname - } - fitem - { - result = @builder.alias(val[0], val[1], val[3]) - } - | kALIAS tGVAR tGVAR - { - result = @builder.alias(val[0], - @builder.gvar(val[1]), - @builder.gvar(val[2])) - } - | kALIAS tGVAR tBACK_REF - { - result = @builder.alias(val[0], - @builder.gvar(val[1]), - @builder.back_ref(val[2])) - } - | kALIAS tGVAR tNTH_REF - { - diagnostic :error, :nth_ref_alias, nil, val[2] - } - | kUNDEF undef_list - { - result = @builder.undef_method(val[0], val[1]) - } - | stmt kIF_MOD expr_value - { - result = @builder.condition_mod(val[0], nil, - val[1], val[2]) - } - | stmt kUNLESS_MOD expr_value - { - result = @builder.condition_mod(nil, val[0], - val[1], val[2]) - } - | stmt kWHILE_MOD expr_value - { - result = @builder.loop_mod(:while, val[0], val[1], val[2]) - } - | stmt kUNTIL_MOD expr_value - { - result = @builder.loop_mod(:until, val[0], val[1], val[2]) - } - | stmt kRESCUE_MOD stmt - { - rescue_body = @builder.rescue_body(val[1], - nil, nil, nil, - nil, val[2]) - - result = @builder.begin_body(val[0], [ rescue_body ]) - } - | klEND tLCURLY compstmt tRCURLY - { - result = @builder.postexe(val[0], val[1], val[2], val[3]) - } - | lhs tEQL command_call - { - result = @builder.assign(val[0], val[1], val[2]) - } - | mlhs tEQL command_call - { - result = @builder.multi_assign(val[0], val[1], val[2]) - } - | var_lhs tOP_ASGN command_call - { - result = @builder.op_assign(val[0], val[1], val[2]) - } - | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN command_call - { - result = @builder.op_assign( - @builder.index( - val[0], val[1], val[2], val[3]), - val[4], val[5]) - } - | primary_value tDOT tIDENTIFIER tOP_ASGN command_call - { - result = @builder.op_assign( - @builder.call_method( - val[0], val[1], val[2]), - val[3], val[4]) - } - | primary_value tDOT tCONSTANT tOP_ASGN command_call - { - result = @builder.op_assign( - @builder.call_method( - val[0], val[1], val[2]), - val[3], val[4]) - } - | primary_value tCOLON2 tCONSTANT tOP_ASGN command_call - { - result = @builder.op_assign( - @builder.call_method( - val[0], val[1], val[2]), - val[3], val[4]) - } - | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_call - { - result = @builder.op_assign( - @builder.call_method( - val[0], val[1], val[2]), - val[3], val[4]) - } - | backref tOP_ASGN command_call - { - @builder.op_assign(val[0], val[1], val[2]) - } - | lhs tEQL mrhs - { - result = @builder.assign(val[0], val[1], - @builder.array(nil, val[2], nil)) - } - | mlhs tEQL arg_value - { - result = @builder.multi_assign(val[0], val[1], val[2]) - } - | mlhs tEQL mrhs - { - result = @builder.multi_assign(val[0], val[1], - @builder.array(nil, val[2], nil)) - } - | expr - - expr: command_call - | expr kAND expr - { - result = @builder.logical_op(:and, val[0], val[1], val[2]) - } - | expr kOR expr - { - result = @builder.logical_op(:or, val[0], val[1], val[2]) - } - | kNOT opt_nl expr - { - result = @builder.not_op(val[0], nil, val[2], nil) - } - | tBANG command_call - { - result = @builder.not_op(val[0], nil, val[1], nil) - } - | arg - - expr_value: expr - - command_call: command - | block_command - - block_command: block_call - | block_call tDOT operation2 command_args - { - result = @builder.call_method(val[0], val[1], val[2], - *val[3]) - } - | block_call tCOLON2 operation2 command_args - { - result = @builder.call_method(val[0], val[1], val[2], - *val[3]) - } - - cmd_brace_block: tLBRACE_ARG - { - @static_env.extend_dynamic - } - opt_block_param compstmt tRCURLY - { - result = [ val[0], val[2], val[3], val[4] ] - - @static_env.unextend - } - - command: operation command_args =tLOWEST - { - result = @builder.call_method(nil, nil, val[0], - *val[1]) - } - | operation command_args cmd_brace_block - { - method_call = @builder.call_method(nil, nil, val[0], - *val[1]) - - begin_t, args, body, end_t = val[2] - result = @builder.block(method_call, - begin_t, args, body, end_t) - } - | primary_value tDOT operation2 command_args =tLOWEST - { - result = @builder.call_method(val[0], val[1], val[2], - *val[3]) - } - | primary_value tDOT operation2 command_args cmd_brace_block - { - method_call = @builder.call_method(val[0], val[1], val[2], - *val[3]) - - begin_t, args, body, end_t = val[4] - result = @builder.block(method_call, - begin_t, args, body, end_t) - } - | primary_value tCOLON2 operation2 command_args =tLOWEST - { - result = @builder.call_method(val[0], val[1], val[2], - *val[3]) - } - | primary_value tCOLON2 operation2 command_args cmd_brace_block - { - method_call = @builder.call_method(val[0], val[1], val[2], - *val[3]) - - begin_t, args, body, end_t = val[4] - result = @builder.block(method_call, - begin_t, args, body, end_t) - } - | kSUPER command_args - { - result = @builder.keyword_cmd(:super, val[0], - *val[1]) - } - | kYIELD command_args - { - result = @builder.keyword_cmd(:yield, val[0], - *val[1]) - } - | kRETURN call_args - { - result = @builder.keyword_cmd(:return, val[0], - nil, val[1], nil) - } - | kBREAK call_args - { - result = @builder.keyword_cmd(:break, val[0], - nil, val[1], nil) - } - | kNEXT call_args - { - result = @builder.keyword_cmd(:next, val[0], - nil, val[1], nil) - } - - mlhs: mlhs_basic - { - result = @builder.multi_lhs(nil, val[0], nil) - } - | tLPAREN mlhs_inner rparen - { - result = @builder.begin(val[0], val[1], val[2]) - } - - mlhs_inner: mlhs_basic - { - result = @builder.multi_lhs(nil, val[0], nil) - } - | tLPAREN mlhs_inner rparen - { - result = @builder.multi_lhs(val[0], val[1], val[2]) - } - - mlhs_basic: mlhs_head - | mlhs_head mlhs_item - { - result = val[0]. - push(val[1]) - } - | mlhs_head tSTAR mlhs_node - { - result = val[0]. - push(@builder.splat(val[1], val[2])) - } - | mlhs_head tSTAR mlhs_node tCOMMA mlhs_post - { - result = val[0]. - push(@builder.splat(val[1], val[2])). - concat(val[4]) - } - | mlhs_head tSTAR - { - result = val[0]. - push(@builder.splat(val[1])) - } - | mlhs_head tSTAR tCOMMA mlhs_post - { - result = val[0]. - push(@builder.splat(val[1])). - concat(val[3]) - } - | tSTAR mlhs_node - { - result = [ @builder.splat(val[0], val[1]) ] - } - | tSTAR mlhs_node tCOMMA mlhs_post - { - result = [ @builder.splat(val[0], val[1]), - *val[3] ] - } - | tSTAR - { - result = [ @builder.splat(val[0]) ] - } - | tSTAR tCOMMA mlhs_post - { - result = [ @builder.splat(val[0]), - *val[2] ] - } - - mlhs_item: mlhs_node - | tLPAREN mlhs_inner rparen - { - result = @builder.begin(val[0], val[1], val[2]) - } - - mlhs_head: mlhs_item tCOMMA - { - result = [ val[0] ] - } - | mlhs_head mlhs_item tCOMMA - { - result = val[0] << val[1] - } - - mlhs_post: mlhs_item - { - result = [ val[0] ] - } - | mlhs_post tCOMMA mlhs_item - { - result = val[0] << val[2] - } - - mlhs_node: variable - { - result = @builder.assignable(val[0]) - } - | primary_value tLBRACK2 opt_call_args rbracket - { - result = @builder.index_asgn(val[0], val[1], val[2], val[3]) - } - | primary_value tDOT tIDENTIFIER - { - result = @builder.attr_asgn(val[0], val[1], val[2]) - } - | primary_value tCOLON2 tIDENTIFIER - { - result = @builder.attr_asgn(val[0], val[1], val[2]) - } - | primary_value tDOT tCONSTANT - { - result = @builder.attr_asgn(val[0], val[1], val[2]) - } - | primary_value tCOLON2 tCONSTANT - { - result = @builder.assignable( - @builder.const_fetch(val[0], val[1], val[2])) - } - | tCOLON3 tCONSTANT - { - result = @builder.assignable( - @builder.const_global(val[0], val[1])) - } - | backref - { - result = @builder.assignable(val[0]) - } - - lhs: variable - { - result = @builder.assignable(val[0]) - } - | primary_value tLBRACK2 opt_call_args rbracket - { - result = @builder.index_asgn(val[0], val[1], val[2], val[3]) - } - | primary_value tDOT tIDENTIFIER - { - result = @builder.attr_asgn(val[0], val[1], val[2]) - } - | primary_value tCOLON2 tIDENTIFIER - { - result = @builder.attr_asgn(val[0], val[1], val[2]) - } - | primary_value tDOT tCONSTANT - { - result = @builder.attr_asgn(val[0], val[1], val[2]) - } - | primary_value tCOLON2 tCONSTANT - { - result = @builder.assignable( - @builder.const_fetch(val[0], val[1], val[2])) - } - | tCOLON3 tCONSTANT - { - result = @builder.assignable( - @builder.const_global(val[0], val[1])) - } - | backref - { - result = @builder.assignable(val[0]) - } - - cname: tIDENTIFIER - { - diagnostic :error, :module_name_const, nil, val[0] - } - | tCONSTANT - - cpath: tCOLON3 cname - { - result = @builder.const_global(val[0], val[1]) - } - | cname - { - result = @builder.const(val[0]) - } - | primary_value tCOLON2 cname - { - result = @builder.const_fetch(val[0], val[1], val[2]) - } - - fname: tIDENTIFIER | tCONSTANT | tFID - | op - | reswords - - fsym: fname - { - result = @builder.symbol(val[0]) - } - | symbol - - fitem: fsym - | dsym - - undef_list: fitem - { - result = [ val[0] ] - } - | undef_list tCOMMA - { - @lexer.state = :expr_fname - } - fitem - { - result = val[0] << val[3] - } - - op: tPIPE | tCARET | tAMPER2 | tCMP | tEQ | tEQQ - | tMATCH | tNMATCH | tGT | tGEQ | tLT | tLEQ - | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2 - | tSTAR | tDIVIDE | tPERCENT | tPOW | tBANG | tTILDE - | tUPLUS | tUMINUS | tAREF | tASET | tBACK_REF2 - - reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND - | kALIAS | kAND | kBEGIN | kBREAK | kCASE - | kCLASS | kDEF | kDEFINED | kDO | kELSE - | kELSIF | kEND | kENSURE | kFALSE | kFOR - | kIN | kMODULE | kNEXT | kNIL | kNOT - | kOR | kREDO | kRESCUE | kRETRY | kRETURN - | kSELF | kSUPER | kTHEN | kTRUE | kUNDEF - | kWHEN | kYIELD | kIF | kUNLESS | kWHILE - | kUNTIL - - arg: lhs tEQL arg - { - result = @builder.assign(val[0], val[1], val[2]) - } - | lhs tEQL arg kRESCUE_MOD arg - { - rescue_body = @builder.rescue_body(val[3], - nil, nil, nil, - nil, val[4]) - - rescue_ = @builder.begin_body(val[2], [ rescue_body ]) - - result = @builder.assign(val[0], val[1], rescue_) - } - | var_lhs tOP_ASGN arg - { - result = @builder.op_assign(val[0], val[1], val[2]) - } - | var_lhs tOP_ASGN arg kRESCUE_MOD arg - { - rescue_body = @builder.rescue_body(val[3], - nil, nil, nil, - nil, val[4]) - - rescue_ = @builder.begin_body(val[2], [ rescue_body ]) - - result = @builder.op_assign(val[0], val[1], rescue_) - } - | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN arg - { - result = @builder.op_assign( - @builder.index( - val[0], val[1], val[2], val[3]), - val[4], val[5]) - } - | primary_value tDOT tIDENTIFIER tOP_ASGN arg - { - result = @builder.op_assign( - @builder.call_method( - val[0], val[1], val[2]), - val[3], val[4]) - } - | primary_value tDOT tCONSTANT tOP_ASGN arg - { - result = @builder.op_assign( - @builder.call_method( - val[0], val[1], val[2]), - val[3], val[4]) - } - | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg - { - result = @builder.op_assign( - @builder.call_method( - val[0], val[1], val[2]), - val[3], val[4]) - } - | primary_value tCOLON2 tCONSTANT tOP_ASGN arg - { - diagnostic :error, :dynamic_const, nil, val[2], [ val[3] ] - } - | tCOLON3 tCONSTANT tOP_ASGN arg - { - diagnostic :error, :dynamic_const, nil, val[1], [ val[2] ] - } - | backref tOP_ASGN arg - { - result = @builder.op_assign(val[0], val[1], val[2]) - } - | arg tDOT2 arg - { - result = @builder.range_inclusive(val[0], val[1], val[2]) - } - | arg tDOT3 arg - { - result = @builder.range_exclusive(val[0], val[1], val[2]) - } - | arg tPLUS arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tMINUS arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tSTAR2 arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tDIVIDE arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tPERCENT arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tPOW arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | tUMINUS_NUM tINTEGER tPOW arg - { - result = @builder.unary_op(val[0], - @builder.binary_op( - @builder.integer(val[1]), - val[2], val[3])) - } - | tUMINUS_NUM tFLOAT tPOW arg - { - result = @builder.unary_op(val[0], - @builder.binary_op( - @builder.float(val[1]), - val[2], val[3])) - } - | tUPLUS arg - { - result = @builder.unary_op(val[0], val[1]) - } - | tUMINUS arg - { - result = @builder.unary_op(val[0], val[1]) - } - | arg tPIPE arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tCARET arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tAMPER2 arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tCMP arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tGT arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tGEQ arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tLT arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tLEQ arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tEQ arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tEQQ arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tNEQ arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tMATCH arg - { - result = @builder.match_op(val[0], val[1], val[2]) - } - | arg tNMATCH arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | tBANG arg - { - result = @builder.not_op(val[0], nil, val[1], nil) - } - | tTILDE arg - { - result = @builder.unary_op(val[0], val[1]) - } - | arg tLSHFT arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tRSHFT arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tANDOP arg - { - result = @builder.logical_op(:and, val[0], val[1], val[2]) - } - | arg tOROP arg - { - result = @builder.logical_op(:or, val[0], val[1], val[2]) - } - | kDEFINED opt_nl arg - { - result = @builder.keyword_cmd(:defined?, val[0], nil, [ val[2] ], nil) - } - - | arg tEH arg opt_nl tCOLON arg - { - result = @builder.ternary(val[0], val[1], - val[2], val[4], val[5]) - } - | primary - - arg_value: arg - - aref_args: none - | args trailer - | args tCOMMA assocs trailer - { - result = val[0] << @builder.associate(nil, val[2], nil) - } - | assocs trailer - { - result = [ @builder.associate(nil, val[0], nil) ] - } - - paren_args: tLPAREN2 opt_call_args rparen - { - result = val - } - - opt_paren_args: # nothing - { - result = [ nil, [], nil ] - } - | paren_args - - opt_call_args: # nothing - { - result = [] - } - | call_args - - call_args: command - { - result = [ val[0] ] - } - | args opt_block_arg - { - result = val[0].concat(val[1]) - } - | assocs opt_block_arg - { - result = [ @builder.associate(nil, val[0], nil) ] - result.concat(val[1]) - } - | args tCOMMA assocs opt_block_arg - { - assocs = @builder.associate(nil, val[2], nil) - result = val[0] << assocs - result.concat(val[3]) - } - | args tCOMMA assocs tCOMMA args opt_block_arg - { - val[2][-1] = @builder.objc_varargs(val[2][-1], val[4]) - assocs = @builder.associate(nil, val[2], nil) - result = val[0] << assocs - result.concat(val[5]) - } - | block_arg - { - result = [ val[0] ] - } - - call_args2: arg_value tCOMMA args opt_block_arg - { - result = [ val[0], *val[2].concat(val[3]) ] - } - | arg_value tCOMMA block_arg - { - result = [ val[0], val[2] ] - } - | assocs opt_block_arg - { - result = [ @builder.associate(nil, val[0], nil), - *val[1] ] - } - | arg_value tCOMMA assocs opt_block_arg - { - result = [ val[0], - @builder.associate(nil, val[2], nil), - *val[3] ] - } - | arg_value tCOMMA args tCOMMA assocs opt_block_arg - { - result = [ val[0], - *val[2]. - push(@builder.associate(nil, val[4], nil)). - concat(val[5]) ] - } - | block_arg - { - result = [ val[0] ] - } - - command_args: { - result = @lexer.cmdarg.dup - @lexer.cmdarg.push(true) - } - open_args - { - @lexer.cmdarg = val[0] - - result = val[1] - } - - open_args: call_args - { - result = [ nil, val[0], nil ] - } - | tLPAREN_ARG - { - @lexer.state = :expr_endarg - } - rparen - { - result = [ val[0], [], val[2] ] - } - | tLPAREN_ARG call_args2 - { - @lexer.state = :expr_endarg - } - rparen - { - result = [ val[0], val[1], val[3] ] - } - - block_arg: tAMPER arg_value - { - result = @builder.block_pass(val[0], val[1]) - } - - opt_block_arg: tCOMMA block_arg - { - result = [ val[1] ] - } - | tCOMMA - { - result = [] - } - | # nothing - { - result = [] - } - - args: arg_value - { - result = [ val[0] ] - } - | tSTAR arg_value - { - result = [ @builder.splat(val[0], val[1]) ] - } - | args tCOMMA arg_value - { - result = val[0] << val[2] - } - | args tCOMMA tSTAR arg_value - { - result = val[0] << @builder.splat(val[2], val[3]) - } - - mrhs: args tCOMMA arg_value - { - result = val[0] << val[2] - } - | args tCOMMA tSTAR arg_value - { - result = val[0] << @builder.splat(val[2], val[3]) - } - | tSTAR arg_value - { - result = [ @builder.splat(val[0], val[1]) ] - } - - primary: literal - | strings - | xstring - | regexp - | words - | qwords - | var_ref - | backref - | tFID - { - result = @builder.call_method(nil, nil, val[0]) - } - | kBEGIN bodystmt kEND - { - result = @builder.begin_keyword(val[0], val[1], val[2]) - } - | tLPAREN_ARG expr - { - @lexer.state = :expr_endarg - } - rparen - { - result = @builder.begin(val[0], val[1], val[3]) - } - | tLPAREN compstmt tRPAREN - { - result = @builder.begin(val[0], val[1], val[2]) - } - | primary_value tCOLON2 tCONSTANT - { - result = @builder.const_fetch(val[0], val[1], val[2]) - } - | tCOLON3 tCONSTANT - { - result = @builder.const_global(val[0], val[1]) - } - | tLBRACK aref_args tRBRACK - { - result = @builder.array(val[0], val[1], val[2]) - } - | tLBRACE assoc_list tRCURLY - { - result = @builder.associate(val[0], val[1], val[2]) - } - | kRETURN - { - result = @builder.keyword_cmd(:return, val[0]) - } - | kYIELD tLPAREN2 call_args rparen - { - result = @builder.keyword_cmd(:yield, val[0], val[1], val[2], val[3]) - } - | kYIELD tLPAREN2 rparen - { - result = @builder.keyword_cmd(:yield, val[0], val[1], [], val[2]) - } - | kYIELD - { - result = @builder.keyword_cmd(:yield, val[0]) - } - | kDEFINED opt_nl tLPAREN2 expr rparen - { - result = @builder.keyword_cmd(:defined?, val[0], - val[2], [ val[3] ], val[4]) - } - | kNOT tLPAREN2 expr rparen - { - result = @builder.not_op(val[0], val[1], val[2], val[3]) - } - | kNOT tLPAREN2 rparen - { - result = @builder.not_op(val[0], val[1], nil, val[2]) - } - | operation brace_block - { - method_call = @builder.call_method(nil, nil, val[0]) - - begin_t, args, body, end_t = val[1] - result = @builder.block(method_call, - begin_t, args, body, end_t) - } - | method_call - | method_call brace_block - { - begin_t, args, body, end_t = val[1] - result = @builder.block(val[0], - begin_t, args, body, end_t) - } - | tLAMBDA lambda - { - lambda_call = @builder.call_lambda(val[0]) - - args, (begin_t, body, end_t) = val[1] - result = @builder.block(lambda_call, - begin_t, args, body, end_t) - } - | kIF expr_value then compstmt if_tail kEND - { - else_t, else_ = val[4] - result = @builder.condition(val[0], val[1], val[2], - val[3], else_t, - else_, val[5]) - } - | kUNLESS expr_value then compstmt opt_else kEND - { - else_t, else_ = val[4] - result = @builder.condition(val[0], val[1], val[2], - else_, else_t, - val[3], val[5]) - } - | kWHILE - { - @lexer.cond.push(true) - } - expr_value do - { - @lexer.cond.pop - } - compstmt kEND - { - result = @builder.loop(:while, val[0], val[2], val[3], - val[5], val[6]) - } - | kUNTIL - { - @lexer.cond.push(true) - } - expr_value do - { - @lexer.cond.pop - } - compstmt kEND - { - result = @builder.loop(:until, val[0], val[2], val[3], - val[5], val[6]) - } - | kCASE expr_value opt_terms case_body kEND - { - *when_bodies, (else_t, else_body) = *val[3] - - result = @builder.case(val[0], val[1], - when_bodies, else_t, else_body, - val[4]) - } - | kCASE opt_terms case_body kEND - { - *when_bodies, (else_t, else_body) = *val[2] - - result = @builder.case(val[0], nil, - when_bodies, else_t, else_body, - val[3]) - } - | kFOR for_var kIN - { - @lexer.cond.push(true) - } - expr_value do - { - @lexer.cond.pop - } - compstmt kEND - { - result = @builder.for(val[0], val[1], - val[2], val[4], - val[5], val[7], val[8]) - } - | kCLASS cpath superclass - { - @static_env.extend_static - @lexer.push_cmdarg - } - bodystmt kEND - { - if in_def? - diagnostic :error, :class_in_def, nil, val[0] - end - - lt_t, superclass = val[2] - result = @builder.def_class(val[0], val[1], - lt_t, superclass, - val[4], val[5]) - - @lexer.pop_cmdarg - @static_env.unextend - } - | kCLASS tLSHFT expr term - { - result = @def_level - @def_level = 0 - - @static_env.extend_static - @lexer.push_cmdarg - } - bodystmt kEND - { - result = @builder.def_sclass(val[0], val[1], val[2], - val[5], val[6]) - - @lexer.pop_cmdarg - @static_env.unextend - - @def_level = val[4] - } - | kMODULE cpath - { - @static_env.extend_static - @lexer.push_cmdarg - } - bodystmt kEND - { - if in_def? - diagnostic :error, :module_in_def, nil, val[0] - end - - result = @builder.def_module(val[0], val[1], - val[3], val[4]) - - @lexer.pop_cmdarg - @static_env.unextend - } - | kDEF fname - { - @def_level += 1 - @static_env.extend_static - @lexer.push_cmdarg - } - f_arglist bodystmt kEND - { - result = @builder.def_method(val[0], val[1], - val[3], val[4], val[5]) - - @lexer.pop_cmdarg - @static_env.unextend - @def_level -= 1 - } - | kDEF singleton dot_or_colon - { - @lexer.state = :expr_fname - } - fname - { - @def_level += 1 - @static_env.extend_static - @lexer.push_cmdarg - } - f_arglist bodystmt kEND - { - result = @builder.def_singleton(val[0], val[1], val[2], - val[4], val[6], val[7], val[8]) - - @lexer.pop_cmdarg - @static_env.unextend - @def_level -= 1 - } - | kBREAK - { - result = @builder.keyword_cmd(:break, val[0]) - } - | kNEXT - { - result = @builder.keyword_cmd(:next, val[0]) - } - | kREDO - { - result = @builder.keyword_cmd(:redo, val[0]) - } - | kRETRY - { - result = @builder.keyword_cmd(:retry, val[0]) - } - - primary_value: primary - - then: term - | kTHEN - | term kTHEN - { - result = val[1] - } - - do: term - | kDO_COND - - if_tail: opt_else - | kELSIF expr_value then compstmt if_tail - { - else_t, else_ = val[4] - result = [ val[0], - @builder.condition(val[0], val[1], val[2], - val[3], else_t, - else_, nil), - ] - } - - opt_else: none - | kELSE compstmt - { - result = val - } - - for_var: lhs - | mlhs - - f_marg: f_norm_arg - | tLPAREN f_margs rparen - { - result = @builder.multi_lhs(val[0], val[1], val[2]) - } - - f_marg_list: f_marg - { - result = [ val[0] ] - } - | f_marg_list tCOMMA f_marg - { - result = val[0] << val[2] - } - - f_margs: f_marg_list - | f_marg_list tCOMMA tSTAR f_norm_arg - { - result = val[0]. - push(@builder.objc_restarg(val[2], val[3])) - } - | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list - { - result = val[0]. - push(@builder.objc_restarg(val[2], val[3])). - concat(val[5]) - } - | f_marg_list tCOMMA tSTAR - { - result = val[0]. - push(@builder.objc_restarg(val[2])) - } - | f_marg_list tCOMMA tSTAR tCOMMA f_marg_list - { - result = val[0]. - push(@builder.objc_restarg(val[2])). - concat(val[4]) - } - | tSTAR f_norm_arg - { - result = [ @builder.objc_restarg(val[0], val[1]) ] - } - | tSTAR f_norm_arg tCOMMA f_marg_list - { - result = [ @builder.objc_restarg(val[0], val[1]), - *val[3] ] - } - | tSTAR - { - result = [ @builder.objc_restarg(val[0]) ] - } - | tSTAR tCOMMA f_marg_list - { - result = [ @builder.objc_restarg(val[0]), - *val[2] ] - } - - block_param: f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg opt_f_block_arg - { - result = val[0]. - concat(val[2]). - concat(val[4]). - concat(val[5]) - } - | f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_f_block_arg - { - result = val[0]. - concat(val[2]). - concat(val[4]). - concat(val[6]). - concat(val[7]) - } - | f_arg tCOMMA f_block_optarg opt_f_block_arg - { - result = val[0]. - concat(val[2]). - concat(val[3]) - } - | f_arg tCOMMA f_block_optarg tCOMMA f_arg opt_f_block_arg - { - result = val[0]. - concat(val[2]). - concat(val[4]). - concat(val[5]) - } - | f_arg tCOMMA f_rest_arg opt_f_block_arg - { - result = val[0]. - concat(val[2]). - concat(val[3]) - } - | f_arg tCOMMA - | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_f_block_arg - { - result = val[0]. - concat(val[2]). - concat(val[4]). - concat(val[5]) - } - | f_arg opt_f_block_arg - { - result = val[0].concat(val[1]) - } - | f_block_optarg tCOMMA f_rest_arg opt_f_block_arg - { - result = val[0]. - concat(val[2]). - concat(val[3]) - } - | f_block_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_f_block_arg - { - result = val[0]. - concat(val[2]). - concat(val[4]). - concat(val[5]) - } - | f_block_optarg opt_f_block_arg - { - result = val[0]. - concat(val[1]) - } - | f_block_optarg tCOMMA f_arg opt_f_block_arg - { - result = val[0]. - concat(val[2]). - concat(val[3]) - } - | f_rest_arg opt_f_block_arg - { - result = val[0]. - concat(val[1]) - } - | f_rest_arg tCOMMA f_arg opt_f_block_arg - { - result = val[0]. - concat(val[2]). - concat(val[3]) - } - | f_block_arg - { - result = [ val[0] ] - } - - opt_block_param: # nothing - { - result = @builder.args(nil, [], nil) - } - | block_param_def - { - @lexer.state = :expr_value - } - - block_param_def: tPIPE opt_bv_decl tPIPE - { - result = @builder.args(val[0], val[1], val[2]) - } - | tOROP - { - result = @builder.args(val[0], [], val[0]) - } - | tPIPE block_param opt_bv_decl tPIPE - { - result = @builder.args(val[0], val[1].concat(val[2]), val[3]) - } - - opt_bv_decl: # nothing - { - result = [] - } - | tSEMI bv_decls - { - result = val[1] - } - - bv_decls: bvar - { - result = [ val[0] ] - } - | bv_decls tCOMMA bvar - { - result = val[0] << val[2] - } - - bvar: tIDENTIFIER - { - result = @builder.shadowarg(val[0]) - } - | f_bad_arg - - lambda: { - @static_env.extend_dynamic - } - f_larglist lambda_body - { - result = [ val[1], val[2] ] - - @static_env.unextend - } - - f_larglist: tLPAREN2 f_args opt_bv_decl rparen - { - result = @builder.args(val[0], val[1].concat(val[2]), val[3]) - } - | f_args - { - result = @builder.args(nil, val[0], nil) - } - - lambda_body: tLAMBEG compstmt tRCURLY - { - result = [ val[0], val[1], val[2] ] - } - | kDO_LAMBDA compstmt kEND - { - result = [ val[0], val[1], val[2] ] - } - - do_block: kDO_BLOCK - { - @static_env.extend_dynamic - } - opt_block_param compstmt kEND - { - result = [ val[0], val[2], val[3], val[4] ] - - @static_env.unextend - } - - block_call: command do_block - { - begin_t, block_args, body, end_t = val[1] - result = @builder.block(val[0], - begin_t, block_args, body, end_t) - } - | block_call tDOT operation2 opt_paren_args - { - lparen_t, args, rparen_t = val[3] - result = @builder.call_method(val[0], val[1], val[2], - lparen_t, args, rparen_t) - } - | block_call tCOLON2 operation2 opt_paren_args - { - lparen_t, args, rparen_t = val[3] - result = @builder.call_method(val[0], val[1], val[2], - lparen_t, args, rparen_t) - } - - method_call: operation paren_args - { - lparen_t, args, rparen_t = val[1] - result = @builder.call_method(nil, nil, val[0], - lparen_t, args, rparen_t) - } - | primary_value tDOT operation2 opt_paren_args - { - lparen_t, args, rparen_t = val[3] - result = @builder.call_method(val[0], val[1], val[2], - lparen_t, args, rparen_t) - } - | primary_value tCOLON2 operation2 paren_args - { - lparen_t, args, rparen_t = val[3] - result = @builder.call_method(val[0], val[1], val[2], - lparen_t, args, rparen_t) - } - | primary_value tCOLON2 operation3 - { - result = @builder.call_method(val[0], val[1], val[2]) - } - | primary_value tDOT paren_args - { - lparen_t, args, rparen_t = val[2] - result = @builder.call_method(val[0], val[1], nil, - lparen_t, args, rparen_t) - } - | primary_value tCOLON2 paren_args - { - lparen_t, args, rparen_t = val[2] - result = @builder.call_method(val[0], val[1], nil, - lparen_t, args, rparen_t) - } - | kSUPER paren_args - { - lparen_t, args, rparen_t = val[1] - result = @builder.keyword_cmd(:super, val[0], - lparen_t, args, rparen_t) - } - | kSUPER - { - result = @builder.keyword_cmd(:zsuper, val[0]) - } - | primary_value tLBRACK2 opt_call_args rbracket - { - result = @builder.index(val[0], val[1], val[2], val[3]) - } - - brace_block: tLCURLY - { - @static_env.extend_dynamic - } - opt_block_param compstmt tRCURLY - { - result = [ val[0], val[2], val[3], val[4] ] - - @static_env.unextend - } - | kDO - { - @static_env.extend_dynamic - } - opt_block_param compstmt kEND - { - result = [ val[0], val[2], val[3], val[4] ] - - @static_env.unextend - } - - case_body: kWHEN args then compstmt cases - { - result = [ @builder.when(val[0], val[1], val[2], val[3]), - *val[4] ] - } - - cases: opt_else - { - result = [ val[0] ] - } - | case_body - - opt_rescue: kRESCUE exc_list exc_var then compstmt opt_rescue - { - assoc_t, exc_var = val[2] - - if val[1] - exc_list = @builder.array(nil, val[1], nil) - end - - result = [ @builder.rescue_body(val[0], - exc_list, assoc_t, exc_var, - val[3], val[4]), - *val[5] ] - } - | - { - result = [] - } - - exc_list: arg_value - { - result = [ val[0] ] - } - | mrhs - | none - - exc_var: tASSOC lhs - { - result = [ val[0], val[1] ] - } - | none - - opt_ensure: kENSURE compstmt - { - result = [ val[0], val[1] ] - } - | none - - literal: numeric - | symbol - | dsym - - strings: string - { - result = @builder.string_compose(nil, val[0], nil) - } - - string: string1 - { - result = [ val[0] ] - } - | string string1 - { - result = val[0] << val[1] - } - - string1: tSTRING_BEG string_contents tSTRING_END - { - result = @builder.string_compose(val[0], val[1], val[2]) - } - | tSTRING - { - result = @builder.string(val[0]) - } - | tCHARACTER - { - result = @builder.character(val[0]) - } - - xstring: tXSTRING_BEG xstring_contents tSTRING_END - { - result = @builder.xstring_compose(val[0], val[1], val[2]) - } - - regexp: tREGEXP_BEG regexp_contents tSTRING_END tREGEXP_OPT - { - opts = @builder.regexp_options(val[3]) - result = @builder.regexp_compose(val[0], val[1], val[2], opts) - } - - words: tWORDS_BEG word_list tSTRING_END - { - result = @builder.words_compose(val[0], val[1], val[2]) - } - - word_list: # nothing - { - result = [] - } - | word_list word tSPACE - { - result = val[0] << @builder.word(val[1]) - } - - word: string_content - { - result = [ val[0] ] - } - | word string_content - { - result = val[0] << val[1] - } - - qwords: tQWORDS_BEG qword_list tSTRING_END - { - result = @builder.words_compose(val[0], val[1], val[2]) - } - - qword_list: # nothing - { - result = [] - } - | qword_list tSTRING_CONTENT tSPACE - { - result = val[0] << @builder.string_internal(val[1]) - } - - string_contents: # nothing - { - result = [] - } - | string_contents string_content - { - result = val[0] << val[1] - } - -xstring_contents: # nothing - { - result = [] - } - | xstring_contents string_content - { - result = val[0] << val[1] - } - -regexp_contents: # nothing - { - result = [] - } - | regexp_contents string_content - { - result = val[0] << val[1] - } - - string_content: tSTRING_CONTENT - { - result = @builder.string_internal(val[0]) - } - | tSTRING_DVAR string_dvar - { - result = val[1] - } - | tSTRING_DBEG - { - @lexer.cond.push(false) - @lexer.cmdarg.push(false) - } - compstmt tRCURLY - { - @lexer.cond.lexpop - @lexer.cmdarg.lexpop - - result = @builder.begin(val[0], val[2], val[3]) - } - - string_dvar: tGVAR - { - result = @builder.gvar(val[0]) - } - | tIVAR - { - result = @builder.ivar(val[0]) - } - | tCVAR - { - result = @builder.cvar(val[0]) - } - | backref - - - symbol: tSYMBOL - { - result = @builder.symbol(val[0]) - } - - dsym: tSYMBEG xstring_contents tSTRING_END - { - result = @builder.symbol_compose(val[0], val[1], val[2]) - } - - numeric: tINTEGER - { - result = @builder.integer(val[0]) - } - | tFLOAT - { - result = @builder.float(val[0]) - } - | tUMINUS_NUM tINTEGER =tLOWEST - { - result = @builder.negate(val[0], - @builder.integer(val[1])) - } - | tUMINUS_NUM tFLOAT =tLOWEST - { - result = @builder.negate(val[0], - @builder.float(val[1])) - } - - variable: tIDENTIFIER - { - result = @builder.ident(val[0]) - } - | tIVAR - { - result = @builder.ivar(val[0]) - } - | tGVAR - { - result = @builder.gvar(val[0]) - } - | tCONSTANT - { - result = @builder.const(val[0]) - } - | tCVAR - { - result = @builder.cvar(val[0]) - } - | kNIL - { - result = @builder.nil(val[0]) - } - | kSELF - { - result = @builder.self(val[0]) - } - | kTRUE - { - result = @builder.true(val[0]) - } - | kFALSE - { - result = @builder.false(val[0]) - } - | k__FILE__ - { - result = @builder.__FILE__(val[0]) - } - | k__LINE__ - { - result = @builder.__LINE__(val[0]) - } - | k__ENCODING__ - { - result = @builder.__ENCODING__(val[0]) - } - - var_ref: variable - { - result = @builder.accessible(val[0]) - } - - var_lhs: variable - { - result = @builder.assignable(val[0]) - } - - backref: tNTH_REF - { - result = @builder.nth_ref(val[0]) - } - | tBACK_REF - { - result = @builder.back_ref(val[0]) - } - - superclass: term - { - result = nil - } - | tLT expr_value term - { - result = [ val[0], val[1] ] - } - | error term - { - yyerrok - result = nil - } - - f_arglist: tLPAREN2 f_args rparen - { - result = @builder.args(val[0], val[1], val[2]) - - @lexer.state = :expr_value - } - | f_args term - { - result = @builder.args(nil, val[0], nil) - } - - f_args: f_arg tCOMMA f_optarg tCOMMA f_rest_arg opt_f_block_arg - { - result = val[0]. - concat(val[2]). - concat(val[4]). - concat(val[5]) - } - | f_arg tCOMMA f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_f_block_arg - { - result = val[0]. - concat(val[2]). - concat(val[4]). - concat(val[6]). - concat(val[7]) - } - | f_arg tCOMMA f_optarg opt_f_block_arg - { - result = val[0]. - concat(val[2]). - concat(val[3]) - } - | f_arg tCOMMA f_optarg tCOMMA f_arg opt_f_block_arg - { - result = val[0]. - concat(val[2]). - concat(val[4]). - concat(val[5]) - } - | f_arg tCOMMA f_rest_arg opt_f_block_arg - { - result = val[0]. - concat(val[2]). - concat(val[3]) - } - | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_f_block_arg - { - result = val[0]. - concat(val[2]). - concat(val[4]). - concat(val[5]) - } - | f_arg opt_f_block_arg - { - result = val[0]. - concat(val[1]) - } - | f_optarg tCOMMA f_rest_arg opt_f_block_arg - { - result = val[0]. - concat(val[2]). - concat(val[3]) - } - | f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_f_block_arg - { - result = val[0]. - concat(val[2]). - concat(val[4]). - concat(val[5]) - } - | f_optarg opt_f_block_arg - { - result = val[0]. - concat(val[1]) - } - | f_optarg tCOMMA f_arg opt_f_block_arg - { - result = val[0]. - concat(val[2]). - concat(val[3]) - } - | f_rest_arg opt_f_block_arg - { - result = val[0]. - concat(val[1]) - } - | f_rest_arg tCOMMA f_arg opt_f_block_arg - { - result = val[0]. - concat(val[2]). - concat(val[3]) - } - | f_block_arg - { - result = [ val[0] ] - } - | # nothing - { - result = [] - } - - f_bad_arg: tCONSTANT - { - diagnostic :error, :argument_const, nil, val[0] - } - | tIVAR - { - diagnostic :error, :argument_ivar, nil, val[0] - } - | tGVAR - { - diagnostic :error, :argument_gvar, nil, val[0] - } - | tCVAR - { - diagnostic :error, :argument_cvar, nil, val[0] - } - - f_norm_arg: f_bad_arg - | tIDENTIFIER - { - @static_env.declare val[0][0] - - result = @builder.arg(val[0]) - } - | tIDENTIFIER tASSOC tIDENTIFIER - { - @static_env.declare val[2][0] - - result = @builder.objc_kwarg(val[0], val[1], val[2]) - } - | tLABEL tIDENTIFIER - { - @static_env.declare val[1][0] - - result = @builder.objc_kwarg(val[0], nil, val[1]) - } - - f_arg_item: f_norm_arg - | tLPAREN f_margs rparen - { - result = @builder.multi_lhs(val[0], val[1], val[2]) - } - - f_arg: f_arg_item - { - result = [ val[0] ] - } - | f_arg tCOMMA f_arg_item - { - result = val[0] << val[2] - } - - f_opt: tIDENTIFIER tEQL arg_value - { - @static_env.declare val[0][0] - - result = @builder.optarg(val[0], val[1], val[2]) - } - - f_block_opt: tIDENTIFIER tEQL primary_value - { - @static_env.declare val[0][0] - - result = @builder.optarg(val[0], val[1], val[2]) - } - - f_block_optarg: f_block_opt - { - result = [ val[0] ] - } - | f_block_optarg tCOMMA f_block_opt - { - result = val[0] << val[2] - } - - f_optarg: f_opt - { - result = [ val[0] ] - } - | f_optarg tCOMMA f_opt - { - result = val[0] << val[2] - } - - restarg_mark: tSTAR2 | tSTAR - - f_rest_arg: restarg_mark tIDENTIFIER - { - @static_env.declare val[1][0] - - result = [ @builder.restarg(val[0], val[1]) ] - } - | restarg_mark - { - result = [ @builder.restarg(val[0]) ] - } - - blkarg_mark: tAMPER2 | tAMPER - - f_block_arg: blkarg_mark tIDENTIFIER - { - @static_env.declare val[1][0] - - result = @builder.blockarg(val[0], val[1]) - } - - opt_f_block_arg: tCOMMA f_block_arg - { - result = [ val[1] ] - } - | # nothing - { - result = [] - } - - singleton: var_ref - | tLPAREN2 expr rparen - { - result = val[1] - } - - assoc_list: # nothing - { - result = [] - } - | assocs trailer - - assocs: assoc - { - result = [ val[0] ] - } - | assocs tCOMMA assoc - { - result = val[0] << val[2] - } - - assoc: arg_value tASSOC arg_value - { - result = @builder.pair(val[0], val[1], val[2]) - } - | tLABEL arg_value - { - result = @builder.pair_keyword(val[0], val[1]) - } - - operation: tIDENTIFIER | tCONSTANT | tFID - operation2: tIDENTIFIER | tCONSTANT | tFID | op - operation3: tIDENTIFIER | tFID | op - dot_or_colon: tDOT | tCOLON2 - opt_terms: | terms - opt_nl: | tNL - rparen: opt_nl tRPAREN - { - result = val[1] - } - rbracket: opt_nl tRBRACK - { - result = val[1] - } - trailer: | tNL | tCOMMA - - term: tSEMI - { - yyerrok - } - | tNL - - terms: term - | terms tSEMI - - none: # nothing - { - result = nil - } -end - ----- header - -require 'parser' - -Parser.check_for_encoding_support - ----- inner - - def version - 19 # closest released match: v1_9_0_2 - end - - def default_encoding - Encoding::BINARY - end diff --git a/test/racc/assets/mailp.y b/test/racc/assets/mailp.y deleted file mode 100644 index eb7d4d529d..0000000000 --- a/test/racc/assets/mailp.y +++ /dev/null @@ -1,437 +0,0 @@ -# -# mailp for test -# - -class Testp - -rule - - content : DateH datetime { @field.date = val[1] } - | RecvH received - | RetpathH returnpath - | MaddrH addrs { @field.addrs.replace val[1] } - | SaddrH addr { @field.addr = val[1] } - | MmboxH mboxes { @field.addrs.replace val[1] } - | SmboxH mbox { @field.addr = val[1] } - | MsgidH msgid { @field.msgid = val[1] } - | KeyH keys { @field.keys.replace val[1] } - | EncH enc - | VersionH version - | CTypeH ctype - | CEncodingH cencode - | CDispositionH cdisp - | Mbox mbox - { - mb = val[1] - @field.phrase = mb.phrase - @field.setroute mb.route - @field.local = mb.local - @field.domain = mb.domain - } - | Spec spec - { - mb = val[1] - @field.local = mb.local - @field.domain = mb.domain - } - ; - - datetime : day DIGIT ATOM DIGIT hour zone - # 0 1 2 3 4 5 - # day month year - { - t = Time.gm( val[3].to_i, val[2], val[1].to_i, 0, 0, 0 ) - result = (t + val[4] - val[5]).localtime - } - ; - - day : /* none */ - | ATOM ',' - ; - - hour : DIGIT ':' DIGIT - { - result = (result.to_i * 60 * 60) + (val[2].to_i * 60) - } - | DIGIT ':' DIGIT ':' DIGIT - { - result = (result.to_i * 60 * 60) + - (val[2].to_i * 60) - + val[4].to_i - } - ; - - zone : ATOM - { - result = ::TMail.zonestr2i( val[0] ) * 60 - } - ; - - received : from by via with id for recvdatetime - ; - - from : /* none */ - | FROM domain - { - @field.from = Address.join( val[1] ) - } - | FROM domain '@' domain - { - @field.from = Address.join( val[3] ) - } - | FROM domain DOMLIT - { - @field.from = Address.join( val[1] ) - } - ; - - by : /* none */ - | BY domain - { - @field.by = Address.join( val[1] ) - } - ; - - via : /* none */ - | VIA ATOM - { - @field.via = val[1] - } - ; - - with : /* none */ - | WITH ATOM - { - @field.with.push val[1] - } - ; - - id : /* none */ - | ID msgid - { - @field.msgid = val[1] - } - | ID ATOM - { - @field.msgid = val[1] - } - ; - - for : /* none */ - | FOR addr - { - @field.for_ = val[1].address - } - ; - - recvdatetime - : /* none */ - | ';' datetime - { - @field.date = val[1] - } - ; - - returnpath: '<' '>' - | routeaddr - { - @field.route.replace result.route - @field.addr = result.addr - } - ; - - addrs : addr { result = val } - | addrs ',' addr { result.push val[2] } - ; - - addr : mbox - | group - ; - - mboxes : mbox - { - result = val - } - | mboxes ',' mbox - { - result.push val[2] - } - ; - - mbox : spec - | routeaddr - | phrase routeaddr - { - val[1].phrase = HFdecoder.decode( result ) - result = val[1] - } - ; - - group : phrase ':' mboxes ';' - { - result = AddressGroup.new( result, val[2] ) - } - # | phrase ':' ';' { result = AddressGroup.new( result ) } - ; - - routeaddr : '<' route spec '>' - { - result = val[2] - result.route = val[1] - } - | '<' spec '>' - { - result = val[1] - } - ; - - route : at_domains ':' - ; - - at_domains: '@' domain { result = [ val[1] ] } - | at_domains ',' '@' domain { result.push val[3] } - ; - - spec : local '@' domain { result = Address.new( val[0], val[2] ) } - | local { result = Address.new( result, nil ) } - ; - - local : word { result = val } - | local '.' word { result.push val[2] } - ; - - domain : domword { result = val } - | domain '.' domword { result.push val[2] } - ; - - domword : atom - | DOMLIT - | DIGIT - ; - - msgid : '<' spec '>' - { - val[1] = val[1].addr - result = val.join('') - } - ; - - phrase : word - | phrase word { result << ' ' << val[1] } - ; - - word : atom - | QUOTED - | DIGIT - ; - - keys : phrase - | keys ',' phrase - ; - - enc : word - { - @field.encrypter = val[0] - } - | word word - { - @field.encrypter = val[0] - @field.keyword = val[1] - } - ; - - version : DIGIT '.' DIGIT - { - @field.major = val[0].to_i - @field.minor = val[2].to_i - } - ; - - ctype : TOKEN '/' TOKEN params - { - @field.main = val[0] - @field.sub = val[2] - } - | TOKEN params - { - @field.main = val[0] - @field.sub = '' - } - ; - - params : /* none */ - | params ';' TOKEN '=' value - { - @field.params[ val[2].downcase ] = val[4] - } - ; - - value : TOKEN - | QUOTED - ; - - cencode : TOKEN - { - @field.encoding = val[0] - } - ; - - cdisp : TOKEN disp_params - { - @field.disposition = val[0] - } - ; - - disp_params - : /* none */ - | disp_params ';' disp_param - ; - - disp_param: /* none */ - | TOKEN '=' value - { - @field.params[ val[0].downcase ] = val[2] - } - ; - - atom : ATOM - | FROM - | BY - | VIA - | WITH - | ID - | FOR - ; - -end - - ----- header -# -# mailp for test -# - -require 'tmail/mails' - - -module TMail - ----- inner - - MAILP_DEBUG = false - - def initialize - self.debug = MAILP_DEBUG - end - - def debug=( flag ) - @yydebug = flag && Racc_debug_parser - @scanner_debug = flag - end - - def debug - @yydebug - end - - - def Mailp.parse( str, obj, ident ) - new.parse( str, obj, ident ) - end - - - NATIVE_ROUTINE = { - 'TMail::MsgidH' => :msgid_parse, - 'TMail::RefH' => :refs_parse - } - - def parse( str, obj, ident ) - return if /\A\s*\z/ === str - - @field = obj - - if mid = NATIVE_ROUTINE[ obj.type.name ] then - send mid, str - else - unless ident then - ident = obj.type.name.split('::')[-1].to_s - cmt = [] - obj.comments.replace cmt - else - cmt = nil - end - - @scanner = MailScanner.new( str, ident, cmt ) - @scanner.debug = @scanner_debug - @first = [ ident.intern, ident ] - @pass_array = [nil, nil] - - do_parse - end - end - - - private - - - def next_token - if @first then - ret = @first - @first = nil - ret - else - @scanner.scan @pass_array - end - end - - def on_error( tok, val, vstack ) - raise ParseError, - "\nparse error in '#{@field.name}' header, on token #{val.inspect}" - end - - - - def refs_parse( str ) - arr = [] - - while mdata = ::TMail::MSGID.match( str ) do - str = mdata.post_match - - pre = mdata.pre_match - pre.strip! - proc_phrase pre, arr unless pre.empty? - arr.push mdata.to_s - end - str.strip! - proc_phrase str, arr if not pre or pre.empty? - - @field.refs.replace arr - end - - def proc_phrase( str, arr ) - while mdata = /"([^\\]*(?:\\.[^"\\]*)*)"/.match( str ) do - str = mdata.post_match - - pre = mdata.pre_match - pre.strip! - arr.push pre unless pre.empty? - arr.push mdata[1] - end - str.strip! - arr.push unless str.empty? - end - - - def msgid_parse( str ) - if mdata = ::TMail::MSGID.match( str ) then - @field.msgid = mdata.to_s - else - raise ParseError, "wrong Message-ID format: #{str}" - end - end - ----- footer - -end # module TMail - -mp = TMail::Testp.new -mp.parse diff --git a/test/racc/assets/mediacloth.y b/test/racc/assets/mediacloth.y deleted file mode 100644 index 94cc411ea7..0000000000 --- a/test/racc/assets/mediacloth.y +++ /dev/null @@ -1,599 +0,0 @@ -# Copyright (c) 2006 Pluron Inc. -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -# The parser for the MediaWiki language. -# -# Usage together with a lexer: -# inputFile = File.new("data/input1", "r") -# input = inputFile.read -# parser = MediaWikiParser.new -# parser.lexer = MediaWikiLexer.new -# parser.parse(input) - -class MediaWikiParser - -token TEXT BOLD_START BOLD_END ITALIC_START ITALIC_END LINK_START LINK_END LINKSEP - INTLINK_START INTLINK_END INTLINKSEP RESOURCESEP CHAR_ENT - PRE_START PRE_END PREINDENT_START PREINDENT_END - SECTION_START SECTION_END HLINE SIGNATURE_NAME SIGNATURE_DATE SIGNATURE_FULL - PARA_START PARA_END UL_START UL_END OL_START OL_END LI_START LI_END - DL_START DL_END DT_START DT_END DD_START DD_END TAG_START TAG_END ATTR_NAME ATTR_VALUE - TABLE_START TABLE_END ROW_START ROW_END HEAD_START HEAD_END CELL_START CELL_END - KEYWORD TEMPLATE_START TEMPLATE_END CATEGORY PASTE_START PASTE_END - - -rule - -wiki: - repeated_contents - { - @nodes.push WikiAST.new(0, @wiki_ast_length) - #@nodes.last.children.insert(0, val[0]) - #puts val[0] - @nodes.last.children += val[0] - } - ; - -contents: - text - { - result = val[0] - } - | bulleted_list - { - result = val[0] - } - | numbered_list - { - result = val[0] - } - | dictionary_list - { - list = ListAST.new(@ast_index, @ast_length) - list.list_type = :Dictionary - list.children = val[0] - result = list - } - | preformatted - { - result = val[0] - } - | section - { - result = val[0] - } - | tag - { - result = val[0] - } - | template - { - result = val[0] - } - | KEYWORD - { - k = KeywordAST.new(@ast_index, @ast_length) - k.text = val[0] - result = k - } - | PARA_START para_contents PARA_END - { - p = ParagraphAST.new(@ast_index, @ast_length) - p.children = val[1] - result = p - } - | LINK_START link_contents LINK_END - { - l = LinkAST.new(@ast_index, @ast_length) - l.link_type = val[0] - l.url = val[1][0] - l.children += val[1][1..-1] if val[1].length > 1 - result = l - } - | PASTE_START para_contents PASTE_END - { - p = PasteAST.new(@ast_index, @ast_length) - p.children = val[1] - result = p - } - | INTLINK_START TEXT RESOURCESEP TEXT reslink_repeated_contents INTLINK_END - { - l = ResourceLinkAST.new(@ast_index, @ast_length) - l.prefix = val[1] - l.locator = val[3] - l.children = val[4] unless val[4].nil? or val[4].empty? - result = l - } - | INTLINK_START TEXT intlink_repeated_contents INTLINK_END - { - l = InternalLinkAST.new(@ast_index, @ast_length) - l.locator = val[1] - l.children = val[2] unless val[2].nil? or val[2].empty? - result = l - } - | INTLINK_START CATEGORY TEXT cat_sort_contents INTLINK_END - { - l = CategoryAST.new(@ast_index, @ast_length) - l.locator = val[2] - l.sort_as = val[3] - result = l - } - | INTLINK_START RESOURCESEP CATEGORY TEXT intlink_repeated_contents INTLINK_END - { - l = CategoryLinkAST.new(@ast_index, @ast_length) - l.locator = val[3] - l.children = val[4] unless val[4].nil? or val[4].empty? - result = l - } - | table - ; - -para_contents: - { - result = nil - } - | repeated_contents - { - result = val[0] - } - ; - -tag: - TAG_START tag_attributes TAG_END - { - if val[0] != val[2] - raise Racc::ParseError.new("XHTML end tag #{val[2]} does not match start tag #{val[0]}") - end - elem = ElementAST.new(@ast_index, @ast_length) - elem.name = val[0] - elem.attributes = val[1] - result = elem - } - | TAG_START tag_attributes repeated_contents TAG_END - { - if val[0] != val[3] - raise Racc::ParseError.new("XHTML end tag #{val[3]} does not match start tag #{val[0]}") - end - elem = ElementAST.new(@ast_index, @ast_length) - elem.name = val[0] - elem.attributes = val[1] - elem.children += val[2] - result = elem - } - ; - -tag_attributes: - { - result = nil - } - | ATTR_NAME tag_attributes - { - attr_map = val[2] ? val[2] : {} - attr_map[val[0]] = true - result = attr_map - } - | ATTR_NAME ATTR_VALUE tag_attributes - { - attr_map = val[2] ? val[2] : {} - attr_map[val[0]] = val[1] - result = attr_map - } - ; - - -link_contents: - TEXT - { - result = val - } - | TEXT LINKSEP link_repeated_contents - { - result = [val[0]] - result += val[2] - } - ; - - -link_repeated_contents: - repeated_contents - { - result = val[0] - } - | repeated_contents LINKSEP link_repeated_contents - { - result = val[0] - result += val[2] if val[2] - } - ; - - -intlink_repeated_contents: - { - result = nil - } - | INTLINKSEP repeated_contents - { - result = val[1] - } - ; - -cat_sort_contents: - { - result = nil - } - | INTLINKSEP TEXT - { - result = val[1] - } - ; - -reslink_repeated_contents: - { - result = nil - } - | INTLINKSEP reslink_repeated_contents - { - result = val[1] - } - | INTLINKSEP repeated_contents reslink_repeated_contents - { - i = InternalLinkItemAST.new(@ast_index, @ast_length) - i.children = val[1] - result = [i] - result += val[2] if val[2] - } - ; - -repeated_contents: contents - { - result = [] - result << val[0] - } - | repeated_contents contents - { - result = [] - result += val[0] - result << val[1] - } - ; - -text: element - { - p = TextAST.new(@ast_index, @ast_length) - p.formatting = val[0][0] - p.contents = val[0][1] - result = p - } - | formatted_element - { - result = val[0] - } - ; - -table: - TABLE_START table_contents TABLE_END - { - table = TableAST.new(@ast_index, @ast_length) - table.children = val[1] unless val[1].nil? or val[1].empty? - result = table - } - | TABLE_START TEXT table_contents TABLE_END - { - table = TableAST.new(@ast_index, @ast_length) - table.options = val[1] - table.children = val[2] unless val[2].nil? or val[2].empty? - result = table - } - -table_contents: - { - result = nil - } - | ROW_START row_contents ROW_END table_contents - { - row = TableRowAST.new(@ast_index, @ast_length) - row.children = val[1] unless val[1].nil? or val[1].empty? - result = [row] - result += val[3] unless val[3].nil? or val[3].empty? - } - | ROW_START TEXT row_contents ROW_END table_contents - { - row = TableRowAST.new(@ast_index, @ast_length) - row.children = val[2] unless val[2].nil? or val[2].empty? - row.options = val[1] - result = [row] - result += val[4] unless val[4].nil? or val[4].empty? - } - -row_contents: - { - result = nil - } - | HEAD_START HEAD_END row_contents - { - cell = TableCellAST.new(@ast_index, @ast_length) - cell.type = :head - result = [cell] - result += val[2] unless val[2].nil? or val[2].empty? - } - | HEAD_START repeated_contents HEAD_END row_contents - { - cell = TableCellAST.new(@ast_index, @ast_length) - cell.children = val[1] unless val[1].nil? or val[1].empty? - cell.type = :head - result = [cell] - result += val[3] unless val[3].nil? or val[3].empty? - } - | CELL_START CELL_END row_contents - { - cell = TableCellAST.new(@ast_index, @ast_length) - cell.type = :body - result = [cell] - result += val[2] unless val[2].nil? or val[2].empty? - } - | CELL_START repeated_contents CELL_END row_contents - { - if val[2] == 'attributes' - result = [] - else - cell = TableCellAST.new(@ast_index, @ast_length) - cell.children = val[1] unless val[1].nil? or val[1].empty? - cell.type = :body - result = [cell] - end - result += val[3] unless val[3].nil? or val[3].empty? - if val[2] == 'attributes' and val[3] and val[3].first.class == TableCellAST - val[3].first.attributes = val[1] - end - result - } - - -element: - TEXT - { return [:None, val[0]] } - | HLINE - { return [:HLine, val[0]] } - | CHAR_ENT - { return [:CharacterEntity, val[0]] } - | SIGNATURE_DATE - { return [:SignatureDate, val[0]] } - | SIGNATURE_NAME - { return [:SignatureName, val[0]] } - | SIGNATURE_FULL - { return [:SignatureFull, val[0]] } - ; - -formatted_element: - BOLD_START BOLD_END - { - result = FormattedAST.new(@ast_index, @ast_length) - result.formatting = :Bold - result - } - | ITALIC_START ITALIC_END - { - result = FormattedAST.new(@ast_index, @ast_length) - result.formatting = :Italic - result - } - | BOLD_START repeated_contents BOLD_END - { - p = FormattedAST.new(@ast_index, @ast_length) - p.formatting = :Bold - p.children += val[1] - result = p - } - | ITALIC_START repeated_contents ITALIC_END - { - p = FormattedAST.new(@ast_index, @ast_length) - p.formatting = :Italic - p.children += val[1] - result = p - } - ; - -bulleted_list: UL_START list_item list_contents UL_END - { - list = ListAST.new(@ast_index, @ast_length) - list.list_type = :Bulleted - list.children << val[1] - list.children += val[2] - result = list - } - ; - -numbered_list: OL_START list_item list_contents OL_END - { - list = ListAST.new(@ast_index, @ast_length) - list.list_type = :Numbered - list.children << val[1] - list.children += val[2] - result = list - } - ; - -list_contents: - { result = [] } - list_item list_contents - { - result << val[1] - result += val[2] - } - | - { result = [] } - ; - -list_item: - LI_START LI_END - { - result = ListItemAST.new(@ast_index, @ast_length) - } - | LI_START repeated_contents LI_END - { - li = ListItemAST.new(@ast_index, @ast_length) - li.children += val[1] - result = li - } - ; - -dictionary_list: - DL_START dictionary_term dictionary_contents DL_END - { - result = [val[1]] - result += val[2] - } - | DL_START dictionary_contents DL_END - { - result = val[1] - } - ; - -dictionary_term: - DT_START DT_END - { - result = ListTermAST.new(@ast_index, @ast_length) - } - | DT_START repeated_contents DT_END - { - term = ListTermAST.new(@ast_index, @ast_length) - term.children += val[1] - result = term - } - -dictionary_contents: - dictionary_definition dictionary_contents - { - result = [val[0]] - result += val[1] if val[1] - } - | - { - result = [] - } - -dictionary_definition: - DD_START DD_END - { - result = ListDefinitionAST.new(@ast_index, @ast_length) - } - | DD_START repeated_contents DD_END - { - term = ListDefinitionAST.new(@ast_index, @ast_length) - term.children += val[1] - result = term - } - -preformatted: PRE_START repeated_contents PRE_END - { - p = PreformattedAST.new(@ast_index, @ast_length) - p.children += val[1] - result = p - } - | PREINDENT_START repeated_contents PREINDENT_END - { - p = PreformattedAST.new(@ast_index, @ast_length) - p.indented = true - p.children += val[1] - result = p - } - ; - -section: SECTION_START repeated_contents SECTION_END - { result = [val[1], val[0].length] - s = SectionAST.new(@ast_index, @ast_length) - s.children = val[1] - s.level = val[0].length - result = s - } - ; - -template: TEMPLATE_START TEXT template_parameters TEMPLATE_END - { - t = TemplateAST.new(@ast_index, @ast_length) - t.template_name = val[1] - t.children = val[2] unless val[2].nil? or val[2].empty? - result = t - } - ; - -template_parameters: - { - result = nil - } - | INTLINKSEP TEXT template_parameters - { - p = TemplateParameterAST.new(@ast_index, @ast_length) - p.parameter_value = val[1] - result = [p] - result += val[2] if val[2] - } - | INTLINKSEP template template_parameters - { - p = TemplateParameterAST.new(@ast_index, @ast_length) - p.children << val[1] - result = [p] - result += val[2] if val[2] - } - ; - -end - ----- header ---- -require 'mediacloth/mediawikiast' - ----- inner ---- - -attr_accessor :lexer - -def initialize - @nodes = [] - @context = [] - @wiki_ast_length = 0 - super -end - -#Tokenizes input string and parses it. -def parse(input) - @yydebug=true - lexer.tokenize(input) - do_parse - return @nodes.last -end - -#Asks the lexer to return the next token. -def next_token - token = @lexer.lex - if token[0].to_s.upcase.include? "_START" - @context << token[2..3] - elsif token[0].to_s.upcase.include? "_END" - @ast_index = @context.last[0] - @ast_length = token[2] + token[3] - @context.last[0] - @context.pop - else - @ast_index = token[2] - @ast_length = token[3] - end - - @wiki_ast_length += token[3] - - return token[0..1] -end diff --git a/test/racc/assets/mof.y b/test/racc/assets/mof.y deleted file mode 100644 index 2e83c79b6f..0000000000 --- a/test/racc/assets/mof.y +++ /dev/null @@ -1,649 +0,0 @@ -# Distributed under the Ruby license -# See http://www.ruby-lang.org/en/LICENSE.txt for the full license text -# Copyright (c) 2010 Klaus Kämpf <kkaempf@suse.de> - -/* - * According to appendix A of - * http://www.dmtf.org/standards/cim/cim_spec_v22 - */ - -class MOF::Parser - prechigh -/* nonassoc UMINUS */ - left '*' '/' - left '+' '-' - preclow - - token PRAGMA INCLUDE IDENTIFIER CLASS ASSOCIATION INDICATION - AMENDED ENABLEOVERRIDE DISABLEOVERRIDE RESTRICTED TOSUBCLASS TOINSTANCE - TRANSLATABLE QUALIFIER SCOPE SCHEMA PROPERTY REFERENCE - METHOD PARAMETER FLAVOR INSTANCE - AS REF ANY OF - DT_VOID - DT_UINT8 DT_SINT8 DT_UINT16 DT_SINT16 DT_UINT32 DT_SINT32 - DT_UINT64 DT_SINT64 DT_REAL32 DT_REAL64 DT_CHAR16 DT_STR - DT_BOOLEAN DT_DATETIME - positiveDecimalValue - stringValue - realValue - charValue - booleanValue - nullValue - binaryValue - octalValue - decimalValue - hexValue - -rule - - /* Returns a Hash of filename and MofResult */ - mofSpecification - : /* empty */ - { result = Hash.new } - | mofProduction - { result = { @name => @result } } - | mofSpecification mofProduction - { result = val[0] - result[@name] = @result - } - ; - - mofProduction - : compilerDirective - | classDeclaration - { #puts "Class '#{val[0].name}'" - @result.classes << val[0] - } - | qualifierDeclaration - { @result.qualifiers << val[0] - @qualifiers[val[0].name.downcase] = val[0] - } - | instanceDeclaration - { @result.instances << val[0] } - ; - -/*** - * compilerDirective - * - */ - - compilerDirective - : "#" PRAGMA INCLUDE pragmaParameters_opt - { raise MOF::Helper::Error.new(@name,@lineno,@line,"Missing filename after '#pragma include'") unless val[3] - open val[3], :pragma - } - | "#" PRAGMA pragmaName pragmaParameters_opt - | "#" INCLUDE pragmaParameters_opt - { raise StyleError.new(@name,@lineno,@line,"Use '#pragma include' instead of '#include'") unless @style == :wmi - raise MOF::Helper::Error.new(@name,@lineno,@line,"Missing filename after '#include'") unless val[2] - open val[2], :pragma - } - ; - - pragmaName - : IDENTIFIER - ; - - pragmaParameters_opt - : /* empty */ - { raise StyleError.new(@name,@lineno,@line,"#pragma parameter missing") unless @style == :wmi } - | "(" pragmaParameterValues ")" - { result = val[1] } - ; - - pragmaParameterValues - : pragmaParameterValue - | pragmaParameterValues "," pragmaParameterValue - ; - - pragmaParameterValue - : string - | integerValue - { raise StyleError.new(@name,@lineno,@line,"#pragma parameter missing") unless @style == :wmi } - | IDENTIFIER - ; - -/*** - * classDeclaration - * - */ - - classDeclaration - : qualifierList_opt CLASS className alias_opt superClass_opt "{" classFeatures "}" ";" - { qualifiers = val[0] - features = val[6] - # FIXME: features must not include references - result = CIM::Class.new(val[2],qualifiers,val[3],val[4],features) - } - ; - - classFeatures - : /* empty */ - { result = [] } - | classFeatures classFeature - { result = val[0] << val[1] } - ; - - classFeature - : propertyDeclaration - | methodDeclaration - | referenceDeclaration /* must have association qualifier */ - ; - - - qualifierList_opt - : /* empty */ - | qualifierList - { result = CIM::QualifierSet.new val[0] } - ; - - qualifierList - : "[" qualifier qualifiers "]" - { result = val[2] - result.unshift val[1] if val[1] } - ; - - qualifiers - : /* empty */ - { result = [] } - | qualifiers "," qualifier - { result = val[0] - result << val[2] if val[2] - } - ; - - qualifier - : qualifierName qualifierParameter_opt flavor_opt - { # Get qualifier decl - qualifier = case val[0] - when CIM::Qualifier then val[0].definition - when CIM::QualifierDeclaration then val[0] - when String then @qualifiers[val[0].downcase] - else - nil - end - raise MOF::Helper::Error.new(@name,@lineno,@line,"'#{val[0]}' is not a valid qualifier") unless qualifier - value = val[1] - raise MOF::Helper::Error.new(@name,@lineno,@line,"#{value.inspect} does not match qualifier type '#{qualifier.type}'") unless qualifier.type.matches?(value)||@style == :wmi - # Don't propagate a boolean 'false' - if qualifier.type == :boolean && value == false - result = nil - else - result = CIM::Qualifier.new(qualifier,value,val[2]) - end - } - ; - - flavor_opt - : /* empty */ - | ":" flavor - { result = CIM::QualifierFlavors.new val[1] } - ; - - qualifierParameter_opt - : /* empty */ - | qualifierParameter - ; - - qualifierParameter - : "(" constantValue ")" - { result = val[1] } - | arrayInitializer - ; - - /* CIM::Flavors */ - flavor - : AMENDED | ENABLEOVERRIDE | DISABLEOVERRIDE | RESTRICTED | TOSUBCLASS | TRANSLATABLE | TOINSTANCE - { case val[0].to_sym - when :amended, :toinstance - raise StyleError.new(@name,@lineno,@line,"'#{val[0]}' is not a valid flavor") unless @style == :wmi - end - } - ; - - alias_opt - : /* empty */ - | alias - ; - - superClass_opt - : /* empty */ - | superClass - ; - - className - : IDENTIFIER /* must be <schema>_<classname> in CIM v2.x */ - { raise ParseError.new("Class name must be prefixed by '<schema>_'") unless val[0].include?("_") || @style == :wmi } - ; - - alias - : AS aliasIdentifier - { result = val[1] } - ; - - aliasIdentifier - : "$" IDENTIFIER /* NO whitespace ! */ - { result = val[1] } - ; - - superClass - : ":" className - { result = val[1] } - ; - - - propertyDeclaration - : qualifierList_opt dataType propertyName array_opt defaultValue_opt ";" - { if val[3] - type = CIM::Array.new val[3],val[1] - else - type = val[1] - end - result = CIM::Property.new(type,val[2],val[0],val[4]) - } - ; - - referenceDeclaration - : qualifierList_opt objectRef referenceName array_opt defaultValue_opt ";" - { if val[4] - raise StyleError.new(@name,@lineno,@line,"Array not allowed in reference declaration") unless @style == :wmi - end - result = CIM::Reference.new(val[1],val[2],val[0],val[4]) } - ; - - methodDeclaration - : qualifierList_opt dataType methodName "(" parameterList_opt ")" ";" - { result = CIM::Method.new(val[1],val[2],val[0],val[4]) } - ; - - propertyName - : IDENTIFIER - | PROPERTY - { # tmplprov.mof has 'string Property;' - raise StyleError.new(@name,@lineno,@line,"Invalid keyword '#{val[0]}' used for property name") unless @style == :wmi - } - ; - - referenceName - : IDENTIFIER - | INDICATION - { result = "Indication" } - ; - - methodName - : IDENTIFIER - ; - - dataType - : DT_UINT8 - | DT_SINT8 - | DT_UINT16 - | DT_SINT16 - | DT_UINT32 - | DT_SINT32 - | DT_UINT64 - | DT_SINT64 - | DT_REAL32 - | DT_REAL64 - | DT_CHAR16 - | DT_STR - | DT_BOOLEAN - | DT_DATETIME - | DT_VOID - { raise StyleError.new(@name,@lineno,@line,"'void' is not a valid datatype") unless @style == :wmi } - ; - - objectRef - : className - { # WMI uses class names as data types (without REF ?!) - raise StyleError.new(@name,@lineno,@line,"Expected 'ref' keyword after classname '#{val[0]}'") unless @style == :wmi - result = CIM::ReferenceType.new val[0] - } - - | className REF - { result = CIM::ReferenceType.new val[0] } - ; - - parameterList_opt - : /* empty */ - | parameterList - ; - - parameterList - : parameter parameters - { result = val[1].unshift val[0] } - ; - - parameters - : /* empty */ - { result = [] } - | parameters "," parameter - { result = val[0] << val[2] } - ; - - parameter - : qualifierList_opt typespec parameterName array_opt parameterValue_opt - { if val[3] - type = CIM::Array.new val[3], val[1] - else - type = val[1] - end - result = CIM::Property.new(type,val[2],val[0]) - } - ; - - typespec - : dataType - | objectRef - ; - - parameterName - : IDENTIFIER - ; - - array_opt - : /* empty */ - | array - ; - - parameterValue_opt - : /* empty */ - | defaultValue - { raise "Default parameter value not allowed in syntax style '{@style}'" unless @style == :wmi } - ; - - array - : "[" positiveDecimalValue_opt "]" - { result = val[1] } - ; - - positiveDecimalValue_opt - : /* empty */ - { result = -1 } - | positiveDecimalValue - ; - - defaultValue_opt - : /* empty */ - | defaultValue - ; - - defaultValue - : "=" initializer - { result = val[1] } - ; - - initializer - : constantValue - | arrayInitializer - | referenceInitializer - ; - - arrayInitializer - : "{" constantValues "}" - { result = val[1] } - ; - - constantValues - : /* empty */ - | constantValue - { result = [ val[0] ] } - | constantValues "," constantValue - { result = val[0] << val[2] } - ; - - constantValue - : integerValue - | realValue - | charValue - | string - | booleanValue - | nullValue - | instance - { raise "Instance as property value not allowed in syntax style '{@style}'" unless @style == :wmi } - ; - - integerValue - : binaryValue - | octalValue - | decimalValue - | positiveDecimalValue - | hexValue - ; - - string - : stringValue - | string stringValue - { result = val[0] + val[1] } - ; - - referenceInitializer - : objectHandle - | aliasIdentifier - ; - - objectHandle - : namespace_opt modelPath - ; - - namespace_opt - : /* empty */ - | namespaceHandle ":" - ; - - namespaceHandle - : IDENTIFIER - ; - - /* - * Note - : structure depends on type of namespace - */ - - modelPath - : className "." keyValuePairList - ; - - keyValuePairList - : keyValuePair keyValuePairs - ; - - keyValuePairs - : /* empty */ - | keyValuePairs "," keyValuePair - ; - - keyValuePair - : keyname "=" initializer - ; - - keyname - : propertyName | referenceName - ; - -/*** - * qualifierDeclaration - * - */ - - qualifierDeclaration - /* 0 1 2 3 4 */ - : QUALIFIER qualifierName qualifierType scope defaultFlavor_opt ";" - { result = CIM::QualifierDeclaration.new( val[1], val[2][0], val[2][1], val[3], val[4]) } - ; - - defaultFlavor_opt - : /* empty */ - | defaultFlavor - ; - - qualifierName - : IDENTIFIER - | ASSOCIATION /* meta qualifier */ - | INDICATION /* meta qualifier */ - | REFERENCE /* Added in DSP0004 2.7.0 */ - | SCHEMA - ; - - /* [type, value] */ - qualifierType - : ":" dataType array_opt defaultValue_opt - { type = val[2].nil? ? val[1] : CIM::Array.new(val[2],val[1]) - result = [ type, val[3] ] - } - ; - - scope - : "," SCOPE "(" metaElements ")" - { result = CIM::QualifierScopes.new(val[3]) } - ; - - metaElements - : metaElement - { result = [ val[0] ] } - | metaElements "," metaElement - { result = val[0] << val[2] } - ; - - metaElement - : SCHEMA - | CLASS - | ASSOCIATION - | INDICATION - | QUALIFIER - | PROPERTY - | REFERENCE - | METHOD - | PARAMETER - | ANY - ; - - defaultFlavor - : "," FLAVOR "(" flavors ")" - { result = CIM::QualifierFlavors.new val[3] } - ; - - flavors - : flavor - { result = [ val[0] ] } - | flavors "," flavor - { result = val[0] << val[2] } - ; - -/*** - * instanceDeclaration - * - */ - - instanceDeclaration - : instance ";" - ; - - instance - : qualifierList_opt INSTANCE OF className alias_opt "{" valueInitializers "}" - ; - - valueInitializers - : valueInitializer - | valueInitializers valueInitializer - ; - - valueInitializer - : qualifierList_opt keyname "=" initializer ";" - | qualifierList_opt keyname ";" - { raise "Instance property '#{val[1]} must have a value" unless @style == :wmi } - ; - -end # class Parser - ----- header ---- - -# parser.rb - generated by racc - -require 'strscan' -require 'rubygems' -require 'cim' -require File.join(__dir__, 'result') -require File.join(__dir__, 'scanner') -require File.join(__dir__, 'case') - ----- inner ---- - -# -# Initialize MOF::Parser -# MOF::Parser.new options = {} -# -# options -> Hash of options -# :debug -> boolean -# :includes -> array of include dirs -# :style -> :cim or :wmi -# -def initialize options = {} - @yydebug = options[:debug] - @includes = options[:includes] || [] - @quiet = options[:quiet] - @style = options[:style] || :cim # default to style CIM v2.2 syntax - - @lineno = 1 - @file = nil - @iconv = nil - @eol = "\n" - @fname = nil - @fstack = [] - @in_comment = false - @seen_files = [] - @qualifiers = {} -end - -# -# Make options hash from argv -# -# returns [ files, options ] -# - - def self.argv_handler name, argv - files = [] - options = { :namespace => "" } - while argv.size > 0 - case opt = argv.shift - when "-h" - $stderr.puts "Ruby MOF compiler" - $stderr.puts "#{name} [-h] [-d] [-I <dir>] [<moffiles>]" - $stderr.puts "Compiles <moffile>" - $stderr.puts "\t-d debug" - $stderr.puts "\t-h this help" - $stderr.puts "\t-I <dir> include dir" - $stderr.puts "\t-f force" - $stderr.puts "\t-n <namespace>" - $stderr.puts "\t-o <output>" - $stderr.puts "\t-s <style> syntax style (wmi,cim)" - $stderr.puts "\t-q quiet" - $stderr.puts "\t<moffiles> file(s) to read (else use $stdin)" - exit 0 - when "-f" then options[:force] = true - when "-s" then options[:style] = argv.shift.to_sym - when "-d" then options[:debug] = true - when "-q" then options[:quiet] = true - when "-I" - options[:includes] ||= [] - dirname = argv.shift - unless File.directory?(dirname) - files << dirname - dirname = File.dirname(dirname) - end - options[:includes] << Pathname.new(dirname) - when "-n" then options[:namespace] = argv.shift - when "-o" then options[:output] = argv.shift - when /^-.+/ - $stderr.puts "Undefined option #{opt}" - else - files << opt - end - end - [ files, options ] - end - -include Helper -include Scanner - ----- footer ---- diff --git a/test/racc/assets/namae.y b/test/racc/assets/namae.y deleted file mode 100644 index 0378345fef..0000000000 --- a/test/racc/assets/namae.y +++ /dev/null @@ -1,302 +0,0 @@ -# -*- ruby -*- -# vi: set ft=ruby : - -# Copyright (C) 2012 President and Fellows of Harvard College -# Copyright (C) 2013-2014 Sylvester Keil -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY EXPRESS OR -# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO -# EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY -# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# The views and conclusions contained in the software and documentation are -# those of the authors and should not be interpreted as representing official -# policies, either expressed or implied, of the copyright holder. - -class Namae::Parser - -token COMMA UWORD LWORD PWORD NICK AND APPELLATION TITLE SUFFIX - -expect 0 - -rule - - names : { result = [] } - | name { result = [val[0]] } - | names AND name { result = val[0] << val[2] } - - name : word { result = Name.new(:given => val[0]) } - | display_order - | honorific word { result = val[0].merge(:family => val[1]) } - | honorific display_order { result = val[1].merge(val[0]) } - | sort_order - - honorific : APPELLATION { result = Name.new(:appellation => val[0]) } - | TITLE { result = Name.new(:title => val[0]) } - - display_order : u_words word opt_suffices opt_titles - { - result = Name.new(:given => val[0], :family => val[1], - :suffix => val[2], :title => val[3]) - } - | u_words NICK last opt_suffices opt_titles - { - result = Name.new(:given => val[0], :nick => val[1], - :family => val[2], :suffix => val[3], :title => val[4]) - } - | u_words NICK von last opt_suffices opt_titles - { - result = Name.new(:given => val[0], :nick => val[1], - :particle => val[2], :family => val[3], - :suffix => val[4], :title => val[5]) - } - | u_words von last - { - result = Name.new(:given => val[0], :particle => val[1], - :family => val[2]) - } - | von last - { - result = Name.new(:particle => val[0], :family => val[1]) - } - - sort_order : last COMMA first - { - result = Name.new({ :family => val[0], :suffix => val[2][0], - :given => val[2][1] }, !!val[2][0]) - } - | von last COMMA first - { - result = Name.new({ :particle => val[0], :family => val[1], - :suffix => val[3][0], :given => val[3][1] }, !!val[3][0]) - } - | u_words von last COMMA first - { - result = Name.new({ :particle => val[0,2].join(' '), :family => val[2], - :suffix => val[4][0], :given => val[4][1] }, !!val[4][0]) - } - ; - - von : LWORD - | von LWORD { result = val.join(' ') } - | von u_words LWORD { result = val.join(' ') } - - last : LWORD | u_words - - first : opt_words { result = [nil,val[0]] } - | words opt_comma suffices { result = [val[2],val[0]] } - | suffices { result = [val[0],nil] } - | suffices COMMA words { result = [val[0],val[2]] } - - u_words : u_word - | u_words u_word { result = val.join(' ') } - - u_word : UWORD | PWORD - - words : word - | words word { result = val.join(' ') } - - opt_comma : /* empty */ | COMMA - opt_words : /* empty */ | words - - word : LWORD | UWORD | PWORD - - opt_suffices : /* empty */ | suffices - - suffices : SUFFIX - | suffices SUFFIX { result = val.join(' ') } - - opt_titles : /* empty */ | titles - - titles : TITLE - | titles TITLE { result = val.join(' ') } - ----- header -require 'singleton' -require 'strscan' - ----- inner - - include Singleton - - attr_reader :options, :input - - def initialize - @input, @options = StringScanner.new(''), { - :debug => false, - :prefer_comma_as_separator => false, - :comma => ',', - :stops => ',;', - :separator => /\s*(\band\b|\&|;)\s*/i, - :title => /\s*\b(sir|lord|count(ess)?|(gen|adm|col|maj|capt|cmdr|lt|sgt|cpl|pvt|prof|dr|md|ph\.?d)\.?)(\s+|$)/i, - :suffix => /\s*\b(JR|Jr|jr|SR|Sr|sr|[IVX]{2,})(\.|\b)/, - :appellation => /\s*\b((mrs?|ms|fr|hr)\.?|miss|herr|frau)(\s+|$)/i - } - end - - def debug? - options[:debug] || ENV['DEBUG'] - end - - def separator - options[:separator] - end - - def comma - options[:comma] - end - - def stops - options[:stops] - end - - def title - options[:title] - end - - def suffix - options[:suffix] - end - - def appellation - options[:appellation] - end - - def prefer_comma_as_separator? - options[:prefer_comma_as_separator] - end - - def parse(input) - parse!(input) - rescue => e - warn e.message if debug? - [] - end - - def parse!(string) - input.string = normalize(string) - reset - do_parse - end - - def normalize(string) - string = string.strip - string - end - - def reset - @commas, @words, @initials, @suffices, @yydebug = 0, 0, 0, 0, debug? - self - end - - private - - def stack - @vstack || @racc_vstack || [] - end - - def last_token - stack[-1] - end - - def consume_separator - return next_token if seen_separator? - @commas, @words, @initials, @suffices = 0, 0, 0, 0 - [:AND, :AND] - end - - def consume_comma - @commas += 1 - [:COMMA, :COMMA] - end - - def consume_word(type, word) - @words += 1 - - case type - when :UWORD - @initials += 1 if word =~ /^[[:upper:]]+\b/ - when :SUFFIX - @suffices += 1 - end - - [type, word] - end - - def seen_separator? - !stack.empty? && last_token == :AND - end - - def suffix? - !@suffices.zero? || will_see_suffix? - end - - def will_see_suffix? - input.peek(8).to_s.strip.split(/\s+/)[0] =~ suffix - end - - def will_see_initial? - input.peek(6).to_s.strip.split(/\s+/)[0] =~ /^[[:upper:]]+\b/ - end - - def seen_full_name? - prefer_comma_as_separator? && @words > 1 && - (@initials > 0 || !will_see_initial?) && !will_see_suffix? - end - - def next_token - case - when input.nil?, input.eos? - nil - when input.scan(separator) - consume_separator - when input.scan(/\s*#{comma}\s*/) - if @commas.zero? && !seen_full_name? || @commas == 1 && suffix? - consume_comma - else - consume_separator - end - when input.scan(/\s+/) - next_token - when input.scan(title) - consume_word(:TITLE, input.matched.strip) - when input.scan(suffix) - consume_word(:SUFFIX, input.matched.strip) - when input.scan(appellation) - [:APPELLATION, input.matched.strip] - when input.scan(/((\\\w+)?\{[^\}]*\})*[[:upper:]][^\s#{stops}]*/) - consume_word(:UWORD, input.matched) - when input.scan(/((\\\w+)?\{[^\}]*\})*[[:lower:]][^\s#{stops}]*/) - consume_word(:LWORD, input.matched) - when input.scan(/(\\\w+)?\{[^\}]*\}[^\s#{stops}]*/) - consume_word(:PWORD, input.matched) - when input.scan(/('[^'\n]+')|("[^"\n]+")/) - consume_word(:NICK, input.matched[1...-1]) - else - raise ArgumentError, - "Failed to parse name #{input.string.inspect}: unmatched data at offset #{input.pos}" - end - end - - def on_error(tid, value, stack) - raise ArgumentError, - "Failed to parse name: unexpected '#{value}' at #{stack.inspect}" - end - -# -*- racc -*- diff --git a/test/racc/assets/nasl.y b/test/racc/assets/nasl.y deleted file mode 100644 index c7b8e46551..0000000000 --- a/test/racc/assets/nasl.y +++ /dev/null @@ -1,626 +0,0 @@ -################################################################################ -# Copyright (c) 2011-2014, Tenable Network Security -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, this -# list of conditions and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -################################################################################ - -class Nasl::Grammar - -preclow - right ASS_EQ ADD_EQ SUB_EQ MUL_EQ DIV_EQ MOD_EQ SLL_EQ SRA_EQ SRL_EQ - left OR - left AND - left CMP_LT CMP_GT CMP_EQ CMP_NE CMP_GE CMP_LE SUBSTR_EQ SUBSTR_NE REGEX_EQ REGEX_NE - left BIT_OR - left BIT_XOR - left AMPERSAND - left BIT_SRA BIT_SRL BIT_SLL - left ADD SUB - left MUL DIV MOD - right NOT - right UMINUS BIT_NOT - right EXP - right INCR DECR -prechigh - -# Tell the parser generator that we don't wish to use the result variable in the -# action section of rules. Instead, the result of the rule will be the value of -# evaluating the action block. -options no_result_var - -# Tell the parser generator that we expect one shift/reduce conflict due to the -# well-known dangling else problem. We could make the grammar solve this -# problem, but this is how the NASL YACC file solves it, so we'll follow suit. -expect 1 - -rule - ############################################################################## - # Aggregate Statements - ############################################################################## - - start : roots - { val[0] } - | /* Blank */ - { [] } - ; - - roots : root roots - { [val[0]] + val[1] } - | root - { [val[0]] } - ; - - root : COMMENT export - { c(*val) } - | export - { val[0] } - | COMMENT function - { c(*val) } - | function - { val[0] } - | statement - { val[0] } - ; - - statement : simple - { val[0] } - | compound - { val[0] } - ; - - ############################################################################## - # Root Statements - ############################################################################## - - export : EXPORT function - { n(:Export, *val) } - ; - - function : FUNCTION ident LPAREN params RPAREN block - { n(:Function, *val) } - | FUNCTION ident LPAREN RPAREN block - { n(:Function, *val) } - ; - - simple : assign - { val[0] } - | break - { val[0] } - | call - { val[0] } - | continue - { val[0] } - | decr - { val[0] } - | empty - { val[0] } - | COMMENT global - { c(*val) } - | global - { val[0] } - | import - { val[0] } - | include - { val[0] } - | incr - { val[0] } - | local - { val[0] } - | rep - { val[0] } - | return - { val[0] } - ; - - compound : block - { val[0] } - | for - { val[0] } - | foreach - { val[0] } - | if - { val[0] } - | repeat - { val[0] } - | while - { val[0] } - ; - - ############################################################################## - # Simple Statements - ############################################################################## - - assign : assign_exp SEMICOLON - { val[0] } - ; - - break : BREAK SEMICOLON - { n(:Break, *val) } - ; - - call : call_exp SEMICOLON - { val[0] } - ; - - continue : CONTINUE SEMICOLON - { n(:Continue, *val) } - ; - - decr : decr_exp SEMICOLON - { val[0] } - ; - - empty : SEMICOLON - { n(:Empty, *val) } - ; - - global : GLOBAL var_decls SEMICOLON - { n(:Global, *val) } - ; - - incr : incr_exp SEMICOLON - { val[0] } - ; - - import : IMPORT LPAREN string RPAREN SEMICOLON - { n(:Import, *val) } - ; - - include : INCLUDE LPAREN string RPAREN SEMICOLON - { n(:Include, *val) } - ; - - local : LOCAL var_decls SEMICOLON - { n(:Local, *val) } - ; - - rep : call_exp REP expr SEMICOLON - { n(:Repetition, *val[0..-1]) } - ; - - return : RETURN expr SEMICOLON - { n(:Return, *val) } - | RETURN ref SEMICOLON - { n(:Return, *val) } - | RETURN SEMICOLON - { n(:Return, *val) } - ; - - ############################################################################## - # Compound Statements - ############################################################################## - - block : LBRACE statements RBRACE - { n(:Block, *val) } - | LBRACE RBRACE - { n(:Block, *val) } - ; - - for : FOR LPAREN field SEMICOLON expr SEMICOLON field RPAREN statement - { n(:For, *val) } - ; - - foreach : FOREACH ident LPAREN expr RPAREN statement - { n(:Foreach, val[0], val[1], val[3], val[5]) } - | FOREACH LPAREN ident IN expr RPAREN statement - { n(:Foreach, val[0], val[2], val[4], val[6]) } - ; - - if : IF LPAREN expr RPAREN statement - { n(:If, *val) } - | IF LPAREN expr RPAREN statement ELSE statement - { n(:If, *val) } - ; - - repeat : REPEAT statement UNTIL expr SEMICOLON - { n(:Repeat, *val) } - ; - - while : WHILE LPAREN expr RPAREN statement - { n(:While, *val) } - ; - - ############################################################################## - # Expressions - ############################################################################## - - assign_exp : lval ASS_EQ expr - { n(:Assignment, *val) } - | lval ASS_EQ ref - { n(:Assignment, *val) } - | lval ADD_EQ expr - { n(:Assignment, *val) } - | lval SUB_EQ expr - { n(:Assignment, *val) } - | lval MUL_EQ expr - { n(:Assignment, *val) } - | lval DIV_EQ expr - { n(:Assignment, *val) } - | lval MOD_EQ expr - { n(:Assignment, *val) } - | lval SRL_EQ expr - { n(:Assignment, *val) } - | lval SRA_EQ expr - { n(:Assignment, *val) } - | lval SLL_EQ expr - { n(:Assignment, *val) } - ; - - call_exp : lval LPAREN args RPAREN - { n(:Call, *val) } - | lval LPAREN RPAREN - { n(:Call, *val) } - ; - - decr_exp : DECR lval - { n(:Decrement, val[0]) } - | lval DECR - { n(:Decrement, val[0]) } - ; - - incr_exp : INCR lval - { n(:Increment, val[0]) } - | lval INCR - { n(:Increment, val[0]) } - ; - - expr : LPAREN expr RPAREN - { n(:Expression, *val) } - | expr AND expr - { n(:Expression, *val) } - | NOT expr - { n(:Expression, *val) } - | expr OR expr - { n(:Expression, *val) } - | expr ADD expr - { n(:Expression, *val) } - | expr SUB expr - { n(:Expression, *val) } - | SUB expr =UMINUS - { n(:Expression, *val) } - | BIT_NOT expr - { n(:Expression, *val) } - | expr MUL expr - { n(:Expression, *val) } - | expr EXP expr - { n(:Expression, *val) } - | expr DIV expr - { n(:Expression, *val) } - | expr MOD expr - { n(:Expression, *val) } - | expr AMPERSAND expr - { n(:Expression, *val) } - | expr BIT_XOR expr - { n(:Expression, *val) } - | expr BIT_OR expr - { n(:Expression, *val) } - | expr BIT_SRA expr - { n(:Expression, *val) } - | expr BIT_SRL expr - { n(:Expression, *val) } - | expr BIT_SLL expr - { n(:Expression, *val) } - | incr_exp - { val[0] } - | decr_exp - { val[0] } - | expr SUBSTR_EQ expr - { n(:Expression, *val) } - | expr SUBSTR_NE expr - { n(:Expression, *val) } - | expr REGEX_EQ expr - { n(:Expression, *val) } - | expr REGEX_NE expr - { n(:Expression, *val) } - | expr CMP_LT expr - { n(:Expression, *val) } - | expr CMP_GT expr - { n(:Expression, *val) } - | expr CMP_EQ expr - { n(:Expression, *val) } - | expr CMP_NE expr - { n(:Expression, *val) } - | expr CMP_GE expr - { n(:Expression, *val) } - | expr CMP_LE expr - { n(:Expression, *val) } - | assign_exp - { val[0] } - | string - { val[0] } - | call_exp - { val[0] } - | lval - { val[0] } - | ip - { val[0] } - | int - { val[0] } - | undef - { val[0] } - | list_expr - { val[0] } - | array_expr - { val[0] } - ; - - ############################################################################## - # Named Components - ############################################################################## - - arg : ident COLON expr - { n(:Argument, *val) } - | ident COLON ref - { n(:Argument, *val) } - | expr - { n(:Argument, *val) } - | ref - { n(:Argument, *val) } - ; - - kv_pair : string COLON expr - { n(:KeyValuePair, *val) } - | int COLON expr - { n(:KeyValuePair, *val) } - | ident COLON expr - { n(:KeyValuePair, *val) } - | string COLON ref - { n(:KeyValuePair, *val) } - | int COLON ref - { n(:KeyValuePair, *val) } - | ident COLON ref - { n(:KeyValuePair, *val) } - ; - - kv_pairs : kv_pair COMMA kv_pairs - { [val[0]] + val[2] } - | kv_pair COMMA - { [val[0]] } - | kv_pair - { [val[0]] } - ; - - lval : ident indexes - { n(:Lvalue, *val) } - | ident - { n(:Lvalue, *val) } - ; - - ref : AT_SIGN ident - { n(:Reference, val[1]) } - ; - - ############################################################################## - # Anonymous Components - ############################################################################## - - args : arg COMMA args - { [val[0]] + val[2] } - | arg - { [val[0]] } - ; - - array_expr : LBRACE kv_pairs RBRACE - { n(:Array, *val) } - | LBRACE RBRACE - { n(:Array, *val) } - ; - - field : assign_exp - { val[0] } - | call_exp - { val[0] } - | decr_exp - { val[0] } - | incr_exp - { val[0] } - | /* Blank */ - { nil } - ; - - index : LBRACK expr RBRACK - { val[1] } - | PERIOD ident - { val[1] } - ; - - indexes : index indexes - { [val[0]] + val[1] } - | index - { [val[0]] } - ; - - list_elem : expr - { val[0] } - | ref - { val[0] } - ; - - list_elems : list_elem COMMA list_elems - { [val[0]] + val[2] } - | list_elem - { [val[0]] } - ; - - list_expr : LBRACK list_elems RBRACK - { n(:List, *val) } - | LBRACK RBRACK - { n(:List, *val) } - ; - - param : AMPERSAND ident - { n(:Parameter, val[1], 'reference') } - | ident - { n(:Parameter, val[0], 'value') } - ; - - params : param COMMA params - { [val[0]] + val[2] } - | param - { [val[0]] } - ; - - statements : statement statements - { [val[0]] + val[1] } - | statement - { [val[0]] } - ; - - var_decl : ident ASS_EQ expr - { n(:Assignment, *val) } - | ident ASS_EQ ref - { n(:Assignment, *val) } - | ident - { val[0] } - ; - - var_decls : var_decl COMMA var_decls - { [val[0]] + val[2] } - | var_decl - { [val[0]] } - ; - - ############################################################################## - # Literals - ############################################################################## - - ident : IDENT - { n(:Identifier, *val) } - | REP - { n(:Identifier, *val) } - | IN - { n(:Identifier, *val) } - ; - - int : INT_DEC - { n(:Integer, *val) } - | INT_HEX - { n(:Integer, *val) } - | INT_OCT - { n(:Integer, *val) } - | FALSE - { n(:Integer, *val) } - | TRUE - { n(:Integer, *val) } - ; - - ip : int PERIOD int PERIOD int PERIOD int - { n(:Ip, *val) } - - string : DATA - { n(:String, *val) } - | STRING - { n(:String, *val) } - ; - - undef : UNDEF - { n(:Undefined, *val) } - ; -end - ----- header ---- - -require 'nasl/parser/tree' - -require 'nasl/parser/argument' -require 'nasl/parser/array' -require 'nasl/parser/assigment' -require 'nasl/parser/block' -require 'nasl/parser/break' -require 'nasl/parser/call' -require 'nasl/parser/comment' -require 'nasl/parser/continue' -require 'nasl/parser/decrement' -require 'nasl/parser/empty' -require 'nasl/parser/export' -require 'nasl/parser/expression' -require 'nasl/parser/for' -require 'nasl/parser/foreach' -require 'nasl/parser/function' -require 'nasl/parser/global' -require 'nasl/parser/identifier' -require 'nasl/parser/if' -require 'nasl/parser/import' -require 'nasl/parser/include' -require 'nasl/parser/increment' -require 'nasl/parser/integer' -require 'nasl/parser/ip' -require 'nasl/parser/key_value_pair' -require 'nasl/parser/list' -require 'nasl/parser/local' -require 'nasl/parser/lvalue' -require 'nasl/parser/parameter' -require 'nasl/parser/reference' -require 'nasl/parser/repeat' -require 'nasl/parser/repetition' -require 'nasl/parser/return' -require 'nasl/parser/string' -require 'nasl/parser/undefined' -require 'nasl/parser/while' - ----- inner ---- - -def n(cls, *args) - begin - Nasl.const_get(cls).new(@tree, *args) - rescue - puts "An exception occurred during the creation of a #{cls} instance." - puts - puts "The arguments passed to the constructor were:" - puts args - puts - puts @tok.last.context - puts - raise - end -end - -def c(*args) - n(:Comment, *args) - args[1] -end - -def on_error(type, value, stack) - raise ParseException, "The language's grammar does not permit #{value.name} to appear here", value.context -end - -def next_token - @tok = @tkz.get_token - - if @first && @tok.first == :COMMENT - n(:Comment, @tok.last) - @tok = @tkz.get_token - end - @first = false - - return @tok -end - -def parse(env, code, path) - @first = true - @tree = Tree.new(env) - @tkz = Tokenizer.new(code, path) - @tree.concat(do_parse) -end - ----- footer ---- diff --git a/test/racc/assets/newsyn.y b/test/racc/assets/newsyn.y deleted file mode 100644 index 5b670c966a..0000000000 --- a/test/racc/assets/newsyn.y +++ /dev/null @@ -1,25 +0,0 @@ - -class A - - preclow - left preclow prechigh right left nonassoc token - right preclow prechigh right left nonassoc token - nonassoc preclow prechigh right left nonassoc token - prechigh - - convert - left 'a' - right 'b' - preclow 'c' - nonassoc 'd' - preclow 'e' - prechigh 'f' - end - -rule - - left: right nonassoc preclow prechigh - - right: A B C - -end diff --git a/test/racc/assets/noend.y b/test/racc/assets/noend.y deleted file mode 100644 index 5aa0670be0..0000000000 --- a/test/racc/assets/noend.y +++ /dev/null @@ -1,4 +0,0 @@ -class MyParser -rule -input: A B C -end diff --git a/test/racc/assets/nokogiri-css.y b/test/racc/assets/nokogiri-css.y deleted file mode 100644 index 24dfbf3b1b..0000000000 --- a/test/racc/assets/nokogiri-css.y +++ /dev/null @@ -1,255 +0,0 @@ -class Nokogiri::CSS::Parser - -token FUNCTION INCLUDES DASHMATCH LBRACE HASH PLUS GREATER S STRING IDENT -token COMMA NUMBER PREFIXMATCH SUFFIXMATCH SUBSTRINGMATCH TILDE NOT_EQUAL -token SLASH DOUBLESLASH NOT EQUAL RPAREN LSQUARE RSQUARE HAS - -rule - selector - : selector COMMA simple_selector_1toN { - result = [val.first, val.last].flatten - } - | prefixless_combinator_selector { result = val.flatten } - | optional_S simple_selector_1toN { result = [val.last].flatten } - ; - combinator - : PLUS { result = :DIRECT_ADJACENT_SELECTOR } - | GREATER { result = :CHILD_SELECTOR } - | TILDE { result = :FOLLOWING_SELECTOR } - | DOUBLESLASH { result = :DESCENDANT_SELECTOR } - | SLASH { result = :CHILD_SELECTOR } - ; - simple_selector - : element_name hcap_0toN { - result = if val[1].nil? - val.first - else - Node.new(:CONDITIONAL_SELECTOR, [val.first, val[1]]) - end - } - | function - | function pseudo { - result = Node.new(:CONDITIONAL_SELECTOR, val) - } - | function attrib { - result = Node.new(:CONDITIONAL_SELECTOR, val) - } - | hcap_1toN { - result = Node.new(:CONDITIONAL_SELECTOR, - [Node.new(:ELEMENT_NAME, ['*']), val.first] - ) - } - ; - prefixless_combinator_selector - : combinator simple_selector_1toN { - result = Node.new(val.first, [nil, val.last]) - } - ; - simple_selector_1toN - : simple_selector combinator simple_selector_1toN { - result = Node.new(val[1], [val.first, val.last]) - } - | simple_selector S simple_selector_1toN { - result = Node.new(:DESCENDANT_SELECTOR, [val.first, val.last]) - } - | simple_selector - ; - class - : '.' IDENT { result = Node.new(:CLASS_CONDITION, [val[1]]) } - ; - element_name - : namespaced_ident - | '*' { result = Node.new(:ELEMENT_NAME, val) } - ; - namespaced_ident - : namespace '|' IDENT { - result = Node.new(:ELEMENT_NAME, - [[val.first, val.last].compact.join(':')] - ) - } - | IDENT { - name = @namespaces.key?('xmlns') ? "xmlns:#{val.first}" : val.first - result = Node.new(:ELEMENT_NAME, [name]) - } - ; - namespace - : IDENT { result = val[0] } - | - ; - attrib - : LSQUARE attrib_name attrib_val_0or1 RSQUARE { - result = Node.new(:ATTRIBUTE_CONDITION, - [val[1]] + (val[2] || []) - ) - } - | LSQUARE function attrib_val_0or1 RSQUARE { - result = Node.new(:ATTRIBUTE_CONDITION, - [val[1]] + (val[2] || []) - ) - } - | LSQUARE NUMBER RSQUARE { - # Non standard, but hpricot supports it. - result = Node.new(:PSEUDO_CLASS, - [Node.new(:FUNCTION, ['nth-child(', val[1]])] - ) - } - ; - attrib_name - : namespace '|' IDENT { - result = Node.new(:ELEMENT_NAME, - [[val.first, val.last].compact.join(':')] - ) - } - | IDENT { - # Default namespace is not applied to attributes. - # So we don't add prefix "xmlns:" as in namespaced_ident. - result = Node.new(:ELEMENT_NAME, [val.first]) - } - ; - function - : FUNCTION RPAREN { - result = Node.new(:FUNCTION, [val.first.strip]) - } - | FUNCTION expr RPAREN { - result = Node.new(:FUNCTION, [val.first.strip, val[1]].flatten) - } - | FUNCTION nth RPAREN { - result = Node.new(:FUNCTION, [val.first.strip, val[1]].flatten) - } - | NOT expr RPAREN { - result = Node.new(:FUNCTION, [val.first.strip, val[1]].flatten) - } - | HAS selector RPAREN { - result = Node.new(:FUNCTION, [val.first.strip, val[1]].flatten) - } - ; - expr - : NUMBER COMMA expr { result = [val.first, val.last] } - | STRING COMMA expr { result = [val.first, val.last] } - | IDENT COMMA expr { result = [val.first, val.last] } - | NUMBER - | STRING - | IDENT # even, odd - { - case val[0] - when 'even' - result = Node.new(:NTH, ['2','n','+','0']) - when 'odd' - result = Node.new(:NTH, ['2','n','+','1']) - when 'n' - result = Node.new(:NTH, ['1','n','+','0']) - else - # This is not CSS standard. It allows us to support this: - # assert_xpath("//a[foo(., @href)]", @parser.parse('a:foo(@href)')) - # assert_xpath("//a[foo(., @a, b)]", @parser.parse('a:foo(@a, b)')) - # assert_xpath("//a[foo(., a, 10)]", @parser.parse('a:foo(a, 10)')) - result = val - end - } - ; - nth - : NUMBER IDENT PLUS NUMBER # 5n+3 -5n+3 - { - if val[1] == 'n' - result = Node.new(:NTH, val) - else - raise Racc::ParseError, "parse error on IDENT '#{val[1]}'" - end - } - | IDENT PLUS NUMBER { # n+3, -n+3 - if val[0] == 'n' - val.unshift("1") - result = Node.new(:NTH, val) - elsif val[0] == '-n' - val[0] = 'n' - val.unshift("-1") - result = Node.new(:NTH, val) - else - raise Racc::ParseError, "parse error on IDENT '#{val[1]}'" - end - } - | NUMBER IDENT { # 5n, -5n, 10n-1 - n = val[1] - if n[0, 2] == 'n-' - val[1] = 'n' - val << "-" - # b is contained in n as n is the string "n-b" - val << n[2, n.size] - result = Node.new(:NTH, val) - elsif n == 'n' - val << "+" - val << "0" - result = Node.new(:NTH, val) - else - raise Racc::ParseError, "parse error on IDENT '#{val[1]}'" - end - } - ; - pseudo - : ':' function { - result = Node.new(:PSEUDO_CLASS, [val[1]]) - } - | ':' IDENT { result = Node.new(:PSEUDO_CLASS, [val[1]]) } - ; - hcap_0toN - : hcap_1toN - | - ; - hcap_1toN - : attribute_id hcap_1toN { - result = Node.new(:COMBINATOR, val) - } - | class hcap_1toN { - result = Node.new(:COMBINATOR, val) - } - | attrib hcap_1toN { - result = Node.new(:COMBINATOR, val) - } - | pseudo hcap_1toN { - result = Node.new(:COMBINATOR, val) - } - | negation hcap_1toN { - result = Node.new(:COMBINATOR, val) - } - | attribute_id - | class - | attrib - | pseudo - | negation - ; - attribute_id - : HASH { result = Node.new(:ID, val) } - ; - attrib_val_0or1 - : eql_incl_dash IDENT { result = [val.first, val[1]] } - | eql_incl_dash STRING { result = [val.first, val[1]] } - | - ; - eql_incl_dash - : EQUAL { result = :equal } - | PREFIXMATCH { result = :prefix_match } - | SUFFIXMATCH { result = :suffix_match } - | SUBSTRINGMATCH { result = :substring_match } - | NOT_EQUAL { result = :not_equal } - | INCLUDES { result = :includes } - | DASHMATCH { result = :dash_match } - ; - negation - : NOT negation_arg RPAREN { - result = Node.new(:NOT, [val[1]]) - } - ; - negation_arg - : element_name - | element_name hcap_1toN - | hcap_1toN - ; - optional_S - : S - | - ; -end - ----- header - -require 'nokogiri/css/parser_extras' diff --git a/test/racc/assets/nonass.y b/test/racc/assets/nonass.y deleted file mode 100644 index b9a35a2626..0000000000 --- a/test/racc/assets/nonass.y +++ /dev/null @@ -1,41 +0,0 @@ -# -# nonassoc test -# - -class P - -preclow - nonassoc N - left P -prechigh - -rule - -target : exp -exp : exp N exp - | exp P exp - | T - -end - ----- inner - - def parse - @src = [[:T,'T'], [:N,'N'], [:T,'T'], [:N,'N'], [:T,'T']] - do_parse - end - - def next_token - @src.shift - end - ----- footer - -begin - P.new.parse -rescue ParseError - exit 0 -else - $stderr.puts 'parse error not raised: nonassoc not work' - exit 1 -end diff --git a/test/racc/assets/normal.y b/test/racc/assets/normal.y deleted file mode 100644 index 96ae352c82..0000000000 --- a/test/racc/assets/normal.y +++ /dev/null @@ -1,27 +0,0 @@ - -class Testp - - convert - A '2' - B '3' - end - - prechigh - left B - preclow - -rule - -/* comment */ - target: A B C nonterminal { action "string" == /regexp/o - 1 /= 3 } - ; # comment - - nonterminal: A '+' B = A; - -/* end */ -end - ----- driver - - # driver is old name diff --git a/test/racc/assets/norule.y b/test/racc/assets/norule.y deleted file mode 100644 index e50a4b3472..0000000000 --- a/test/racc/assets/norule.y +++ /dev/null @@ -1,4 +0,0 @@ - -class A -rule -end diff --git a/test/racc/assets/nullbug1.y b/test/racc/assets/nullbug1.y deleted file mode 100644 index 4b267ba0ea..0000000000 --- a/test/racc/assets/nullbug1.y +++ /dev/null @@ -1,25 +0,0 @@ -# -# number of conflicts must be ZERO. -# - -class T - -rule - -targ : dummy - | a b c - -dummy : V v - -V : E e - | F f - | - ; - -E : - ; - -F : - ; - -end diff --git a/test/racc/assets/nullbug2.y b/test/racc/assets/nullbug2.y deleted file mode 100644 index 0c1d43bf3e..0000000000 --- a/test/racc/assets/nullbug2.y +++ /dev/null @@ -1,15 +0,0 @@ -# -# number of conflicts must be ZERO. -# - -class A -rule - targ: operation voidhead - | variable - - voidhead : void B - void: - - operation: A - variable : A -end diff --git a/test/racc/assets/opal.y b/test/racc/assets/opal.y deleted file mode 100644 index ae6a5a6bdd..0000000000 --- a/test/racc/assets/opal.y +++ /dev/null @@ -1,1807 +0,0 @@ -# Copyright (C) 2013 by Adam Beynon -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -class Opal::Parser - -token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS - kTHEN kELSIF kELSE kCASE kWHEN kWHILE kUNTIL kFOR kBREAK kNEXT - kREDO kRETRY kIN kDO kDO_COND kDO_BLOCK kDO_LAMBDA kRETURN kYIELD kSUPER - kSELF kNIL kTRUE kFALSE kAND kOR kNOT kIF_MOD kUNLESS_MOD kWHILE_MOD - kUNTIL_MOD kRESCUE_MOD kALIAS kDEFINED klBEGIN klEND k__LINE__ - k__FILE__ k__ENCODING__ tIDENTIFIER tFID tGVAR tIVAR tCONSTANT - tLABEL tCVAR tNTH_REF tBACK_REF tSTRING_CONTENT tINTEGER tFLOAT - tREGEXP_END tUPLUS tUMINUS tUMINUS_NUM tPOW tCMP tEQ tEQQ tNEQ tGEQ tLEQ tANDOP - tOROP tMATCH tNMATCH tJSDOT tDOT tDOT2 tDOT3 tAREF tASET tLSHFT tRSHFT - tCOLON2 tCOLON3 tOP_ASGN tASSOC tLPAREN tLPAREN2 tRPAREN tLPAREN_ARG - ARRAY_BEG tRBRACK tLBRACE tLBRACE_ARG tSTAR tSTAR2 tAMPER tAMPER2 - tTILDE tPERCENT tDIVIDE tPLUS tMINUS tLT tGT tPIPE tBANG tCARET - tLCURLY tRCURLY tBACK_REF2 tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG - tWORDS_BEG tAWORDS_BEG tSTRING_DBEG tSTRING_DVAR tSTRING_END tSTRING - tSYMBOL tNL tEH tCOLON tCOMMA tSPACE tSEMI tLAMBDA tLAMBEG - tLBRACK2 tLBRACK tJSLBRACK tDSTAR - -prechigh - right tBANG tTILDE tUPLUS - right tPOW - right tUMINUS_NUM tUMINUS - left tSTAR2 tDIVIDE tPERCENT - left tPLUS tMINUS - left tLSHFT tRSHFT - left tAMPER2 - left tPIPE tCARET - left tGT tGEQ tLT tLEQ - nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH - left tANDOP - left tOROP - nonassoc tDOT2 tDOT3 - right tEH tCOLON - left kRESCUE_MOD - right tEQL tOP_ASGN - nonassoc kDEFINED - right kNOT - left kOR kAND - nonassoc kIF_MOD kUNLESS_MOD kWHILE_MOD kUNTIL_MOD - nonassoc tLBRACE_ARG - nonassoc tLOWEST -preclow - -rule - - program: top_compstmt - - top_compstmt: top_stmts opt_terms - { - result = new_compstmt val[0] - } - - top_stmts: # none - { - result = new_block - } - | top_stmt - { - result = new_block val[0] - } - | top_stmts terms top_stmt - { - val[0] << val[2] - result = val[0] - } - - top_stmt: stmt - | klBEGIN tLCURLY top_compstmt tRCURLY - { - result = val[2] - } - - bodystmt: compstmt opt_rescue opt_else opt_ensure - { - result = new_body(val[0], val[1], val[2], val[3]) - } - - compstmt: stmts opt_terms - { - result = new_compstmt val[0] - } - - stmts: # none - { - result = new_block - } - | stmt - { - result = new_block val[0] - } - | stmts terms stmt - { - val[0] << val[2] - result = val[0] - } - - stmt: kALIAS fitem - { - lexer.lex_state = :expr_fname - } - fitem - { - result = new_alias(val[0], val[1], val[3]) - } - | kALIAS tGVAR tGVAR - { - result = s(:valias, value(val[1]).to_sym, value(val[2]).to_sym) - } - | kALIAS tGVAR tBACK_REF - | kALIAS tGVAR tNTH_REF - { - result = s(:valias, value(val[1]).to_sym, value(val[2]).to_sym) - } - | kUNDEF undef_list - { - result = val[1] - } - | stmt kIF_MOD expr_value - { - result = new_if(val[1], val[2], val[0], nil) - } - | stmt kUNLESS_MOD expr_value - { - result = new_if(val[1], val[2], nil, val[0]) - } - | stmt kWHILE_MOD expr_value - { - result = new_while(val[1], val[2], val[0]) - } - | stmt kUNTIL_MOD expr_value - { - result = new_until(val[1], val[2], val[0]) - } - | stmt kRESCUE_MOD stmt - { - result = new_rescue_mod(val[1], val[0], val[2]) - } - | klEND tLCURLY compstmt tRCURLY - | lhs tEQL command_call - { - result = new_assign(val[0], val[1], val[2]) - } - | mlhs tEQL command_call - { - result = s(:masgn, val[0], s(:to_ary, val[2])) - } - | var_lhs tOP_ASGN command_call - { - result = new_op_asgn val[1], val[0], val[2] - } - | primary_value tLBRACK2 aref_args tRBRACK tOP_ASGN command_call - | primary_value tJSLBRACK aref_args tRBRACK tOP_ASGN command_call - | primary_value tDOT tIDENTIFIER tOP_ASGN command_call - { - result = s(:op_asgn2, val[0], op_to_setter(val[2]), value(val[3]).to_sym, val[4]) - } - | primary_value tDOT tCONSTANT tOP_ASGN command_call - | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_call - | backref tOP_ASGN command_call - | lhs tEQL mrhs - { - result = new_assign val[0], val[1], s(:svalue, val[2]) - } - | mlhs tEQL arg_value - { - result = s(:masgn, val[0], s(:to_ary, val[2])) - } - | mlhs tEQL mrhs - { - result = s(:masgn, val[0], val[2]) - } - | expr - - expr: command_call - | expr kAND expr - { - result = s(:and, val[0], val[2]) - } - | expr kOR expr - { - result = s(:or, val[0], val[2]) - } - | kNOT expr - { - result = new_unary_call(['!', []], val[1]) - } - | tBANG command_call - { - result = new_unary_call(val[0], val[1]) - } - | arg - - expr_value: expr - - command_call: command - | block_command - | kRETURN call_args - { - result = new_return(val[0], val[1]) - } - | kBREAK call_args - { - result = new_break(val[0], val[1]) - } - | kNEXT call_args - { - result = new_next(val[0], val[1]) - } - - block_command: block_call - | block_call tJSDOT operation2 command_args - | block_call tDOT operation2 command_args - | block_call tCOLON2 operation2 command_args - - cmd_brace_block: tLBRACE_ARG opt_block_var compstmt tRCURLY - - command: operation command_args =tLOWEST - { - result = new_call(nil, val[0], val[1]) - } - | operation command_args cmd_brace_block - | primary_value tJSDOT operation2 command_args =tLOWEST - { - result = new_js_call(val[0], val[2], val[3]) - } - | primary_value tJSDOT operation2 command_args cmd_brace_block - | primary_value tDOT operation2 command_args =tLOWEST - { - result = new_call(val[0], val[2], val[3]) - } - | primary_value tDOT operation2 command_args cmd_brace_block - | primary_value tCOLON2 operation2 command_args =tLOWEST - { - result = new_call(val[0], val[2], val[3]) - } - | primary_value tCOLON2 operation2 command_args cmd_brace_block - | kSUPER command_args - { - result = new_super(val[0], val[1]) - } - | kYIELD command_args - { - result = new_yield val[1] - } - - mlhs: mlhs_basic - { - result = val[0] - } - | tLPAREN mlhs_entry tRPAREN - { - result = val[1] - } - - mlhs_entry: mlhs_basic - { - result = val[0] - } - | tLPAREN mlhs_entry tRPAREN - { - result = val[1] - } - - mlhs_basic: mlhs_head - { - result = val[0] - } - | mlhs_head mlhs_item - { - result = val[0] << val[1] - } - | mlhs_head tSTAR mlhs_node - { - result = val[0] << s(:splat, val[2]) - } - | mlhs_head tSTAR mlhs_node tCOMMA mlhs_post - | mlhs_head tSTAR - { - result = val[0] << s(:splat) - } - | mlhs_head tSTAR tCOMMA mlhs_post - | tSTAR mlhs_node - { - result = s(:array, s(:splat, val[1])) - } - | tSTAR - { - result = s(:array, s(:splat)) - } - | tSTAR tCOMMA mlhs_post - - mlhs_item: mlhs_node - { - result = val[0] - } - | tLPAREN mlhs_entry tRPAREN - { - result = val[1] - } - - mlhs_head: mlhs_item tCOMMA - { - result = s(:array, val[0]) - } - | mlhs_head mlhs_item tCOMMA - { - result = val[0] << val[1] - } - - mlhs_post: mlhs_item - | mlhs_post tCOMMA mlhs_item - - mlhs_node: variable - { - result = new_assignable val[0] - } - | primary_value tLBRACK2 aref_args tRBRACK - { - args = val[2] ? val[2] : [] - result = s(:attrasgn, val[0], :[]=, s(:arglist, *args)) - } - | primary_value tDOT tIDENTIFIER - { - result = new_call val[0], val[2], [] - } - | primary_value tCOLON2 tIDENTIFIER - | primary_value tDOT tCONSTANT - | primary_value tCOLON2 tCONSTANT - | tCOLON3 tCONSTANT - | backref - - lhs: variable - { - result = new_assignable val[0] - } - | primary_value tJSLBRACK aref_args tRBRACK - { - result = new_js_attrasgn(val[0], val[2]) - } - | primary_value tLBRACK2 aref_args tRBRACK - { - result = new_attrasgn(val[0], :[]=, val[2]) - } - | primary_value tDOT tIDENTIFIER - { - result = new_attrasgn(val[0], op_to_setter(val[2])) - } - | primary_value tCOLON2 tIDENTIFIER - { - result = new_attrasgn(val[0], op_to_setter(val[2])) - } - | primary_value tDOT tCONSTANT - { - result = new_attrasgn(val[0], op_to_setter(val[2])) - } - | primary_value tCOLON2 tCONSTANT - { - result = new_colon2(val[0], val[1], val[2]) - } - | tCOLON3 tCONSTANT - { - result = new_colon3(val[0], val[1]) - } - | backref - - cname: tCONSTANT - - cpath: tCOLON3 cname - { - result = new_colon3(val[0], val[1]) - } - | cname - { - result = new_const(val[0]) - } - | primary_value tCOLON2 cname - { - result = new_colon2(val[0], val[1], val[2]) - } - - fname: tIDENTIFIER - | tCONSTANT - | tFID - | op - { - lexer.lex_state = :expr_end - result = val[0] - } - | reswords - { - lexer.lex_state = :expr_end - result = val[0] - } - - fitem: fname - { - result = new_sym(val[0]) - } - | symbol - - undef_list: fitem - { - result = s(:undef, val[0]) - } - | undef_list tCOMMA fitem - { - result = val[0] << val[2] - } - - op: tPIPE | tCARET | tAMPER2 | tCMP | tEQ | tEQQ - | tMATCH | tNMATCH | tGT | tGEQ | tLT | tLEQ - | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2 - | tSTAR | tDIVIDE | tPERCENT | tPOW | tBANG | tTILDE - | tUPLUS | tUMINUS | tAREF | tASET | tBACK_REF2 - - reswords: k__LINE__ | k__FILE__ | klBEGIN | klEND | kALIAS | kAND - | kBEGIN | kBREAK | kCASE | kCLASS | kDEF | kDEFINED - | kDO | kELSE | kELSIF | kEND | kENSURE | kFALSE - | kFOR | kIN | kMODULE | kNEXT | kNIL | kNOT - | kOR | kREDO | kRESCUE | kRETRY | kRETURN | kSELF - | kSUPER | kTHEN | kTRUE | kUNDEF | kWHEN | kYIELD - | kIF_MOD | kUNLESS_MOD | kWHILE_MOD | kUNTIL_MOD | kRESCUE_MOD - | kIF | kWHILE | kUNTIL | kUNLESS - - arg: lhs tEQL arg - { - result = new_assign(val[0], val[1], val[2]) - } - | lhs tEQL arg kRESCUE_MOD arg - { - result = new_assign val[0], val[1], s(:rescue_mod, val[2], val[4]) - } - | var_lhs tOP_ASGN arg - { - result = new_op_asgn val[1], val[0], val[2] - } - | primary_value tLBRACK2 aref_args tRBRACK tOP_ASGN arg - { - result = new_op_asgn1(val[0], val[2], val[4], val[5]) - } - | primary_value tJSLBRACK aref_args tRBRACK tOP_ASGN arg - { - raise ".JS[...] #{val[4]} is not supported" - } - | primary_value tDOT tIDENTIFIER tOP_ASGN arg - { - result = s(:op_asgn2, val[0], op_to_setter(val[2]), value(val[3]).to_sym, val[4]) - } - | primary_value tDOT tCONSTANT tOP_ASGN arg - | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg - | primary_value tCOLON2 tCONSTANT tOP_ASGN arg - | tCOLON3 tCONSTANT tOP_ASGN arg - | backref tOP_ASGN arg - | arg tDOT2 arg - { - result = new_irange(val[0], val[1], val[2]) - } - | arg tDOT3 arg - { - result = new_erange(val[0], val[1], val[2]) - } - | arg tPLUS arg - { - result = new_binary_call(val[0], val[1], val[2]) - } - | arg tMINUS arg - { - result = new_binary_call(val[0], val[1], val[2]) - } - | arg tSTAR2 arg - { - result = new_binary_call(val[0], val[1], val[2]) - } - | arg tDIVIDE arg - { - result = new_binary_call(val[0], val[1], val[2]) - } - | arg tPERCENT arg - { - result = new_binary_call(val[0], val[1], val[2]) - } - | arg tPOW arg - { - result = new_binary_call(val[0], val[1], val[2]) - } - | '-@NUM' tINTEGER tPOW arg - { - result = new_call new_binary_call(new_int(val[1]), val[2], val[3]), [:"-@", []], [] - } - | '-@NUM' tFLOAT tPOW arg - { - result = new_call new_binary_call(new_float(val[1]), val[2], val[3]), [:"-@", []], [] - } - | tUPLUS arg - { - result = new_call val[1], [:"+@", []], [] - if [:int, :float].include? val[1].type - result = val[1] - end - } - | tUMINUS arg - { - result = new_call val[1], [:"-@", []], [] - if val[1].type == :int - val[1][1] = -val[1][1] - result = val[1] - elsif val[1].type == :float - val[1][1] = -val[1][1].to_f - result = val[1] - end - } - | arg tPIPE arg - { - result = new_binary_call(val[0], val[1], val[2]) - } - | arg tCARET arg - { - result = new_binary_call(val[0], val[1], val[2]) - } - | arg tAMPER2 arg - { - result = new_binary_call(val[0], val[1], val[2]) - } - | arg tCMP arg - { - result = new_binary_call(val[0], val[1], val[2]) - } - | arg tGT arg - { - result = new_binary_call(val[0], val[1], val[2]) - } - | arg tGEQ arg - { - result = new_binary_call(val[0], val[1], val[2]) - } - | arg tLT arg - { - result = new_binary_call(val[0], val[1], val[2]) - } - | arg tLEQ arg - { - result = new_binary_call(val[0], val[1], val[2]) - } - | arg tEQ arg - { - result = new_binary_call(val[0], val[1], val[2]) - } - | arg tEQQ arg - { - result = new_binary_call(val[0], val[1], val[2]) - } - | arg tNEQ arg - { - result = new_binary_call(val[0], val[1], val[2]) - } - | arg tMATCH arg - { - result = new_binary_call(val[0], val[1], val[2]) - } - | arg tNMATCH arg - { - result = new_binary_call(val[0], val[1], val[2]) - } - | tBANG arg - { - result = new_unary_call(val[0], val[1]) - } - | tTILDE arg - { - result = new_unary_call(val[0], val[1]) - } - | arg tLSHFT arg - { - result = new_binary_call(val[0], val[1], val[2]) - } - | arg tRSHFT arg - { - result = new_binary_call(val[0], val[1], val[2]) - } - | arg tANDOP arg - { - result = new_and(val[0], val[1], val[2]) - } - | arg tOROP arg - { - result = new_or(val[0], val[1], val[2]) - } - | kDEFINED opt_nl arg - { - result = s(:defined, val[2]) - } - | arg tEH arg tCOLON arg - { - result = new_if(val[1], val[0], val[2], val[4]) - } - | primary - - arg_value: arg - - aref_args: none - { - result = nil - } - | command opt_nl - { - result = [val[0]] - } - | args trailer - { - result = val[0] - } - | args tCOMMA assocs trailer - { - val[0] << s(:hash, *val[2]) - result = val[0] - } - | assocs trailer - { - result = [s(:hash, *val[0])] - } - - paren_args: tLPAREN2 opt_call_args rparen - { - result = val[1] - } - - rparen: opt_nl tRPAREN - - opt_paren_args: none - { - result = [] - } - | paren_args - - opt_call_args: none - { - result = [] - } - | call_args - | args tCOMMA - { - result = val[0] - } - | args tCOMMA assocs tCOMMA - { - result = val[0] - result << new_hash(nil, val[2], nil) - } - | assocs tCOMMA - { - result = [new_hash(nil, val[0], nil)] - } - - call_args: command - { - result = [val[0]] - } - | args opt_block_arg - { - result = val[0] - add_block_pass val[0], val[1] - } - | assocs opt_block_arg - { - result = [new_hash(nil, val[0], nil)] - add_block_pass result, val[1] - } - | args tCOMMA assocs opt_block_arg - { - result = val[0] - result << new_hash(nil, val[2], nil) - result << val[3] if val[3] - } - | block_arg - { - result = [] - add_block_pass result, val[0] - } - - call_args2: arg_value tCOMMA args opt_block_arg - | block_arg - - command_args: { - lexer.cmdarg_push 1 - } - open_args - { - lexer.cmdarg_pop - result = val[1] - } - - open_args: call_args - | tLPAREN_ARG tRPAREN - { - result = nil - } - | tLPAREN_ARG call_args2 tRPAREN - { - result = val[1] - } - - block_arg: tAMPER arg_value - { - result = new_block_pass(val[0], val[1]) - } - - opt_block_arg: tCOMMA block_arg - { - result = val[1] - } - | # none - { - result = nil - } - - args: arg_value - { - result = [val[0]] - } - | tSTAR arg_value - { - result = [new_splat(val[0], val[1])] - } - | args tCOMMA arg_value - { - result = val[0] << val[2] - } - | args tCOMMA tSTAR arg_value - { - result = val[0] << new_splat(val[2], val[3]) - } - - mrhs: args tCOMMA arg_value - { - val[0] << val[2] - result = s(:array, *val[0]) - } - | args tCOMMA tSTAR arg_value - { - val[0] << s(:splat, val[3]) - result = s(:array, *val[0]) - } - | tSTAR arg_value - { - result = s(:splat, val[1]) - } - - primary: literal - | strings - | xstring - | regexp - | words - | awords - | var_ref - | backref - | tFID - | kBEGIN - { - result = lexer.line - } - bodystmt kEND - { - result = s(:begin, val[2]) - } - | tLPAREN_ARG expr opt_nl tRPAREN - { - result = val[1] - } - | tLPAREN compstmt tRPAREN - { - result = new_paren(val[0], val[1], val[2]) - } - | primary_value tCOLON2 tCONSTANT - { - result = new_colon2(val[0], val[1], val[2]) - } - | tCOLON3 tCONSTANT - { - result = new_colon3(val[0], val[1]) - } - | primary_value tLBRACK2 aref_args tRBRACK - { - result = new_call val[0], [:[], []], val[2] - } - | primary_value tJSLBRACK aref_args tRBRACK - { - result = new_js_call val[0], [:[], []], val[2] - } - | tLBRACK aref_args tRBRACK - { - result = new_array(val[0], val[1], val[2]) - } - | tLBRACE assoc_list tRCURLY - { - result = new_hash(val[0], val[1], val[2]) - } - | kRETURN - { - result = new_return(val[0]) - } - | kYIELD tLPAREN2 call_args tRPAREN - { - result = new_yield val[2] - } - | kYIELD tLPAREN2 tRPAREN - { - result = s(:yield) - } - | kYIELD - { - result = s(:yield) - } - | kDEFINED opt_nl tLPAREN2 expr tRPAREN - { - result = s(:defined, val[3]) - } - | kNOT tLPAREN2 expr tRPAREN - { - result = new_unary_call(['!', []], val[2]) - } - | kNOT tLPAREN2 tRPAREN - { - result = new_unary_call(['!', []], new_nil(val[0])) - } - | operation brace_block - { - result = new_call(nil, val[0], []) - result << val[1] - } - | method_call - | method_call brace_block - { - val[0] << val[1] - result = val[0] - } - | tLAMBDA lambda - { - result = val[1] - } - | kIF expr_value then compstmt if_tail kEND - { - result = new_if(val[0], val[1], val[3], val[4]) - } - | kUNLESS expr_value then compstmt opt_else kEND - { - result = new_if(val[0], val[1], val[4], val[3]) - } - | kWHILE - { - lexer.cond_push 1 - result = lexer.line - } - expr_value do - { - lexer.cond_pop - } - compstmt kEND - { - result = s(:while, val[2], val[5]) - } - | kUNTIL - { - lexer.cond_push 1 - result = lexer.line - } - expr_value do - { - lexer.cond_pop - } - compstmt kEND - { - result = s(:until, val[2], val[5]) - } - | kCASE expr_value opt_terms case_body kEND - { - result = s(:case, val[1], *val[3]) - } - | kCASE opt_terms case_body kEND - { - result = s(:case, nil, *val[2]) - } - | kCASE opt_terms kELSE compstmt kEND - { - result = s(:case, nil, val[3]) - } - | kFOR for_var kIN - { - lexer.cond_push 1 - result = lexer.line - } - expr_value do - { - lexer.cond_pop - } - compstmt kEND - { - result = s(:for, val[4], val[1], val[7]) - } - | kCLASS cpath superclass - { - # ... - } - bodystmt kEND - { - result = new_class val[0], val[1], val[2], val[4], val[5] - } - | kCLASS tLSHFT - { - result = lexer.line - } - expr term - { - # ... - } - bodystmt kEND - { - result = new_sclass(val[0], val[3], val[6], val[7]) - } - | kMODULE - { - result = lexer.line - } - cpath - { - # ... - } - bodystmt kEND - { - result = new_module(val[0], val[2], val[4], val[5]) - } - | kDEF fname - { - push_scope - lexer.lex_state = :expr_endfn - } - f_arglist bodystmt kEND - { - result = new_def(val[0], nil, val[1], val[3], val[4], val[5]) - pop_scope - } - | kDEF singleton dot_or_colon - { - lexer.lex_state = :expr_fname - } - fname - { - push_scope - lexer.lex_state = :expr_endfn - } - f_arglist bodystmt kEND - { - result = new_def(val[0], val[1], val[4], val[6], val[7], val[8]) - pop_scope - } - | kBREAK - { - result = new_break(val[0]) - } - | kNEXT - { - result = s(:next) - } - | kREDO - { - result = s(:redo) - } - | kRETRY - - primary_value: primary - - then: term - | tCOLON - | kTHEN - | term kTHEN - - do: term - | tCOLON - | kDO_COND - - lambda: f_larglist lambda_body - { - result = new_call nil, [:lambda, []], [] - result << new_iter(val[0], val[1]) - } - - f_larglist: tLPAREN2 block_param tRPAREN - { - result = val[1] - } - | tLPAREN2 tRPAREN - { - result = nil - } - | block_param - | none - - lambda_body: tLAMBEG compstmt tRCURLY - { - result = val[1] - } - | kDO_LAMBDA compstmt kEND - { - result = val[1] - } - - if_tail: opt_else - { - result = val[0] - } - | kELSIF expr_value then compstmt if_tail - { - result = new_if(val[0], val[1], val[3], val[4]) - } - - opt_else: none - | kELSE compstmt - { - result = val[1] - } - - f_block_optarg: f_block_opt - { - result = s(:block, val[0]) - } - | f_block_optarg tCOMMA f_block_opt - { - val[0] << val[2] - result = val[0] - } - - f_block_opt: tIDENTIFIER tEQL primary_value - { - result = new_assign(new_assignable(new_ident( - val[0])), val[1], val[2]) - } - - opt_block_var: none - | tPIPE tPIPE - { - result = nil - } - | tOROP - { - result = nil - } - | tPIPE block_param tPIPE - { - result = val[1] - } - - block_args_tail: f_block_arg - { - result = val[0] - } - -opt_block_args_tail: tCOMMA block_args_tail - { - result = val[1] - } - | none - { - nil - } - - block_param: f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg opt_block_args_tail - { - result = new_block_args(val[0], val[2], val[4], val[5]) - } - | f_arg tCOMMA f_block_optarg opt_block_args_tail - { - result = new_block_args(val[0], val[2], nil, val[3]) - } - | f_arg tCOMMA f_rest_arg opt_block_args_tail - { - result = new_block_args(val[0], nil, val[2], val[3]) - } - | f_arg tCOMMA - { - result = new_block_args(val[0], nil, nil, nil) - } - | f_arg opt_block_args_tail - { - result = new_block_args(val[0], nil, nil, val[1]) - } - | f_block_optarg tCOMMA f_rest_arg opt_block_args_tail - { - result = new_block_args(nil, val[0], val[2], val[3]) - } - | f_block_optarg opt_block_args_tail - { - result = new_block_args(nil, val[0], nil, val[1]) - } - | f_rest_arg opt_block_args_tail - { - result = new_block_args(nil, nil, val[0], val[1]) - } - | block_args_tail - { - result = new_block_args(nil, nil, nil, val[0]) - } - - do_block: kDO_BLOCK - { - push_scope :block - result = lexer.line - } - opt_block_var compstmt kEND - { - result = new_iter val[2], val[3] - pop_scope - } - - block_call: command do_block - { - val[0] << val[1] - result = val[0] - } - | block_call tJSDOT operation2 opt_paren_args - | block_call tDOT operation2 opt_paren_args - | block_call tCOLON2 operation2 opt_paren_args - - method_call: operation paren_args - { - result = new_call(nil, val[0], val[1]) - } - | primary_value tDOT operation2 opt_paren_args - { - result = new_call(val[0], val[2], val[3]) - } - | primary_value tJSDOT operation2 opt_paren_args - { - result = new_js_call(val[0], val[2], val[3]) - } - | primary_value tDOT paren_args - { - result = new_call(val[0], [:call, []], val[2]) - } - | primary_value tCOLON2 operation2 paren_args - { - result = new_call(val[0], val[2], val[3]) - } - | primary_value tCOLON2 operation3 - { - result = new_call(val[0], val[2]) - } - | kSUPER paren_args - { - result = new_super(val[0], val[1]) - } - | kSUPER - { - result = new_super(val[0], nil) - } - - brace_block: tLCURLY - { - push_scope :block - result = lexer.line - } - opt_block_var compstmt tRCURLY - { - result = new_iter val[2], val[3] - pop_scope - } - | kDO - { - push_scope :block - result = lexer.line - } - opt_block_var compstmt kEND - { - result = new_iter val[2], val[3] - pop_scope - } - - case_body: kWHEN - { - result = lexer.line - } - args then compstmt cases - { - part = s(:when, s(:array, *val[2]), val[4]) - result = [part] - result.push(*val[5]) if val[5] - } - - cases: opt_else - { - result = [val[0]] - } - | case_body - - opt_rescue: kRESCUE exc_list exc_var then compstmt opt_rescue - { - exc = val[1] || s(:array) - exc << new_assign(val[2], val[2], s(:gvar, '$!'.intern)) if val[2] - result = [s(:resbody, exc, val[4])] - result.push val[5].first if val[5] - } - | # none - { - result = nil - } - - exc_list: arg_value - { - result = s(:array, val[0]) - } - | mrhs - | none - - exc_var: tASSOC lhs - { - result = val[1] - } - | none - { - result = nil - } - - opt_ensure: kENSURE compstmt - { - result = val[1].nil? ? s(:nil) : val[1] - } - | none - - literal: numeric - | symbol - | dsym - - strings: string - { - result = new_str val[0] - } - - string: string1 - | string string1 - { - result = str_append val[0], val[1] - } - - string1: tSTRING_BEG string_contents tSTRING_END - { - result = val[1] - } - | tSTRING - { - result = s(:str, value(val[0])) - } - - xstring: tXSTRING_BEG xstring_contents tSTRING_END - { - result = new_xstr(val[0], val[1], val[2]) - } - - regexp: tREGEXP_BEG xstring_contents tREGEXP_END - { - result = new_regexp val[1], val[2] - } - - words: tWORDS_BEG tSPACE tSTRING_END - { - result = s(:array) - } - | tWORDS_BEG word_list tSTRING_END - { - result = val[1] - } - - word_list: none - { - result = s(:array) - } - | word_list word tSPACE - { - part = val[1] - part = s(:dstr, "", val[1]) if part.type == :evstr - result = val[0] << part - } - - word: string_content - { - result = val[0] - } - | word string_content - { - result = val[0].concat([val[1]]) - } - - awords: tAWORDS_BEG tSPACE tSTRING_END - { - result = s(:array) - } - | tAWORDS_BEG qword_list tSTRING_END - { - result = val[1] - } - - qword_list: none - { - result = s(:array) - } - | qword_list tSTRING_CONTENT tSPACE - { - result = val[0] << s(:str, value(val[1])) - } - - string_contents: none - { - result = nil - } - | string_contents string_content - { - result = str_append val[0], val[1] - } - -xstring_contents: none - { - result = nil - } - | xstring_contents string_content - { - result = str_append val[0], val[1] - } - - string_content: tSTRING_CONTENT - { - result = new_str_content(val[0]) - } - | tSTRING_DVAR - { - result = lexer.strterm - lexer.strterm = nil - } - string_dvar - { - lexer.strterm = val[1] - result = new_evstr(val[2]) - } - | tSTRING_DBEG - { - lexer.cond_push 0 - lexer.cmdarg_push 0 - result = lexer.strterm - lexer.strterm = nil - lexer.lex_state = :expr_beg - } - compstmt tRCURLY - { - lexer.strterm = val[1] - lexer.cond_lexpop - lexer.cmdarg_lexpop - result = new_evstr(val[2]) - } - - string_dvar: tGVAR - { - result = new_gvar(val[0]) - } - | tIVAR - { - result = new_ivar(val[0]) - } - | tCVAR - { - result = new_cvar(val[0]) - } - | backref - - - symbol: tSYMBEG sym - { - result = new_sym(val[1]) - lexer.lex_state = :expr_end - } - | tSYMBOL - { - result = new_sym(val[0]) - } - - sym: fname - | tIVAR - | tGVAR - | tCVAR - - dsym: tSYMBEG xstring_contents tSTRING_END - { - result = new_dsym val[1] - } - - numeric: tINTEGER - { - result = new_int(val[0]) - } - | tFLOAT - { - result = new_float(val[0]) - } - | '-@NUM' tINTEGER =tLOWEST - { - result = negate_num(new_int(val[1])) - } - | '-@NUM' tFLOAT =tLOWEST - { - result = negate_num(new_float(val[1])) - } - | '+@NUM' tINTEGER =tLOWEST - { - result = new_int(val[1]) - } - | '+@NUM' tFLOAT =tLOWEST - { - result = new_float(val[1]) - } - - variable: tIDENTIFIER - { - result = new_ident(val[0]) - } - | tIVAR - { - result = new_ivar(val[0]) - } - | tGVAR - { - result = new_gvar(val[0]) - } - | tCONSTANT - { - result = new_const(val[0]) - } - | tCVAR - { - result = new_cvar(val[0]) - } - | kNIL - { - result = new_nil(val[0]) - } - | kSELF - { - result = new_self(val[0]) - } - | kTRUE - { - result = new_true(val[0]) - } - | kFALSE - { - result = new_false(val[0]) - } - | k__FILE__ - { - result = new___FILE__(val[0]) - } - | k__LINE__ - { - result = new___LINE__(val[0]) - } - - var_ref: variable - { - result = new_var_ref(val[0]) - } - - var_lhs: variable - { - result = new_assignable val[0] - } - - backref: tNTH_REF - { - result = s(:nth_ref, value(val[0])) - } - | tBACK_REF - - superclass: term - { - result = nil - } - | tLT expr_value term - { - result = val[1] - } - | error term - { - result = nil - } - - f_arglist: tLPAREN2 f_args opt_nl tRPAREN - { - result = val[1] - lexer.lex_state = :expr_beg - } - | f_args term - { - result = val[0] - lexer.lex_state = :expr_beg - } - - kwrest_mark: tPOW - | tDSTAR - - f_kwrest: kwrest_mark tIDENTIFIER - { - result = new_kwrestarg(val[1]) - } - | kwrest_mark - { - result = new_kwrestarg() - } - - f_label: tLABEL - { - result = new_sym(val[0]) - } - - f_kw: f_label arg_value - { - result = new_kwoptarg(val[0], val[1]) - } - | f_label - { - result = new_kwarg(val[0]) - } - - f_kwarg: f_kw - { - result = [val[0]] - } - | f_kwarg tCOMMA f_kw - { - result = val[0] - result << val[2] - } - - args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg - { - result = new_args_tail(val[0], val[2], val[3]) - } - | f_kwarg opt_f_block_arg - { - result = new_args_tail(val[0], nil, val[1]) - } - | f_kwrest opt_f_block_arg - { - result = new_args_tail(nil, val[0], val[1]) - } - | f_block_arg - { - result = new_args_tail(nil, nil, val[0]) - } - - opt_args_tail: tCOMMA args_tail - { - result = val[1] - } - | # none - { - result = new_args_tail(nil, nil, nil) - } - - f_args: f_arg tCOMMA f_optarg tCOMMA f_rest_arg opt_args_tail - { - result = new_args(val[0], val[2], val[4], val[5]) - } - | f_arg tCOMMA f_optarg opt_args_tail - { - result = new_args(val[0], val[2], nil, val[3]) - } - | f_arg tCOMMA f_rest_arg opt_args_tail - { - result = new_args(val[0], nil, val[2], val[3]) - } - | f_arg opt_args_tail - { - result = new_args(val[0], nil, nil, val[1]) - } - | f_optarg tCOMMA f_rest_arg opt_args_tail - { - result = new_args(nil, val[0], val[2], val[3]) - } - | f_optarg opt_args_tail - { - result = new_args(nil, val[0], nil, val[1]) - } - | f_rest_arg opt_args_tail - { - result = new_args(nil, nil, val[0], val[1]) - } - | args_tail - { - result = new_args(nil, nil, nil, val[0]) - } - | # none - { - result = new_args(nil, nil, nil, nil) - } - - f_norm_arg: f_bad_arg - | tIDENTIFIER - { - result = value(val[0]).to_sym - scope.add_local result - } - - f_bad_arg: tCONSTANT - { - raise 'formal argument cannot be a constant' - } - | tIVAR - { - raise 'formal argument cannot be an instance variable' - } - | tCVAR - { - raise 'formal argument cannot be a class variable' - } - | tGVAR - { - raise 'formal argument cannot be a global variable' - } - - f_arg_item: f_norm_arg - { - result = val[0] - } - | tLPAREN f_margs tRPAREN - { - result = val[1] - } - - for_var: lhs - | mlhs - - f_marg: f_norm_arg - { - result = s(:lasgn, val[0]) - } - | tLPAREN f_margs tRPAREN - - f_marg_list: f_marg - { - result = s(:array, val[0]) - } - | f_marg_list tCOMMA f_marg - { - val[0] << val[2] - result = val[0] - } - - f_margs: f_marg_list - | f_marg_list tCOMMA tSTAR f_norm_arg - | f_marg_list tCOMMA tSTAR - | tSTAR f_norm_arg - | tSTAR - - f_arg: f_arg_item - { - result = [val[0]] - } - | f_arg tCOMMA f_arg_item - { - val[0] << val[2] - result = val[0] - } - - f_opt: tIDENTIFIER tEQL arg_value - { - result = new_assign(new_assignable(new_ident(val[0])), val[1], val[2]) - } - - f_optarg: f_opt - { - result = s(:block, val[0]) - } - | f_optarg tCOMMA f_opt - { - result = val[0] - val[0] << val[2] - } - - restarg_mark: tSTAR2 - | tSTAR - - f_rest_arg: restarg_mark tIDENTIFIER - { - result = "*#{value(val[1])}".to_sym - } - | restarg_mark - { - result = :"*" - } - - blkarg_mark: tAMPER2 - | tAMPER - - f_block_arg: blkarg_mark tIDENTIFIER - { - result = "&#{value(val[1])}".to_sym - } - - opt_f_block_arg: tCOMMA f_block_arg - { - result = val[1] - } - | # none - { - result = nil - } - - singleton: var_ref - { - result = val[0] - } - | tLPAREN2 expr opt_nl tRPAREN - { - result = val[1] - } - - assoc_list: # none - { - result = [] - } - | assocs trailer - { - result = val[0] - } - - assocs: assoc - { - result = val[0] - } - | assocs tCOMMA assoc - { - result = val[0].push(*val[2]) - } - - assoc: arg_value tASSOC arg_value - { - result = [val[0], val[2]] - } - | tLABEL arg_value - { - result = [new_sym(val[0]), val[1]] - } - - operation: tIDENTIFIER - | tCONSTANT - | tFID - - operation2: tIDENTIFIER - | tCONSTANT - | tFID - | op - - operation3: tIDENTIFIER - | tFID - | op - - dot_or_colon: tDOT - | tCOLON2 - - opt_terms: # none - | terms - - opt_nl: # none - | tNL - - trailer: # none - | tNL - | tCOMMA - - term: tSEMI - | tNL - - terms: term - | terms tSEMI - - none: # none - { - result = nil - } -end - ----- inner diff --git a/test/racc/assets/opt.y b/test/racc/assets/opt.y deleted file mode 100644 index a011953a51..0000000000 --- a/test/racc/assets/opt.y +++ /dev/null @@ -1,123 +0,0 @@ -# -# check options working -# - -class Calcp - - prechigh - left '*' '/' - left '+' '-' - preclow - - convert - NUMBER 'Number' - end - - options no_omit_action_call no_result_var - -rule - - target : exp | /* none */ { 0 } ; - - exp : exp '+' exp { chk(val[0] + val[2]) } - | exp '-' exp { chk(val[0] - val[2]) } - | exp '*' exp { chk(val[0] * val[2]) } - | exp '/' exp { chk(val[0] / val[2]) } - | '(' { $emb = true } exp ')' - { - raise 'must not happen' unless $emb - val[2] - } - | '-' NUMBER { -val[1] } - | NUMBER - ; - -end - -----header - -class Number; end - -----inner - - def parse( src ) - @src = src - do_parse - end - - def next_token - @src.shift - end - - def initialize - @yydebug = true - end - - def chk( i ) - # p i - i - end - -----footer - -$parser = Calcp.new -$test_number = 1 - -def chk( src, ans ) - result = $parser.parse(src) - raise "test #{$test_number} failed" unless result == ans - $test_number += 1 -end - -chk( - [ [Number, 9], - [false, false], - [false, false] ], 9 -) - -chk( - [ [Number, 5], - ['*', nil], - [Number, 1], - ['-', nil], - [Number, 1], - ['*', nil], - [Number, 8], - [false, false], - [false, false] ], -3 -) - -chk( - [ [Number, 5], - ['+', nil], - [Number, 2], - ['-', nil], - [Number, 5], - ['+', nil], - [Number, 2], - ['-', nil], - [Number, 5], - [false, false], - [false, false] ], -1 -) - -chk( - [ ['-', nil], - [Number, 4], - [false, false], - [false, false] ], -4 -) - -chk( - [ [Number, 7], - ['*', nil], - ['(', nil], - [Number, 4], - ['+', nil], - [Number, 3], - [')', nil], - ['-', nil], - [Number, 9], - [false, false], - [false, false] ], 40 -) diff --git a/test/racc/assets/percent.y b/test/racc/assets/percent.y deleted file mode 100644 index 68d63583ca..0000000000 --- a/test/racc/assets/percent.y +++ /dev/null @@ -1,35 +0,0 @@ -class ScannerChecker -rule - target: A - { - i = 7 - i %= 4 - raise 'assert failed' unless i == 3 - tmp = %-This is percent string.- - raise 'assert failed' unless tmp == 'This is percent string.' - a = 5; b = 3 - assert_equal(2,(a%b)) #A - # assert_equal(2,(a %b)) # is %-string - assert_equal(2,(a% b)) #B - assert_equal(2,(a % b)) #C - } -end - ----- inner ---- - - def parse - @q = [[:A, 'A'], [false, '$']] - do_parse - end - - def next_token - @q.shift - end - - def assert_equal( expect, real ) - raise "expect #{expect.inspect} but #{real.inspect}" unless expect == real - end - ----- footer ---- - -parser = ScannerChecker.new.parse diff --git a/test/racc/assets/php_serialization.y b/test/racc/assets/php_serialization.y deleted file mode 100644 index 99f78f2081..0000000000 --- a/test/racc/assets/php_serialization.y +++ /dev/null @@ -1,98 +0,0 @@ -# MIT License -# See https://github.com/divoxx/ruby-php-serialization/blob/master/LICENSE.txt - -class PhpSerialization::Unserializer -rule - - data : null ';' { @object = val[0] } - | bool ';' { @object = val[0] } - | integer ';' { @object = val[0] } - | double ';' { @object = val[0] } - | string ';' { @object = val[0] } - | assoc_array { @object = val[0] } - | object { @object = val[0] } - ; - - null : 'N' { result = nil } - ; - - bool : 'b' ':' NUMBER { result = Integer(val[2]) > 0 } - ; - - integer : 'i' ':' NUMBER { result = Integer(val[2]) } - ; - - double : 'd' ':' NUMBER { result = Float(val[2]) } - ; - - string : 's' ':' NUMBER ':' STRING { result = val[4] } - ; - - object : 'O' ':' NUMBER ':' STRING ':' NUMBER ':' '{' attribute_list '}' - { - if eval("defined?(#{val[4]})") - result = Object.const_get(val[4]).new - - val[9].each do |(attr_name, value)| - # Protected and private attributes will have a \0..\0 prefix - attr_name = attr_name.gsub(/\A\\0[^\\]+\\0/, '') - result.instance_variable_set("@#{attr_name}", value) - end - else - klass_name = val[4].gsub(/^Struct::/, '') - attr_names, values = [], [] - - val[9].each do |(attr_name, value)| - # Protected and private attributes will have a \0..\0 prefix - attr_names << attr_name.gsub(/\A\\0[^\\]+\\0/, '') - values << value - end - - result = Struct.new(klass_name, *attr_names).new(*values) - result.instance_variable_set("@_php_class", klass_name) - end - } - ; - - attribute_list : attribute_list attribute { result = val[0] << val[1] } - | { result = [] } - ; - - attribute : data data { result = val } - ; - - assoc_array : 'a' ':' NUMBER ':' '{' attribute_list '}' - { - # Checks if the keys are a sequence of integers - idx = -1 - arr = val[5].all? { |(k,v)| k == (idx += 1) } - - if arr - result = val[5].map { |(k,v)| v } - else - result = Hash[val[5]] - end - } - ; - -end - ----- header ---- -require 'php_serialization/tokenizer' - ----- inner ---- - def initialize(tokenizer_klass = Tokenizer) - @tokenizer_klass = tokenizer_klass - end - - def run(string) - @tokenizer = @tokenizer_klass.new(string) - yyparse(@tokenizer, :each) - return @object - ensure - @tokenizer = nil - end - - def next_token - @tokenizer.next_token - end diff --git a/test/racc/assets/recv.y b/test/racc/assets/recv.y deleted file mode 100644 index b6e849dda9..0000000000 --- a/test/racc/assets/recv.y +++ /dev/null @@ -1,97 +0,0 @@ -# s/r 5, r/r 10 -class A -rule - - content: RecvH received - ; - - datetime: day - ; - - msgid: '<' spec '>'; - - day: - | ATOM ',' - ; - - received: recvitem_list recvdatetime - ; - - recvitem_list: - | recvitem_list recvitem - ; - - recvitem: by | via | with | for ; - - by: - | BY domain - ; - - via: - | VIA ATOM - ; - - with: WITH ATOM - ; - - for: - | FOR addr - ; - - recvdatetime: - | ';' datetime - ; - - addr: mbox | group ; - - mboxes: mbox - | mboxes ',' mbox - ; - - mbox: spec - | routeaddr - | phrase routeaddr - ; - - group: phrase ':' mboxes ';' - ; - - routeaddr: '<' route spec '>' - | '<' spec '>' - ; - - route: at_domains ':' ; - - at_domains: '@' domain - | at_domains ',' '@' domain - ; - - spec: local '@' domain - | local - ; - - local: word - | local '.' word - ; - - domain: domword - | domain '.' domword - ; - - domword: atom - | DOMLIT - | DIGIT - ; - - phrase: word - | phrase word - ; - - word: atom - | QUOTED - | DIGIT - ; - - atom: ATOM | FROM | BY | VIA | WITH | ID | FOR ; - -end diff --git a/test/racc/assets/riml.y b/test/racc/assets/riml.y deleted file mode 100644 index 1d99b0fdb8..0000000000 --- a/test/racc/assets/riml.y +++ /dev/null @@ -1,665 +0,0 @@ -# Copyright (c) 2012-2014 by Luke Gruber -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be included -# in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -class Riml::Parser - -token IF ELSE ELSEIF THEN UNLESS END -token WHILE UNTIL BREAK CONTINUE -token TRY CATCH FINALLY -token FOR IN -token DEF DEF_BANG SPLAT_PARAM SPLAT_ARG CALL BUILTIN_COMMAND # such as echo "hi" -token CLASS NEW DEFM DEFM_BANG SUPER -token RIML_FILE_COMMAND RIML_CLASS_COMMAND -token RETURN -token NEWLINE -token NUMBER -token STRING_D STRING_S # single- and double-quoted -token EX_LITERAL -token REGEXP -token TRUE FALSE -token LET UNLET UNLET_BANG IDENTIFIER -token DICT_VAL # like dict.key, 'key' is a DICT_VAL -token SCOPE_MODIFIER SCOPE_MODIFIER_LITERAL SPECIAL_VAR_PREFIX -token FINISH - -prechigh - right '!' - left '*' '/' '%' - left '+' '-' '.' - left '>' '>#' '>?' '<' '<#' '<?' '>=' '>=#' '>=?' '<=' '<=#' '<=?' - left '==' '==?' '==#' '=~' '=~?' '=~#' '!~' '!~?' '!~#' '!=' '!=?' '!=#' - left IS ISNOT - left '&&' - left '||' - right '?' - right '=' '+=' '-=' '.=' - left ',' - left IF UNLESS -preclow - -# All rules -rule - - Root: - /* nothing */ { result = make_node(val) { |_| Riml::Nodes.new([]) } } - | Terminator { result = make_node(val) { |_| Riml::Nodes.new([]) } } - | Statements { result = val[0] } - ; - - # any list of expressions - Statements: - Statement { result = make_node(val) { |v| Riml::Nodes.new([ v[0] ]) } } - | Statements Terminator Statement { result = val[0] << val[2] } - | Statements Terminator { result = val[0] } - | Terminator Statements { result = make_node(val) { |v| Riml::Nodes.new(v[1]) } } - ; - - # All types of expressions in Riml - Statement: - ExplicitCall { result = val[0] } - | Def { result = val[0] } - | Return { result = val[0] } - | UnletVariable { result = val[0] } - | ExLiteral { result = val[0] } - | For { result = val[0] } - | While { result = val[0] } - | Until { result = val[0] } - | Try { result = val[0] } - | ClassDefinition { result = val[0] } - | LoopKeyword { result = val[0] } - | EndScript { result = val[0] } - | RimlFileCommand { result = val[0] } - | RimlClassCommand { result = val[0] } - | MultiAssign { result = val[0] } - | If { result = val[0] } - | Unless { result = val[0] } - | Expression { result = val[0] } - ; - - Expression: - ExpressionWithoutDictLiteral { result = val[0] } - | Dictionary { result = val[0] } - | Dictionary DictGetWithDotLiteral { result = make_node(val) { |v| Riml::DictGetDotNode.new(v[0], v[1]) } } - | BinaryOperator { result = val[0] } - | Ternary { result = val[0] } - | Assign { result = val[0] } - | Super { result = val[0] } - | '(' Expression ')' { result = make_node(val) { |v| Riml::WrapInParensNode.new(v[1]) } } - ; - - ExpressionWithoutDictLiteral: - UnaryOperator { result = val[0] } - | DictGet { result = val[0] } - | ListOrDictGet { result = val[0] } - | AllVariableRetrieval { result = val[0] } - | LiteralWithoutDictLiteral { result = val[0] } - | Call { result = val[0] } - | ObjectInstantiation { result = val[0] } - | '(' ExpressionWithoutDictLiteral ')' { result = make_node(val) { |v| Riml::WrapInParensNode.new(v[1]) } } - ; - - # for inside curly-brace variable names - PossibleStringValue: - String { result = val[0] } - | DictGet { result = val[0] } - | ListOrDictGet { result = val[0] } - | AllVariableRetrieval { result = val[0] } - | BinaryOperator { result = val[0] } - | Ternary { result = val[0] } - | Call { result = val[0] } - ; - - Terminator: - NEWLINE { result = nil } - | ';' { result = nil } - ; - - LiteralWithoutDictLiteral: - Number { result = val[0] } - | String { result = val[0] } - | Regexp { result = val[0] } - | List { result = val[0] } - | ScopeModifierLiteral { result = val[0] } - | TRUE { result = make_node(val) { |_| Riml::TrueNode.new } } - | FALSE { result = make_node(val) { |_| Riml::FalseNode.new } } - ; - - Number: - NUMBER { result = make_node(val) { |v| Riml::NumberNode.new(v[0]) } } - ; - - String: - STRING_S { result = make_node(val) { |v| Riml::StringNode.new(v[0], :s) } } - | STRING_D { result = make_node(val) { |v| Riml::StringNode.new(v[0], :d) } } - | String STRING_S { result = make_node(val) { |v| Riml::StringLiteralConcatNode.new(v[0], Riml::StringNode.new(v[1], :s)) } } - | String STRING_D { result = make_node(val) { |v| Riml::StringLiteralConcatNode.new(v[0], Riml::StringNode.new(v[1], :d)) } } - ; - - Regexp: - REGEXP { result = make_node(val) { |v| Riml::RegexpNode.new(v[0]) } } - ; - - ScopeModifierLiteral: - SCOPE_MODIFIER_LITERAL { result = make_node(val) { |v| Riml::ScopeModifierLiteralNode.new(v[0]) } } - ; - - List: - ListLiteral { result = make_node(val) { |v| Riml::ListNode.new(v[0]) } } - ; - - ListUnpack: - '[' ListItems ';' Expression ']' { result = make_node(val) { |v| Riml::ListUnpackNode.new(v[1] << v[3]) } } - ; - - ListLiteral: - '[' ListItems ']' { result = val[1] } - | '[' ListItems ',' ']' { result = val[1] } - ; - - ListItems: - /* nothing */ { result = [] } - | Expression { result = [val[0]] } - | ListItems ',' Expression { result = val[0] << val[2] } - ; - - Dictionary: - DictionaryLiteral { result = make_node(val) { |v| Riml::DictionaryNode.new(v[0]) } } - ; - - # {'key': 'value', 'key2': 'value2'} - # Save as [['key', 'value'], ['key2', 'value2']] because ruby-1.8.7 offers - # no guarantee for key-value pair ordering. - DictionaryLiteral: - '{' DictItems '}' { result = val[1] } - | '{' DictItems ',' '}' { result = val[1] } - ; - - # [[key, value], [key, value]] - DictItems: - /* nothing */ { result = [] } - | DictItem { result = val } - | DictItems ',' DictItem { result = val[0] << val[2] } - ; - - # [key, value] - DictItem: - Expression ':' Expression { result = [val[0], val[2]] } - ; - - DictGet: - AllVariableRetrieval DictGetWithDot { result = make_node(val) { |v| Riml::DictGetDotNode.new(v[0], v[1]) } } - | ListOrDictGet DictGetWithDot { result = make_node(val) { |v| Riml::DictGetDotNode.new(v[0], v[1]) } } - | Call DictGetWithDot { result = make_node(val) { |v| Riml::DictGetDotNode.new(v[0], v[1]) } } - | '(' Expression ')' DictGetWithDot { result = make_node(val) { |v| Riml::DictGetDotNode.new(Riml::WrapInParensNode.new(v[1]), v[3]) } } - ; - - ListOrDictGet: - ExpressionWithoutDictLiteral ListOrDictGetWithBrackets { result = make_node(val) { |v| Riml::ListOrDictGetNode.new(v[0], v[1]) } } - | '(' Expression ')' ListOrDictGetWithBrackets { result = make_node(val) { |v| Riml::ListOrDictGetNode.new(Riml::WrapInParensNode.new(v[1]), v[3]) } } - ; - - ListOrDictGetAssign: - ExpressionWithoutDictLiteral ListOrDictGetWithBrackets { result = make_node(val) { |v| Riml::ListOrDictGetNode.new(v[0], v[1]) } } - ; - - ListOrDictGetWithBrackets: - '[' Expression ']' { result = [val[1]] } - | '[' SubList ']' { result = [val[1]] } - | ListOrDictGetWithBrackets '[' Expression ']' { result = val[0] << val[2] } - | ListOrDictGetWithBrackets '[' SubList ']' { result = val[0] << val[2] } - ; - - SubList: - Expression ':' Expression { result = make_node(val) { |v| Riml::SublistNode.new([v[0], Riml::LiteralNode.new(' : '), v[2]]) } } - | Expression ':' { result = make_node(val) { |v| Riml::SublistNode.new([v[0], Riml::LiteralNode.new(' :')]) } } - | ':' Expression { result = make_node(val) { |v| Riml::SublistNode.new([Riml::LiteralNode.new(': '), v[1]]) } } - | ':' { result = make_node(val) { |_| Riml::SublistNode.new([Riml::LiteralNode.new(':')]) } } - ; - - DictGetWithDot: - DICT_VAL { result = [val[0]] } - | DictGetWithDot DICT_VAL { result = val[0] << val[1] } - ; - - DictGetWithDotLiteral: - '.' IDENTIFIER { result = [val[1]] } - | DictGetWithDotLiteral DICT_VAL { result = val[0] << val[1] } - ; - - Call: - Scope DefCallIdentifier '(' ArgList ')' { result = make_node(val) { |v| Riml::CallNode.new(v[0], v[1], v[3]) } } - | DictGet '(' ArgList ')' { result = make_node(val) { |v| Riml::CallNode.new(nil, v[0], v[2]) } } - | BUILTIN_COMMAND '(' ArgList ')' { result = make_node(val) { |v| Riml::CallNode.new(nil, v[0], v[2]) } } - | BUILTIN_COMMAND ArgListWithoutNothing { result = make_node(val) { |v| Riml::CallNode.new(nil, v[0], v[1]) } } - | BUILTIN_COMMAND NEWLINE { result = make_node(val) { |v| Riml::CallNode.new(nil, v[0], []) } } - | CALL '(' ArgList ')' { result = make_node(val) { |v| Riml::ExplicitCallNode.new(nil, nil, v[2]) } } - ; - - ObjectInstantiationCall: - Scope DefCallIdentifier '(' ArgList ')' { result = make_node(val) { |v| Riml::CallNode.new(v[0], v[1], v[3]) } } - | Scope DefCallIdentifier { result = make_node(val) { |v| Riml::CallNode.new(v[0], v[1], []) } } - ; - - RimlFileCommand: - RIML_FILE_COMMAND '(' ArgList ')' { result = make_node(val) { |v| Riml::RimlFileCommandNode.new(nil, v[0], v[2]) } } - | RIML_FILE_COMMAND ArgList { result = make_node(val) { |v| Riml::RimlFileCommandNode.new(nil, v[0], v[1]) } } - ; - - RimlClassCommand: - RIML_CLASS_COMMAND '(' ClassArgList ')' { result = make_node(val) { |v| Riml::RimlClassCommandNode.new(nil, v[0], v[2]) } } - | RIML_CLASS_COMMAND ClassArgList { result = make_node(val) { |v| Riml::RimlClassCommandNode.new(nil, v[0], v[1]) } } - ; - - ClassArgList: - Scope IDENTIFIER { result = ["#{val[0]}#{val[1]}"] } - | String { result = val } - | ClassArgList ',' Scope IDENTIFIER { result = val[0].concat ["#{val[2]}#{val[3]}"] } - ; - - ExplicitCall: - CALL Scope DefCallIdentifier '(' ArgList ')' { result = make_node(val) { |v| Riml::ExplicitCallNode.new(v[1], v[2], v[4]) } } - | CALL DictGet '(' ArgList ')' { result = make_node(val) { |v| Riml::ExplicitCallNode.new(nil, v[1], v[3]) } } - ; - - Scope: - SCOPE_MODIFIER { result = val[0] } - | /* nothing */ { result = nil } - ; - - # [SID, scope_modifier] - SIDAndScope: - Scope { result = [ nil, val[0] ] } - | '<' IDENTIFIER '>' Scope { result = [ make_node(val) { |v| Riml::SIDNode.new(v[1]) }, val[3] ] } - ; - - ArgList: - /* nothing */ { result = [] } - | ArgListWithoutNothingWithSplat { result = val[0] } - ; - - ArgListWithSplat: - /* nothing */ { result = [] } - | ArgListWithoutNothingWithSplat { result = val[0] } - ; - - ArgListWithoutNothingWithSplat: - Expression { result = val } - | SPLAT_ARG Expression { result = [ make_node(val) { |v| Riml::SplatNode.new(v[1]) } ] } - | ArgListWithoutNothingWithSplat "," Expression { result = val[0] << val[2] } - | ArgListWithoutNothingWithSplat "," SPLAT_ARG Expression { result = val[0] << make_node(val) { |v| Riml::SplatNode.new(v[3]) } } - ; - - ArgListWithoutNothing: - Expression { result = val } - | ArgListWithoutNothing "," Expression { result = val[0] << val[2] } - ; - - BinaryOperator: - Expression '||' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } } - | Expression '&&' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } } - - | Expression '==' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } } - | Expression '==#' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } } - | Expression '==?' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } } - - # added by riml - | Expression '===' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } } - - | Expression '!=' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } } - | Expression '!=#' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } } - | Expression '!=?' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } } - - | Expression '=~' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } } - | Expression '=~#' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } } - | Expression '=~?' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } } - - | Expression '!~' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } } - | Expression '!~#' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } } - | Expression '!~?' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } } - - | Expression '>' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } } - | Expression '>#' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } } - | Expression '>?' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } } - - | Expression '>=' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } } - | Expression '>=#' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } } - | Expression '>=?' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } } - - | Expression '<' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } } - | Expression '<#' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } } - | Expression '<?' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } } - - | Expression '<=' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } } - | Expression '<=#' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } } - | Expression '<=?' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } } - - | Expression '+' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } } - | Expression '-' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } } - | Expression '*' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } } - | Expression '/' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } } - | Expression '.' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } } - | Expression '%' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } } - - | Expression IS Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } } - | Expression ISNOT Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } } - ; - - UnaryOperator: - '!' Expression { result = make_node(val) { |v| Riml::UnaryOperatorNode.new(val[0], [val[1]]) } } - | '+' Expression { result = make_node(val) { |v| Riml::UnaryOperatorNode.new(val[0], [val[1]]) } } - | '-' Expression { result = make_node(val) { |v| Riml::UnaryOperatorNode.new(val[0], [val[1]]) } } - ; - - # ['=', LHS, RHS] - Assign: - LET AssignExpression { result = make_node(val) { |v| Riml::AssignNode.new(v[1][0], v[1][1], v[1][2]) } } - | AssignExpression { result = make_node(val) { |v| Riml::AssignNode.new(v[0][0], v[0][1], v[0][2]) } } - ; - - MultiAssign: - Assign ',' Assign { result = make_node(val) { |v| Riml::MultiAssignNode.new([v[0], v[2]]) } } - | MultiAssign ',' Assign { val[0].assigns << val[2]; result = val[0] } - ; - - # ['=', AssignLHS, Expression] - AssignExpression: - AssignLHS '=' Expression { result = [val[1], val[0], val[2]] } - | AssignLHS '+=' Expression { result = [val[1], val[0], val[2]] } - | AssignLHS '-=' Expression { result = [val[1], val[0], val[2]] } - | AssignLHS '.=' Expression { result = [val[1], val[0], val[2]] } - ; - - AssignLHS: - AllVariableRetrieval { result = val[0] } - | List { result = val[0] } - | ListUnpack { result = val[0] } - | DictGet { result = val[0] } - | ListOrDictGetAssign { result = val[0] } - ; - - # retrieving the value of a variable - VariableRetrieval: - SimpleVariableRetrieval { result = val[0] } - | SPECIAL_VAR_PREFIX IDENTIFIER { result = make_node(val) { |v| Riml::GetSpecialVariableNode.new(v[0], v[1]) } } - | ScopeModifierLiteral ListOrDictGetWithBrackets { result = make_node(val) { |v| Riml::GetVariableByScopeAndDictNameNode.new(v[0], v[1]) } } - ; - - SimpleVariableRetrieval: - Scope IDENTIFIER { result = make_node(val) { |v| Riml::GetVariableNode.new(v[0], v[1]) } } - ; - - AllVariableRetrieval: - VariableRetrieval { result = val[0] } - | Scope CurlyBraceName { result = make_node(val) { |v| Riml::GetCurlyBraceNameNode.new(v[0], v[1]) } } - ; - - UnletVariable: - UNLET VariableRetrieval { result = make_node(val) { |v| Riml::UnletVariableNode.new('!', [ v[1] ]) } } - | UNLET_BANG VariableRetrieval { result = make_node(val) { |v| Riml::UnletVariableNode.new('!', [ v[1] ]) } } - | UnletVariable VariableRetrieval { result = val[0] << val[1] } - ; - - CurlyBraceName: - CurlyBraceVarPart { result = make_node(val) { |v| Riml::CurlyBraceVariable.new([ v[0] ]) } } - | IDENTIFIER CurlyBraceName { result = make_node(val) { |v| Riml::CurlyBraceVariable.new([ Riml::CurlyBracePart.new(v[0]), v[1] ]) } } - | CurlyBraceName IDENTIFIER { result = val[0] << make_node(val) { |v| Riml::CurlyBracePart.new(v[1]) } } - | CurlyBraceName CurlyBraceVarPart { result = val[0] << val[1] } - ; - - CurlyBraceVarPart: - '{' PossibleStringValue '}' { result = make_node(val) { |v| Riml::CurlyBracePart.new(v[1]) } } - | '{' PossibleStringValue CurlyBraceVarPart '}' { result = make_node(val) { |v| Riml::CurlyBracePart.new([v[1], v[2]]) } } - | '{' CurlyBraceVarPart PossibleStringValue '}' { result = make_node(val) { |v| Riml::CurlyBracePart.new([v[1], v[2]]) } } - ; - - # Method definition - # [SID, scope_modifier, name, parameters, keyword, expressions] - Def: - FunctionType SIDAndScope DefCallIdentifier DefKeywords Block END { result = make_node(val) { |v| Riml.const_get(val[0]).new('!', v[1][0], v[1][1], v[2], [], v[3], v[4]) } } - | FunctionType SIDAndScope DefCallIdentifier '(' ParamList ')' DefKeywords Block END { result = make_node(val) { |v| Riml.const_get(val[0]).new('!', v[1][0], v[1][1], v[2], v[4], v[6], v[7]) } } - | FunctionType SIDAndScope DefCallIdentifier '(' SPLAT_PARAM ')' DefKeywords Block END { result = make_node(val) { |v| Riml.const_get(val[0]).new('!', v[1][0], v[1][1], v[2], [v[4]], v[6], v[7]) } } - | FunctionType SIDAndScope DefCallIdentifier '(' ParamList ',' SPLAT_PARAM ')' DefKeywords Block END { result = make_node(val) { |v| Riml.const_get(val[0]).new('!', v[1][0], v[1][1], v[2], v[4] << v[6], v[8], v[9]) } } - ; - - FunctionType: - DEF { result = "DefNode" } - | DEF_BANG { result = "DefNode" } - | DEFM { result = "DefMethodNode" } - ; - - DefCallIdentifier: - # use '' for first argument instead of nil in order to avoid a double scope-modifier - CurlyBraceName { result = make_node(val) { |v| Riml::GetCurlyBraceNameNode.new('', v[0]) } } - | IDENTIFIER { result = val[0] } - ; - - # Example: 'range', 'dict' or 'abort' after function definition - DefKeywords: - IDENTIFIER { result = [val[0]] } - | DefKeywords IDENTIFIER { result = val[0] << val[1] } - | /* nothing */ { result = nil } - ; - - ParamList: - /* nothing */ { result = [] } - | IDENTIFIER { result = val } - | DefaultParam { result = val } - | ParamList ',' IDENTIFIER { result = val[0] << val[2] } - | ParamList ',' DefaultParam { result = val[0] << val[2] } - ; - - DefaultParam: - IDENTIFIER '=' Expression { result = make_node(val) { |v| Riml::DefaultParamNode.new(v[0], v[2]) } } - ; - - Return: - RETURN Returnable { result = make_node(val) { |v| Riml::ReturnNode.new(v[1]) } } - | RETURN Returnable IF Expression { result = make_node(val) { |v| Riml::IfNode.new(v[3], Nodes.new([ReturnNode.new(v[1])])) } } - | RETURN Returnable UNLESS Expression { result = make_node(val) { |v| Riml::UnlessNode.new(v[3], Nodes.new([ReturnNode.new(v[1])])) } } - ; - - Returnable: - /* nothing */ { result = nil } - | Expression { result = val[0] } - ; - - EndScript: - FINISH { result = make_node(val) { |_| Riml::FinishNode.new } } - ; - - # [expression, expressions] - If: - IF Expression IfBlock END { result = make_node(val) { |v| Riml::IfNode.new(v[1], v[2]) } } - | IF Expression THEN Expression END { result = make_node(val) { |v| Riml::IfNode.new(v[1], Riml::Nodes.new([v[3]])) } } - | Expression IF Expression { result = make_node(val) { |v| Riml::IfNode.new(v[2], Riml::Nodes.new([v[0]])) } } - ; - - Unless: - UNLESS Expression IfBlock END { result = make_node(val) { |v| Riml::UnlessNode.new(v[1], v[2]) } } - | UNLESS Expression THEN Expression END { result = make_node(val) { |v| Riml::UnlessNode.new(v[1], Riml::Nodes.new([v[3]])) } } - | Expression UNLESS Expression { result = make_node(val) { |v| Riml::UnlessNode.new(v[2], Riml::Nodes.new([v[0]])) } } - ; - - Ternary: - Expression '?' Expression ':' Expression { result = make_node(val) { |v| Riml::TernaryOperatorNode.new([v[0], v[2], v[4]]) } } - ; - - While: - WHILE Expression Block END { result = make_node(val) { |v| Riml::WhileNode.new(v[1], v[2]) } } - ; - - LoopKeyword: - BREAK { result = make_node(val) { |_| Riml::BreakNode.new } } - | CONTINUE { result = make_node(val) { |_| Riml::ContinueNode.new } } - ; - - Until: - UNTIL Expression Block END { result = make_node(val) { |v| Riml::UntilNode.new(v[1], v[2]) } } - ; - - For: - FOR SimpleVariableRetrieval IN Expression Block END { result = make_node(val) { |v| Riml::ForNode.new(v[1], v[3], v[4]) } } - | FOR List IN Expression Block END { result = make_node(val) { |v| Riml::ForNode.new(v[1], v[3], v[4]) } } - | FOR ListUnpack IN Expression Block END { result = make_node(val) { |v| Riml::ForNode.new(v[1], v[3], v[4]) } } - ; - - Try: - TRY Block END { result = make_node(val) { |v| Riml::TryNode.new(v[1], nil, nil) } } - | TRY Block Catch END { result = make_node(val) { |v| Riml::TryNode.new(v[1], v[2], nil) } } - | TRY Block Catch FINALLY Block END { result = make_node(val) { |v| Riml::TryNode.new(v[1], v[2], v[4]) } } - ; - - Catch: - /* nothing */ { result = nil } - | CATCH Block { result = [ make_node(val) { |v| Riml::CatchNode.new(nil, v[1]) } ] } - | CATCH Catchable Block { result = [ make_node(val) { |v| Riml::CatchNode.new(v[1], v[2]) } ] } - | Catch CATCH Block { result = val[0] << make_node(val) { |v| Riml::CatchNode.new(nil, v[2]) } } - | Catch CATCH Catchable Block { result = val[0] << make_node(val) { |v| Riml::CatchNode.new(v[2], v[3]) } } - ; - - Catchable: - Regexp { result = val[0] } - | String { result = val[0] } - ; - - # [expressions] - # expressions list could contain an ElseNode, which contains expressions - # itself - Block: - NEWLINE Statements { result = val[1] } - | NEWLINE { result = make_node(val) { |_| Riml::Nodes.new([]) } } - ; - - IfBlock: - Block { result = val[0] } - | NEWLINE Statements ElseBlock { result = val[1] << val[2] } - | NEWLINE Statements ElseifBlock { result = val[1] << val[2] } - | NEWLINE Statements ElseifBlock ElseBlock { result = val[1] << val[2] << val[3] } - ; - - ElseBlock: - ELSE NEWLINE Statements { result = make_node(val) { |v| Riml::ElseNode.new(v[2]) } } - ; - - ElseifBlock: - ELSEIF Expression NEWLINE Statements { result = make_node(val) { |v| Riml::Nodes.new([Riml::ElseifNode.new(v[1], v[3])]) } } - | ElseifBlock ELSEIF Expression NEWLINE Statements { result = val[0] << make_node(val) { |v| Riml::ElseifNode.new(v[2], v[4]) } } - ; - - ClassDefinition: - CLASS Scope IDENTIFIER Block END { result = make_node(val) { |v| Riml::ClassDefinitionNode.new(v[1], v[2], nil, v[3]) } } - | CLASS Scope IDENTIFIER '<' Scope IDENTIFIER Block END { result = make_node(val) { |v| Riml::ClassDefinitionNode.new(v[1], v[2], (v[4] || ClassDefinitionNode::DEFAULT_SCOPE_MODIFIER) + v[5], v[6]) } } - ; - - ObjectInstantiation: - NEW ObjectInstantiationCall { result = make_node(val) { |v| Riml::ObjectInstantiationNode.new(v[1]) } } - ; - - Super: - SUPER '(' ArgListWithSplat ')' { result = make_node(val) { |v| Riml::SuperNode.new(v[2], true) } } - | SUPER { result = make_node(val) { |_| Riml::SuperNode.new([], false) } } - ; - - ExLiteral: - EX_LITERAL { result = make_node(val) { |v| Riml::ExLiteralNode.new(v[0]) } } - ; -end - ----- header - require File.expand_path("../lexer", __FILE__) - require File.expand_path("../nodes", __FILE__) - require File.expand_path("../errors", __FILE__) - require File.expand_path("../ast_rewriter", __FILE__) ----- inner - # This code will be put as-is in the parser class - - attr_accessor :ast_rewriter - attr_writer :options - - # The Parser and AST_Rewriter share this same hash of options - def options - @options ||= {} - end - - def self.ast_cache - @ast_cache - end - @ast_cache = {} - - # parses tokens or code into output nodes - def parse(object, ast_rewriter = Riml::AST_Rewriter.new, filename = nil, included = false) - if (ast = self.class.ast_cache[filename]) - else - if tokens?(object) - @tokens = object - elsif code?(object) - @lexer = Riml::Lexer.new(object, filename, true) - end - - begin - ast = do_parse - rescue Racc::ParseError => e - raise unless @lexer - if (invalid_token = @lexer.prev_token_is_keyword?) - warning = "#{invalid_token.inspect} is a keyword, and cannot " \ - "be used as a variable name" - end - error_msg = e.message - error_msg << "\nWARNING: #{warning}" if warning - error = Riml::ParseError.new(error_msg, @lexer.filename, @lexer.lineno) - raise error - end - self.class.ast_cache[filename] = ast if filename - end - @ast_rewriter ||= ast_rewriter - return ast unless @ast_rewriter - @ast_rewriter.ast = ast.dup - @ast_rewriter.options ||= options - @ast_rewriter.rewrite(filename, included) - @ast_rewriter.ast - end - - # get the next token from either the list of tokens provided, or - # the lexer getting the next token - def next_token - return @tokens.shift unless @lexer - token = @lexer.next_token - if token && @lexer.parser_info - @current_parser_info = token.pop - end - token - end - - private - - def tokens?(object) - Array === object - end - - def code?(object) - String === object - end - - def make_node(racc_val) - node = yield racc_val - node.parser_info = @current_parser_info - node - end diff --git a/test/racc/assets/rrconf.y b/test/racc/assets/rrconf.y deleted file mode 100644 index baf9249a77..0000000000 --- a/test/racc/assets/rrconf.y +++ /dev/null @@ -1,14 +0,0 @@ -# 1 s/r conflict and 1 r/r conflict - -class A -rule - -target: a - -a : - | a list - -list : - | list ITEM - -end diff --git a/test/racc/assets/ruby18.y b/test/racc/assets/ruby18.y deleted file mode 100644 index eceb253298..0000000000 --- a/test/racc/assets/ruby18.y +++ /dev/null @@ -1,1943 +0,0 @@ -# Copyright (c) 2013 Peter Zotov <whitequark@whitequark.org> -# -# Parts of the source are derived from ruby_parser: -# Copyright (c) Ryan Davis, seattle.rb -# -# MIT License -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -class Parser::Ruby18 - -token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS - kTHEN kELSIF kELSE kCASE kWHEN kWHILE kUNTIL kFOR kBREAK kNEXT - kREDO kRETRY kIN kDO kDO_COND kDO_BLOCK kRETURN kYIELD kSUPER - kSELF kNIL kTRUE kFALSE kAND kOR kNOT kIF_MOD kUNLESS_MOD kWHILE_MOD - kUNTIL_MOD kRESCUE_MOD kALIAS kDEFINED klBEGIN klEND k__LINE__ - k__FILE__ tIDENTIFIER tFID tGVAR tIVAR tCONSTANT tCVAR tNTH_REF - tBACK_REF tSTRING_CONTENT tINTEGER tFLOAT tREGEXP_END tUPLUS - tUMINUS tUMINUS_NUM tPOW tCMP tEQ tEQQ tNEQ tGEQ tLEQ tANDOP - tOROP tMATCH tNMATCH tDOT tDOT2 tDOT3 tAREF tASET tLSHFT tRSHFT - tCOLON2 tCOLON3 tOP_ASGN tASSOC tLPAREN tLPAREN2 tRPAREN tLPAREN_ARG - tLBRACK tLBRACK2 tRBRACK tLBRACE tLBRACE_ARG tSTAR tSTAR2 tAMPER tAMPER2 - tTILDE tPERCENT tDIVIDE tPLUS tMINUS tLT tGT tPIPE tBANG tCARET - tLCURLY tRCURLY tBACK_REF2 tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG - tWORDS_BEG tQWORDS_BEG tSTRING_DBEG tSTRING_DVAR tSTRING_END tSTRING - tSYMBOL tREGEXP_OPT tNL tEH tCOLON tCOMMA tSPACE tSEMI - -prechigh - right tBANG tTILDE tUPLUS - right tPOW - right tUMINUS_NUM tUMINUS - left tSTAR2 tDIVIDE tPERCENT - left tPLUS tMINUS - left tLSHFT tRSHFT - left tAMPER2 - left tPIPE tCARET - left tGT tGEQ tLT tLEQ - nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH - left tANDOP - left tOROP - nonassoc tDOT2 tDOT3 - right tEH tCOLON - left kRESCUE_MOD - right tEQL tOP_ASGN - nonassoc kDEFINED - right kNOT - left kOR kAND - nonassoc kIF_MOD kUNLESS_MOD kWHILE_MOD kUNTIL_MOD - nonassoc tLBRACE_ARG - nonassoc tLOWEST -preclow - -rule - - program: compstmt - { - result = val[0] - } - - bodystmt: compstmt opt_rescue opt_else opt_ensure - { - rescue_bodies = val[1] - else_t, else_ = val[2] - ensure_t, ensure_ = val[3] - - if rescue_bodies.empty? && !else_.nil? - diagnostic :warning, :useless_else, nil, else_t - end - - result = @builder.begin_body(val[0], - rescue_bodies, - else_t, else_, - ensure_t, ensure_) - } - - compstmt: stmts opt_terms - { - result = @builder.compstmt(val[0]) - } - - stmts: # nothing - { - result = [] - } - | stmt - { - result = [ val[0] ] - } - | error stmt - { - result = [ val[1] ] - } - | stmts terms stmt - { - result = val[0] << val[2] - } - - stmt: kALIAS fitem - { - @lexer.state = :expr_fname - } - fitem - { - result = @builder.alias(val[0], val[1], val[3]) - } - | kALIAS tGVAR tGVAR - { - result = @builder.alias(val[0], - @builder.gvar(val[1]), - @builder.gvar(val[2])) - } - | kALIAS tGVAR tBACK_REF - { - result = @builder.alias(val[0], - @builder.gvar(val[1]), - @builder.back_ref(val[2])) - } - | kALIAS tGVAR tNTH_REF - { - diagnostic :error, :nth_ref_alias, nil, val[2] - } - | kUNDEF undef_list - { - result = @builder.undef_method(val[0], val[1]) - } - | stmt kIF_MOD expr_value - { - result = @builder.condition_mod(val[0], nil, - val[1], val[2]) - } - | stmt kUNLESS_MOD expr_value - { - result = @builder.condition_mod(nil, val[0], - val[1], val[2]) - } - | stmt kWHILE_MOD expr_value - { - result = @builder.loop_mod(:while, val[0], val[1], val[2]) - } - | stmt kUNTIL_MOD expr_value - { - result = @builder.loop_mod(:until, val[0], val[1], val[2]) - } - | stmt kRESCUE_MOD stmt - { - rescue_body = @builder.rescue_body(val[1], - nil, nil, nil, - nil, val[2]) - - result = @builder.begin_body(val[0], [ rescue_body ]) - } - | klBEGIN tLCURLY compstmt tRCURLY - { - if in_def? - diagnostic :error, :begin_in_method, nil, val[0] - end - - result = @builder.preexe(val[0], val[1], val[2], val[3]) - } - | klEND tLCURLY compstmt tRCURLY - { - result = @builder.postexe(val[0], val[1], val[2], val[3]) - } - | lhs tEQL command_call - { - result = @builder.assign(val[0], val[1], val[2]) - } - | mlhs tEQL command_call - { - result = @builder.multi_assign(val[0], val[1], val[2]) - } - | var_lhs tOP_ASGN command_call - { - result = @builder.op_assign(val[0], val[1], val[2]) - } - | primary_value tLBRACK2 aref_args tRBRACK tOP_ASGN command_call - { - result = @builder.op_assign( - @builder.index( - val[0], val[1], val[2], val[3]), - val[4], val[5]) - } - | primary_value tDOT tIDENTIFIER tOP_ASGN command_call - { - result = @builder.op_assign( - @builder.call_method( - val[0], val[1], val[2]), - val[3], val[4]) - } - | primary_value tDOT tCONSTANT tOP_ASGN command_call - { - result = @builder.op_assign( - @builder.call_method( - val[0], val[1], val[2]), - val[3], val[4]) - } - | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_call - { - result = @builder.op_assign( - @builder.call_method( - val[0], val[1], val[2]), - val[3], val[4]) - } - | backref tOP_ASGN command_call - { - @builder.op_assign(val[0], val[1], val[2]) - } - | lhs tEQL mrhs - { - result = @builder.assign(val[0], val[1], - @builder.array(nil, val[2], nil)) - } - | mlhs tEQL arg_value - { - result = @builder.multi_assign(val[0], val[1], val[2]) - } - | mlhs tEQL mrhs - { - result = @builder.multi_assign(val[0], val[1], - @builder.array(nil, val[2], nil)) - } - | expr - - expr: command_call - | expr kAND expr - { - result = @builder.logical_op(:and, val[0], val[1], val[2]) - } - | expr kOR expr - { - result = @builder.logical_op(:or, val[0], val[1], val[2]) - } - | kNOT expr - { - result = @builder.not_op(val[0], nil, val[1], nil) - } - | tBANG command_call - { - result = @builder.not_op(val[0], nil, val[1], nil) - } - | arg - - expr_value: expr - - command_call: command - | block_command - | kRETURN call_args - { - result = @builder.keyword_cmd(:return, val[0], - nil, val[1], nil) - } - | kBREAK call_args - { - result = @builder.keyword_cmd(:break, val[0], - nil, val[1], nil) - } - | kNEXT call_args - { - result = @builder.keyword_cmd(:next, val[0], - nil, val[1], nil) - } - - block_command: block_call - | block_call tDOT operation2 command_args - { - lparen_t, args, rparen_t = val[3] - result = @builder.call_method(val[0], val[1], val[2], - lparen_t, args, rparen_t) - } - | block_call tCOLON2 operation2 command_args - { - lparen_t, args, rparen_t = val[3] - result = @builder.call_method(val[0], val[1], val[2], - lparen_t, args, rparen_t) - } - - cmd_brace_block: tLBRACE_ARG - { - @static_env.extend_dynamic - } - opt_block_var compstmt tRCURLY - { - result = [ val[0], val[2], val[3], val[4] ] - - @static_env.unextend - } - - command: operation command_args =tLOWEST - { - lparen_t, args, rparen_t = val[1] - result = @builder.call_method(nil, nil, val[0], - lparen_t, args, rparen_t) - } - | operation command_args cmd_brace_block - { - lparen_t, args, rparen_t = val[1] - method_call = @builder.call_method(nil, nil, val[0], - lparen_t, args, rparen_t) - - begin_t, block_args, body, end_t = val[2] - result = @builder.block(method_call, - begin_t, block_args, body, end_t) - } - | primary_value tDOT operation2 command_args =tLOWEST - { - lparen_t, args, rparen_t = val[3] - result = @builder.call_method(val[0], val[1], val[2], - lparen_t, args, rparen_t) - - } - | primary_value tDOT operation2 command_args cmd_brace_block - { - lparen_t, args, rparen_t = val[3] - method_call = @builder.call_method(val[0], val[1], val[2], - lparen_t, args, rparen_t) - - begin_t, block_args, body, end_t = val[4] - result = @builder.block(method_call, - begin_t, block_args, body, end_t) - } - | primary_value tCOLON2 operation2 command_args =tLOWEST - { - lparen_t, args, rparen_t = val[3] - result = @builder.call_method(val[0], val[1], val[2], - lparen_t, args, rparen_t) - } - | primary_value tCOLON2 operation2 command_args cmd_brace_block - { - lparen_t, args, rparen_t = val[3] - method_call = @builder.call_method(val[0], val[1], val[2], - lparen_t, args, rparen_t) - - begin_t, block_args, body, end_t = val[4] - result = @builder.block(method_call, - begin_t, block_args, body, end_t) - } - | kSUPER command_args - { - lparen_t, args, rparen_t = val[1] - result = @builder.keyword_cmd(:super, val[0], - lparen_t, args, rparen_t) - } - | kYIELD command_args - { - lparen_t, args, rparen_t = val[1] - result = @builder.keyword_cmd(:yield, val[0], - lparen_t, args, rparen_t) - } - - mlhs: mlhs_basic - { - result = @builder.multi_lhs(nil, val[0], nil) - } - | tLPAREN mlhs_entry tRPAREN - { - result = @builder.begin(val[0], val[1], val[2]) - } - - mlhs_entry: mlhs_basic - { - result = @builder.multi_lhs(nil, val[0], nil) - } - | tLPAREN mlhs_entry tRPAREN - { - result = @builder.multi_lhs(val[0], val[1], val[2]) - } - - mlhs_basic: mlhs_head - { - result = val[0] - } - | mlhs_head mlhs_item - { - result = val[0] << val[1] - } - | mlhs_head tSTAR mlhs_node - { - result = val[0] << @builder.splat(val[1], val[2]) - } - | mlhs_head tSTAR - { - result = val[0] << @builder.splat(val[1]) - } - | tSTAR mlhs_node - { - result = [ @builder.splat(val[0], val[1]) ] - } - | tSTAR - { - result = [ @builder.splat(val[0]) ] - } - - mlhs_item: mlhs_node - | tLPAREN mlhs_entry tRPAREN - { - result = @builder.begin(val[0], val[1], val[2]) - } - - mlhs_head: mlhs_item tCOMMA - { - result = [ val[0] ] - } - | mlhs_head mlhs_item tCOMMA - { - result = val[0] << val[1] - } - - mlhs_node: variable - { - result = @builder.assignable(val[0]) - } - | primary_value tLBRACK2 aref_args tRBRACK - { - result = @builder.index_asgn(val[0], val[1], val[2], val[3]) - } - | primary_value tDOT tIDENTIFIER - { - result = @builder.attr_asgn(val[0], val[1], val[2]) - } - | primary_value tCOLON2 tIDENTIFIER - { - result = @builder.attr_asgn(val[0], val[1], val[2]) - } - | primary_value tDOT tCONSTANT - { - result = @builder.attr_asgn(val[0], val[1], val[2]) - } - | primary_value tCOLON2 tCONSTANT - { - result = @builder.assignable( - @builder.const_fetch(val[0], val[1], val[2])) - } - | tCOLON3 tCONSTANT - { - result = @builder.assignable( - @builder.const_global(val[0], val[1])) - } - | backref - { - result = @builder.assignable(val[0]) - } - - lhs: variable - { - result = @builder.assignable(val[0]) - } - | primary_value tLBRACK2 aref_args tRBRACK - { - result = @builder.index_asgn(val[0], val[1], val[2], val[3]) - } - | primary_value tDOT tIDENTIFIER - { - result = @builder.attr_asgn(val[0], val[1], val[2]) - } - | primary_value tCOLON2 tIDENTIFIER - { - result = @builder.attr_asgn(val[0], val[1], val[2]) - } - | primary_value tDOT tCONSTANT - { - result = @builder.attr_asgn(val[0], val[1], val[2]) - } - | primary_value tCOLON2 tCONSTANT - { - result = @builder.assignable( - @builder.const_fetch(val[0], val[1], val[2])) - } - | tCOLON3 tCONSTANT - { - result = @builder.assignable( - @builder.const_global(val[0], val[1])) - } - | backref - { - result = @builder.assignable(val[0]) - } - - cname: tIDENTIFIER - { - diagnostic :error, :module_name_const, nil, val[0] - } - | tCONSTANT - - cpath: tCOLON3 cname - { - result = @builder.const_global(val[0], val[1]) - } - | cname - { - result = @builder.const(val[0]) - } - | primary_value tCOLON2 cname - { - result = @builder.const_fetch(val[0], val[1], val[2]) - } - - fname: tIDENTIFIER | tCONSTANT | tFID - | op - | reswords - - fsym: fname - { - result = @builder.symbol(val[0]) - } - | symbol - - fitem: fsym - | dsym - - undef_list: fitem - { - result = [ val[0] ] - } - | undef_list tCOMMA - { - @lexer.state = :expr_fname - } - fitem - { - result = val[0] << val[3] - } - - op: tPIPE | tCARET | tAMPER2 | tCMP | tEQ | tEQQ - | tMATCH | tGT | tGEQ | tLT | tLEQ | tLSHFT - | tRSHFT | tPLUS | tMINUS | tSTAR2 | tSTAR | tDIVIDE - | tPERCENT | tPOW | tTILDE | tUPLUS | tUMINUS | tAREF - | tASET | tBACK_REF2 - - reswords: k__LINE__ | k__FILE__ | klBEGIN | klEND | kALIAS | kAND - | kBEGIN | kBREAK | kCASE | kCLASS | kDEF | kDEFINED - | kDO | kELSE | kELSIF | kEND | kENSURE | kFALSE - | kFOR | kIN | kMODULE | kNEXT | kNIL | kNOT - | kOR | kREDO | kRESCUE | kRETRY | kRETURN | kSELF - | kSUPER | kTHEN | kTRUE | kUNDEF | kWHEN | kYIELD - | kIF | kUNLESS | kWHILE | kUNTIL - - arg: lhs tEQL arg - { - result = @builder.assign(val[0], val[1], val[2]) - } - | lhs tEQL arg kRESCUE_MOD arg - { - rescue_body = @builder.rescue_body(val[3], - nil, nil, nil, - nil, val[4]) - - rescue_ = @builder.begin_body(val[2], [ rescue_body ]) - - result = @builder.assign(val[0], val[1], rescue_) - } - | var_lhs tOP_ASGN arg - { - result = @builder.op_assign(val[0], val[1], val[2]) - } - | primary_value tLBRACK2 aref_args tRBRACK tOP_ASGN arg - { - result = @builder.op_assign( - @builder.index( - val[0], val[1], val[2], val[3]), - val[4], val[5]) - } - | primary_value tDOT tIDENTIFIER tOP_ASGN arg - { - result = @builder.op_assign( - @builder.call_method( - val[0], val[1], val[2]), - val[3], val[4]) - } - | primary_value tDOT tCONSTANT tOP_ASGN arg - { - result = @builder.op_assign( - @builder.call_method( - val[0], val[1], val[2]), - val[3], val[4]) - } - | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg - { - result = @builder.op_assign( - @builder.call_method( - val[0], val[1], val[2]), - val[3], val[4]) - } - | primary_value tCOLON2 tCONSTANT tOP_ASGN arg - { - diagnostic :error, :dynamic_const, nil, val[2], [ val[3] ] - } - | tCOLON3 tCONSTANT tOP_ASGN arg - { - diagnostic :error, :dynamic_const, nil, val[1], [ val[2] ] - } - | backref tOP_ASGN arg - { - result = @builder.op_assign(val[0], val[1], val[2]) - } - | arg tDOT2 arg - { - result = @builder.range_inclusive(val[0], val[1], val[2]) - } - | arg tDOT3 arg - { - result = @builder.range_exclusive(val[0], val[1], val[2]) - } - | arg tPLUS arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tMINUS arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tSTAR2 arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tDIVIDE arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tPERCENT arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tPOW arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | tUMINUS_NUM tINTEGER tPOW arg - { - result = @builder.unary_op(val[0], - @builder.binary_op( - @builder.integer(val[1]), - val[2], val[3])) - } - | tUMINUS_NUM tFLOAT tPOW arg - { - result = @builder.unary_op(val[0], - @builder.binary_op( - @builder.float(val[1]), - val[2], val[3])) - } - | tUPLUS arg - { - result = @builder.unary_op(val[0], val[1]) - } - | tUMINUS arg - { - result = @builder.unary_op(val[0], val[1]) - } - | arg tPIPE arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tCARET arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tAMPER2 arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tCMP arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tGT arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tGEQ arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tLT arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tLEQ arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tEQ arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tEQQ arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tNEQ arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tMATCH arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tNMATCH arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | tBANG arg - { - result = @builder.not_op(val[0], nil, val[1], nil) - } - | tTILDE arg - { - result = @builder.unary_op(val[0], val[1]) - } - | arg tLSHFT arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tRSHFT arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tANDOP arg - { - result = @builder.logical_op(:and, val[0], val[1], val[2]) - } - | arg tOROP arg - { - result = @builder.logical_op(:or, val[0], val[1], val[2]) - } - | kDEFINED opt_nl arg - { - result = @builder.keyword_cmd(:defined?, val[0], nil, [ val[2] ], nil) - } - | arg tEH arg tCOLON arg - { - result = @builder.ternary(val[0], val[1], - val[2], val[3], val[4]) - } - | primary - - arg_value: arg - - aref_args: none - | command opt_nl - { - result = [ val[0] ] - } - | args trailer - { - result = val[0] - } - | args tCOMMA tSTAR arg opt_nl - { - result = val[0] << @builder.splat(val[2], val[3]) - } - | assocs trailer - { - result = [ @builder.associate(nil, val[0], nil) ] - } - | tSTAR arg opt_nl - { - result = [ @builder.splat(val[0], val[1]) ] - } - - paren_args: tLPAREN2 none tRPAREN - { - result = [ val[0], [], val[2] ] - } - | tLPAREN2 call_args opt_nl tRPAREN - { - result = [ val[0], val[1], val[3] ] - } - | tLPAREN2 block_call opt_nl tRPAREN - { - result = [ val[0], [ val[1] ], val[3] ] - } - | tLPAREN2 args tCOMMA block_call opt_nl tRPAREN - { - result = [ val[0], val[1] << val[3], val[5] ] - } - - opt_paren_args: # nothing - { - result = [ nil, [], nil ] - } - | paren_args - - call_args: command - { - result = [ val[0] ] - } - | args opt_block_arg - { - result = val[0].concat(val[1]) - } - | args tCOMMA tSTAR arg_value opt_block_arg - { - result = val[0].concat( - [ @builder.splat(val[2], val[3]), - *val[4] ]) - } - | assocs opt_block_arg - { - result = [ @builder.associate(nil, val[0], nil), - *val[1] ] - } - | assocs tCOMMA tSTAR arg_value opt_block_arg - { - result = [ @builder.associate(nil, val[0], nil), - @builder.splat(val[2], val[3]), - *val[4] ] - } - | args tCOMMA assocs opt_block_arg - { - result = val[0].concat( - [ @builder.associate(nil, val[2], nil), - *val[3] ]) - } - | args tCOMMA assocs tCOMMA tSTAR arg opt_block_arg - { - result = val[0].concat( - [ @builder.associate(nil, val[2], nil), - @builder.splat(val[4], val[5]), - *val[6] ]) - } - | tSTAR arg_value opt_block_arg - { - result = [ @builder.splat(val[0], val[1]), - *val[2] ] - } - | block_arg - { - result = [ val[0] ] - } - - call_args2: arg_value tCOMMA args opt_block_arg - { - result = [ val[0], *val[2].concat(val[3]) ] - } - | arg_value tCOMMA block_arg - { - result = [ val[0], val[2] ] - } - | arg_value tCOMMA tSTAR arg_value opt_block_arg - { - result = [ val[0], - @builder.splat(val[2], val[3]), - *val[4] ] - } - | arg_value tCOMMA args tCOMMA tSTAR arg_value opt_block_arg - { - result = [ val[0], - *val[2]. - push(@builder.splat(val[4], val[5])). - concat(val[6]) ] - } - | assocs opt_block_arg - { - result = [ @builder.associate(nil, val[0], nil), - *val[1] ] - } - | assocs tCOMMA tSTAR arg_value opt_block_arg - { - result = [ @builder.associate(nil, val[0], nil), - @builder.splat(val[2], val[3]), - *val[4] ] - } - | arg_value tCOMMA assocs opt_block_arg - { - result = [ val[0], - @builder.associate(nil, val[2], nil), - *val[3] ] - } - | arg_value tCOMMA args tCOMMA assocs opt_block_arg - { - result = [ val[0], - *val[2]. - push(@builder.associate(nil, val[4], nil)). - concat(val[5]) ] - } - | arg_value tCOMMA assocs tCOMMA tSTAR arg_value opt_block_arg - { - result = [ val[0], - @builder.associate(nil, val[2], nil), - @builder.splat(val[4], val[5]), - *val[6] ] - } - | arg_value tCOMMA args tCOMMA assocs tCOMMA tSTAR arg_value opt_block_arg - { - result = [ val[0], - *val[2]. - push(@builder.associate(nil, val[4], nil)). - push(@builder.splat(val[6], val[7])). - concat(val[8]) ] - } - | tSTAR arg_value opt_block_arg - { - result = [ @builder.splat(val[0], val[1]), - *val[2] ] - } - | block_arg - { - result = [ val[0] ] - } - - command_args: { - result = @lexer.cmdarg.dup - @lexer.cmdarg.push(true) - } - open_args - { - @lexer.cmdarg = val[0] - - result = val[1] - } - - open_args: call_args - { - result = [ nil, val[0], nil ] - } - | tLPAREN_ARG - { - @lexer.state = :expr_endarg - } - tRPAREN - { - result = [ val[0], [], val[2] ] - } - | tLPAREN_ARG call_args2 - { - @lexer.state = :expr_endarg - } - tRPAREN - { - result = [ val[0], val[1], val[3] ] - } - - block_arg: tAMPER arg_value - { - result = @builder.block_pass(val[0], val[1]) - } - - opt_block_arg: tCOMMA block_arg - { - result = [ val[1] ] - } - | # nothing - { - result = [] - } - - args: arg_value - { - result = [ val[0] ] - } - | args tCOMMA arg_value - { - result = val[0] << val[2] - } - - mrhs: args tCOMMA arg_value - { - result = val[0] << val[2] - } - | args tCOMMA tSTAR arg_value - { - result = val[0] << @builder.splat(val[2], val[3]) - } - | tSTAR arg_value - { - result = [ @builder.splat(val[0], val[1]) ] - } - - primary: literal - | strings - | xstring - | regexp - | words - | qwords - | var_ref - | backref - | tFID - { - result = @builder.call_method(nil, nil, val[0]) - } - | kBEGIN bodystmt kEND - { - result = @builder.begin_keyword(val[0], val[1], val[2]) - } - | tLPAREN_ARG expr - { - @lexer.state = :expr_endarg - } - opt_nl tRPAREN - { - result = @builder.begin(val[0], val[1], val[4]) - } - | tLPAREN compstmt tRPAREN - { - result = @builder.begin(val[0], val[1], val[2]) - } - | primary_value tCOLON2 tCONSTANT - { - result = @builder.const_fetch(val[0], val[1], val[2]) - } - | tCOLON3 tCONSTANT - { - result = @builder.const_global(val[0], val[1]) - } - | primary_value tLBRACK2 aref_args tRBRACK - { - result = @builder.index(val[0], val[1], val[2], val[3]) - } - | tLBRACK aref_args tRBRACK - { - result = @builder.array(val[0], val[1], val[2]) - } - | tLBRACE assoc_list tRCURLY - { - result = @builder.associate(val[0], val[1], val[2]) - } - | kRETURN - { - result = @builder.keyword_cmd(:return, val[0]) - } - | kYIELD tLPAREN2 call_args tRPAREN - { - result = @builder.keyword_cmd(:yield, val[0], val[1], val[2], val[3]) - } - | kYIELD tLPAREN2 tRPAREN - { - result = @builder.keyword_cmd(:yield, val[0], val[1], [], val[2]) - } - | kYIELD - { - result = @builder.keyword_cmd(:yield, val[0]) - } - | kDEFINED opt_nl tLPAREN2 expr tRPAREN - { - result = @builder.keyword_cmd(:defined?, val[0], - val[2], [ val[3] ], val[4]) - } - | operation brace_block - { - method_call = @builder.call_method(nil, nil, val[0]) - - begin_t, args, body, end_t = val[1] - result = @builder.block(method_call, - begin_t, args, body, end_t) - } - | method_call - | method_call brace_block - { - begin_t, args, body, end_t = val[1] - result = @builder.block(val[0], - begin_t, args, body, end_t) - } - | kIF expr_value then compstmt if_tail kEND - { - else_t, else_ = val[4] - result = @builder.condition(val[0], val[1], val[2], - val[3], else_t, - else_, val[5]) - } - | kUNLESS expr_value then compstmt opt_else kEND - { - else_t, else_ = val[4] - result = @builder.condition(val[0], val[1], val[2], - else_, else_t, - val[3], val[5]) - } - | kWHILE - { - @lexer.cond.push(true) - } - expr_value do - { - @lexer.cond.pop - } - compstmt kEND - { - result = @builder.loop(:while, val[0], val[2], val[3], - val[5], val[6]) - } - | kUNTIL - { - @lexer.cond.push(true) - } - expr_value do - { - @lexer.cond.pop - } - compstmt kEND - { - result = @builder.loop(:until, val[0], val[2], val[3], - val[5], val[6]) - } - | kCASE expr_value opt_terms case_body kEND - { - when_bodies = val[3][0..-2] - else_t, else_body = val[3][-1] - - result = @builder.case(val[0], val[1], - when_bodies, else_t, else_body, - val[4]) - } - | kCASE opt_terms case_body kEND - { - when_bodies = val[2][0..-2] - else_t, else_body = val[2][-1] - - result = @builder.case(val[0], nil, - when_bodies, else_t, else_body, - val[3]) - } - | kCASE opt_terms kELSE compstmt kEND - { - result = @builder.case(val[0], nil, - [], val[2], val[3], - val[4]) - } - | kFOR for_var kIN - { - @lexer.cond.push(true) - } - expr_value do - { - @lexer.cond.pop - } - compstmt kEND - { - result = @builder.for(val[0], val[1], - val[2], val[4], - val[5], val[7], val[8]) - } - | kCLASS cpath superclass - { - @static_env.extend_static - } - bodystmt kEND - { - if in_def? - diagnostic :error, :class_in_def, nil, val[0] - end - - lt_t, superclass = val[2] - result = @builder.def_class(val[0], val[1], - lt_t, superclass, - val[4], val[5]) - - @static_env.unextend - } - | kCLASS tLSHFT expr term - { - result = @def_level - @def_level = 0 - - @static_env.extend_static - } - bodystmt kEND - { - result = @builder.def_sclass(val[0], val[1], val[2], - val[5], val[6]) - - @static_env.unextend - - @def_level = val[4] - } - | kMODULE cpath - { - @static_env.extend_static - } - bodystmt kEND - { - if in_def? - diagnostic :error, :module_in_def, nil, val[0] - end - - result = @builder.def_module(val[0], val[1], - val[3], val[4]) - - @static_env.unextend - } - | kDEF fname - { - @def_level += 1 - @static_env.extend_static - } - f_arglist bodystmt kEND - { - result = @builder.def_method(val[0], val[1], - val[3], val[4], val[5]) - - @static_env.unextend - @def_level -= 1 - } - | kDEF singleton dot_or_colon - { - @lexer.state = :expr_fname - } - fname - { - @def_level += 1 - @static_env.extend_static - } - f_arglist bodystmt kEND - { - result = @builder.def_singleton(val[0], val[1], val[2], - val[4], val[6], val[7], val[8]) - - @static_env.unextend - @def_level -= 1 - } - | kBREAK - { - result = @builder.keyword_cmd(:break, val[0]) - } - | kNEXT - { - result = @builder.keyword_cmd(:next, val[0]) - } - | kREDO - { - result = @builder.keyword_cmd(:redo, val[0]) - } - | kRETRY - { - result = @builder.keyword_cmd(:retry, val[0]) - } - - primary_value: primary - - then: term - | tCOLON - | kTHEN - | term kTHEN - { - result = val[1] - } - - do: term - | tCOLON - | kDO_COND - - if_tail: opt_else - | kELSIF expr_value then compstmt if_tail - { - else_t, else_ = val[4] - result = [ val[0], - @builder.condition(val[0], val[1], val[2], - val[3], else_t, - else_, nil), - ] - } - - opt_else: none - | kELSE compstmt - { - result = val - } - - for_var: lhs - | mlhs - - block_par: mlhs_item - { - result = [ @builder.arg_expr(val[0]) ] - } - | block_par tCOMMA mlhs_item - { - result = val[0] << @builder.arg_expr(val[2]) - } - - block_var: block_par - | block_par tCOMMA - | block_par tCOMMA tAMPER lhs - { - result = val[0]. - push(@builder.blockarg_expr(val[2], val[3])) - } - | block_par tCOMMA tSTAR lhs tCOMMA tAMPER lhs - { - result = val[0]. - push(@builder.restarg_expr(val[2], val[3])). - push(@builder.blockarg_expr(val[5], val[6])) - } - | block_par tCOMMA tSTAR tCOMMA tAMPER lhs - { - result = val[0]. - push(@builder.restarg_expr(val[2])). - push(@builder.blockarg_expr(val[4], val[5])) - } - | block_par tCOMMA tSTAR lhs - { - result = val[0]. - push(@builder.restarg_expr(val[2], val[3])) - } - | block_par tCOMMA tSTAR - { - result = val[0]. - push(@builder.restarg_expr(val[2])) - } - | tSTAR lhs tCOMMA tAMPER lhs - { - result = [ @builder.restarg_expr(val[0], val[1]), - @builder.blockarg_expr(val[3], val[4]) ] - } - | tSTAR tCOMMA tAMPER lhs - { - result = [ @builder.restarg_expr(val[0]), - @builder.blockarg_expr(val[2], val[3]) ] - } - | tSTAR lhs - { - result = [ @builder.restarg_expr(val[0], val[1]) ] - } - | tSTAR - { - result = [ @builder.restarg_expr(val[0]) ] - } - | tAMPER lhs - { - result = [ @builder.blockarg_expr(val[0], val[1]) ] - } - ; - - opt_block_var: # nothing - { - result = @builder.args(nil, [], nil) - } - | tPIPE tPIPE - { - result = @builder.args(val[0], [], val[1]) - } - | tOROP - { - result = @builder.args(val[0], [], val[0]) - } - | tPIPE block_var tPIPE - { - result = @builder.args(val[0], val[1], val[2], false) - } - - do_block: kDO_BLOCK - { - @static_env.extend_dynamic - } - opt_block_var compstmt kEND - { - result = [ val[0], val[2], val[3], val[4] ] - - @static_env.unextend - } - - block_call: command do_block - { - begin_t, block_args, body, end_t = val[1] - result = @builder.block(val[0], - begin_t, block_args, body, end_t) - } - | block_call tDOT operation2 opt_paren_args - { - lparen_t, args, rparen_t = val[3] - result = @builder.call_method(val[0], val[1], val[2], - lparen_t, args, rparen_t) - } - | block_call tCOLON2 operation2 opt_paren_args - { - lparen_t, args, rparen_t = val[3] - result = @builder.call_method(val[0], val[1], val[2], - lparen_t, args, rparen_t) - } - - method_call: operation paren_args - { - lparen_t, args, rparen_t = val[1] - result = @builder.call_method(nil, nil, val[0], - lparen_t, args, rparen_t) - } - | primary_value tDOT operation2 opt_paren_args - { - lparen_t, args, rparen_t = val[3] - result = @builder.call_method(val[0], val[1], val[2], - lparen_t, args, rparen_t) - } - | primary_value tCOLON2 operation2 paren_args - { - lparen_t, args, rparen_t = val[3] - result = @builder.call_method(val[0], val[1], val[2], - lparen_t, args, rparen_t) - } - | primary_value tCOLON2 operation3 - { - result = @builder.call_method(val[0], val[1], val[2]) - } - | kSUPER paren_args - { - lparen_t, args, rparen_t = val[1] - result = @builder.keyword_cmd(:super, val[0], - lparen_t, args, rparen_t) - } - | kSUPER - { - result = @builder.keyword_cmd(:zsuper, val[0]) - } - - brace_block: tLCURLY - { - @static_env.extend_dynamic - } - opt_block_var compstmt tRCURLY - { - result = [ val[0], val[2], val[3], val[4] ] - - @static_env.unextend - } - | kDO - { - @static_env.extend_dynamic - } - opt_block_var compstmt kEND - { - result = [ val[0], val[2], val[3], val[4] ] - - @static_env.unextend - } - - case_body: kWHEN when_args then compstmt cases - { - result = [ @builder.when(val[0], val[1], val[2], val[3]), - *val[4] ] - } - - when_args: args - | args tCOMMA tSTAR arg_value - { - result = val[0] << @builder.splat(val[2], val[3]) - } - | tSTAR arg_value - { - result = [ @builder.splat(val[0], val[1]) ] - } - - cases: opt_else - { - result = [ val[0] ] - } - | case_body - - opt_rescue: kRESCUE exc_list exc_var then compstmt opt_rescue - { - assoc_t, exc_var = val[2] - - if val[1] - exc_list = @builder.array(nil, val[1], nil) - end - - result = [ @builder.rescue_body(val[0], - exc_list, assoc_t, exc_var, - val[3], val[4]), - *val[5] ] - } - | # nothing - { - result = [] - } - - exc_list: arg_value - { - result = [ val[0] ] - } - | mrhs - | none - - exc_var: tASSOC lhs - { - result = [ val[0], val[1] ] - } - | none - - opt_ensure: kENSURE compstmt - { - result = [ val[0], val[1] ] - } - | none - - literal: numeric - | symbol - | dsym - - strings: string - { - result = @builder.string_compose(nil, val[0], nil) - } - - string: string1 - { - result = [ val[0] ] - } - | string string1 - { - result = val[0] << val[1] - } - - string1: tSTRING_BEG string_contents tSTRING_END - { - result = @builder.string_compose(val[0], val[1], val[2]) - } - | tSTRING - { - result = @builder.string(val[0]) - } - - xstring: tXSTRING_BEG xstring_contents tSTRING_END - { - result = @builder.xstring_compose(val[0], val[1], val[2]) - } - - regexp: tREGEXP_BEG xstring_contents tSTRING_END tREGEXP_OPT - { - opts = @builder.regexp_options(val[3]) - result = @builder.regexp_compose(val[0], val[1], val[2], opts) - } - - words: tWORDS_BEG word_list tSTRING_END - { - result = @builder.words_compose(val[0], val[1], val[2]) - } - - word_list: # nothing - { - result = [] - } - | word_list word tSPACE - { - result = val[0] << @builder.word(val[1]) - } - - word: string_content - { - result = [ val[0] ] - } - | word string_content - { - result = val[0] << val[1] - } - - qwords: tQWORDS_BEG qword_list tSTRING_END - { - result = @builder.words_compose(val[0], val[1], val[2]) - } - - qword_list: # nothing - { - result = [] - } - | qword_list tSTRING_CONTENT tSPACE - { - result = val[0] << @builder.string_internal(val[1]) - } - - string_contents: # nothing - { - result = [] - } - | string_contents string_content - { - result = val[0] << val[1] - } - -xstring_contents: # nothing - { - result = [] - } - | xstring_contents string_content - { - result = val[0] << val[1] - } - - string_content: tSTRING_CONTENT - { - result = @builder.string_internal(val[0]) - } - | tSTRING_DVAR string_dvar - { - result = val[1] - } - | tSTRING_DBEG - { - @lexer.cond.push(false) - @lexer.cmdarg.push(false) - } - compstmt tRCURLY - { - @lexer.cond.lexpop - @lexer.cmdarg.lexpop - - result = @builder.begin(val[0], val[2], val[3]) - } - - string_dvar: tGVAR - { - result = @builder.gvar(val[0]) - } - | tIVAR - { - result = @builder.ivar(val[0]) - } - | tCVAR - { - result = @builder.cvar(val[0]) - } - | backref - - - symbol: tSYMBOL - { - result = @builder.symbol(val[0]) - } - - dsym: tSYMBEG xstring_contents tSTRING_END - { - result = @builder.symbol_compose(val[0], val[1], val[2]) - } - - numeric: tINTEGER - { - result = @builder.integer(val[0]) - } - | tFLOAT - { - result = @builder.float(val[0]) - } - | tUMINUS_NUM tINTEGER =tLOWEST - { - result = @builder.negate(val[0], - @builder.integer(val[1])) - } - | tUMINUS_NUM tFLOAT =tLOWEST - { - result = @builder.negate(val[0], - @builder.float(val[1])) - } - - variable: tIDENTIFIER - { - result = @builder.ident(val[0]) - } - | tIVAR - { - result = @builder.ivar(val[0]) - } - | tGVAR - { - result = @builder.gvar(val[0]) - } - | tCVAR - { - result = @builder.cvar(val[0]) - } - | tCONSTANT - { - result = @builder.const(val[0]) - } - | kNIL - { - result = @builder.nil(val[0]) - } - | kSELF - { - result = @builder.self(val[0]) - } - | kTRUE - { - result = @builder.true(val[0]) - } - | kFALSE - { - result = @builder.false(val[0]) - } - | k__FILE__ - { - result = @builder.__FILE__(val[0]) - } - | k__LINE__ - { - result = @builder.__LINE__(val[0]) - } - - var_ref: variable - { - result = @builder.accessible(val[0]) - } - - var_lhs: variable - { - result = @builder.assignable(val[0]) - } - - backref: tNTH_REF - { - result = @builder.nth_ref(val[0]) - } - | tBACK_REF - { - result = @builder.back_ref(val[0]) - } - - superclass: term - { - result = nil - } - | tLT expr_value term - { - result = [ val[0], val[1] ] - } - | error term - { - yyerrok - result = nil - } - - f_arglist: tLPAREN2 f_args opt_nl tRPAREN - { - result = @builder.args(val[0], val[1], val[3]) - - @lexer.state = :expr_beg - } - | f_args term - { - result = @builder.args(nil, val[0], nil) - } - - f_args: f_arg tCOMMA f_optarg tCOMMA f_rest_arg opt_f_block_arg - { - result = val[0]. - concat(val[2]). - concat(val[4]). - concat(val[5]) - } - | f_arg tCOMMA f_optarg opt_f_block_arg - { - result = val[0]. - concat(val[2]). - concat(val[3]) - } - | f_arg tCOMMA f_rest_arg opt_f_block_arg - { - result = val[0]. - concat(val[2]). - concat(val[3]) - } - | f_arg opt_f_block_arg - { - result = val[0]. - concat(val[1]) - } - | f_optarg tCOMMA f_rest_arg opt_f_block_arg - { - result = val[0]. - concat(val[2]). - concat(val[3]) - } - | f_optarg opt_f_block_arg - { - result = val[0]. - concat(val[1]) - } - | f_rest_arg opt_f_block_arg - { - result = val[0]. - concat(val[1]) - } - | f_block_arg - { - result = [ val[0] ] - } - | # nothing - { - result = [] - } - - f_norm_arg: tCONSTANT - { - diagnostic :error, :argument_const, nil, val[0] - } - | tIVAR - { - diagnostic :error, :argument_ivar, nil, val[0] - } - | tGVAR - { - diagnostic :error, :argument_gvar, nil, val[0] - } - | tCVAR - { - diagnostic :error, :argument_cvar, nil, val[0] - } - | tIDENTIFIER - { - @static_env.declare val[0][0] - - result = @builder.arg(val[0]) - } - - f_arg: f_norm_arg - { - result = [ val[0] ] - } - | f_arg tCOMMA f_norm_arg - { - result = val[0] << val[2] - } - - f_opt: tIDENTIFIER tEQL arg_value - { - @static_env.declare val[0][0] - - result = @builder.optarg(val[0], val[1], val[2]) - } - - f_optarg: f_opt - { - result = [ val[0] ] - } - | f_optarg tCOMMA f_opt - { - result = val[0] << val[2] - } - - restarg_mark: tSTAR2 | tSTAR - - f_rest_arg: restarg_mark tIDENTIFIER - { - @static_env.declare val[1][0] - - result = [ @builder.restarg(val[0], val[1]) ] - } - | restarg_mark - { - result = [ @builder.restarg(val[0]) ] - } - - blkarg_mark: tAMPER2 | tAMPER - - f_block_arg: blkarg_mark tIDENTIFIER - { - @static_env.declare val[1][0] - - result = @builder.blockarg(val[0], val[1]) - } - - opt_f_block_arg: tCOMMA f_block_arg - { - result = [ val[1] ] - } - | # nothing - { - result = [] - } - - singleton: var_ref - | tLPAREN2 expr opt_nl tRPAREN - { - result = val[1] - } - - assoc_list: # nothing - { - result = [] - } - | assocs trailer - { - result = val[0] - } - | args trailer - { - result = @builder.pair_list_18(val[0]) - } - - assocs: assoc - { - result = [ val[0] ] - } - | assocs tCOMMA assoc - { - result = val[0] << val[2] - } - - assoc: arg_value tASSOC arg_value - { - result = @builder.pair(val[0], val[1], val[2]) - } - - operation: tIDENTIFIER | tCONSTANT | tFID - operation2: tIDENTIFIER | tCONSTANT | tFID | op - operation3: tIDENTIFIER | tFID | op - dot_or_colon: tDOT | tCOLON2 - opt_terms: | terms - opt_nl: | tNL - trailer: | tNL | tCOMMA - - term: tSEMI - { - yyerrok - } - | tNL - - terms: term - | terms tSEMI - - none: # nothing - { - result = nil - } - -end - ----- header - -require 'parser' - ----- inner - - def version - 18 - end - - def default_encoding - Encoding::BINARY if defined? Encoding - end diff --git a/test/racc/assets/ruby19.y b/test/racc/assets/ruby19.y deleted file mode 100644 index b405c952e7..0000000000 --- a/test/racc/assets/ruby19.y +++ /dev/null @@ -1,2174 +0,0 @@ -# Copyright (c) 2013 Peter Zotov <whitequark@whitequark.org> -# -# Parts of the source are derived from ruby_parser: -# Copyright (c) Ryan Davis, seattle.rb -# -# MIT License -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -class Parser::Ruby19 - -token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS - kTHEN kELSIF kELSE kCASE kWHEN kWHILE kUNTIL kFOR kBREAK kNEXT - kREDO kRETRY kIN kDO kDO_COND kDO_BLOCK kDO_LAMBDA kRETURN kYIELD kSUPER - kSELF kNIL kTRUE kFALSE kAND kOR kNOT kIF_MOD kUNLESS_MOD kWHILE_MOD - kUNTIL_MOD kRESCUE_MOD kALIAS kDEFINED klBEGIN klEND k__LINE__ - k__FILE__ k__ENCODING__ tIDENTIFIER tFID tGVAR tIVAR tCONSTANT - tLABEL tCVAR tNTH_REF tBACK_REF tSTRING_CONTENT tINTEGER tFLOAT - tREGEXP_END tUPLUS tUMINUS tUMINUS_NUM tPOW tCMP tEQ tEQQ tNEQ - tGEQ tLEQ tANDOP tOROP tMATCH tNMATCH tDOT tDOT2 tDOT3 tAREF - tASET tLSHFT tRSHFT tCOLON2 tCOLON3 tOP_ASGN tASSOC tLPAREN - tLPAREN2 tRPAREN tLPAREN_ARG tLBRACK tLBRACK2 tRBRACK tLBRACE - tLBRACE_ARG tSTAR tSTAR2 tAMPER tAMPER2 tTILDE tPERCENT tDIVIDE - tPLUS tMINUS tLT tGT tPIPE tBANG tCARET tLCURLY tRCURLY - tBACK_REF2 tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG tREGEXP_OPT - tWORDS_BEG tQWORDS_BEG tSTRING_DBEG tSTRING_DVAR tSTRING_END - tSTRING tSYMBOL tNL tEH tCOLON tCOMMA tSPACE tSEMI tLAMBDA tLAMBEG - tCHARACTER - -prechigh - right tBANG tTILDE tUPLUS - right tPOW - right tUMINUS_NUM tUMINUS - left tSTAR2 tDIVIDE tPERCENT - left tPLUS tMINUS - left tLSHFT tRSHFT - left tAMPER2 - left tPIPE tCARET - left tGT tGEQ tLT tLEQ - nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH - left tANDOP - left tOROP - nonassoc tDOT2 tDOT3 - right tEH tCOLON - left kRESCUE_MOD - right tEQL tOP_ASGN - nonassoc kDEFINED - right kNOT - left kOR kAND - nonassoc kIF_MOD kUNLESS_MOD kWHILE_MOD kUNTIL_MOD - nonassoc tLBRACE_ARG - nonassoc tLOWEST -preclow - -rule - - program: top_compstmt - - top_compstmt: top_stmts opt_terms - { - result = @builder.compstmt(val[0]) - } - - top_stmts: # nothing - { - result = [] - } - | top_stmt - { - result = [ val[0] ] - } - | top_stmts terms top_stmt - { - result = val[0] << val[2] - } - | error top_stmt - { - result = [ val[1] ] - } - - top_stmt: stmt - | klBEGIN tLCURLY top_compstmt tRCURLY - { - result = @builder.preexe(val[0], val[1], val[2], val[3]) - } - - bodystmt: compstmt opt_rescue opt_else opt_ensure - { - rescue_bodies = val[1] - else_t, else_ = val[2] - ensure_t, ensure_ = val[3] - - if rescue_bodies.empty? && !else_.nil? - diagnostic :warning, :useless_else, nil, else_t - end - - result = @builder.begin_body(val[0], - rescue_bodies, - else_t, else_, - ensure_t, ensure_) - } - - compstmt: stmts opt_terms - { - result = @builder.compstmt(val[0]) - } - - stmts: # nothing - { - result = [] - } - | stmt - { - result = [ val[0] ] - } - | stmts terms stmt - { - result = val[0] << val[2] - } - | error stmt - { - result = [ val[1] ] - } - - stmt: kALIAS fitem - { - @lexer.state = :expr_fname - } - fitem - { - result = @builder.alias(val[0], val[1], val[3]) - } - | kALIAS tGVAR tGVAR - { - result = @builder.alias(val[0], - @builder.gvar(val[1]), - @builder.gvar(val[2])) - } - | kALIAS tGVAR tBACK_REF - { - result = @builder.alias(val[0], - @builder.gvar(val[1]), - @builder.back_ref(val[2])) - } - | kALIAS tGVAR tNTH_REF - { - diagnostic :error, :nth_ref_alias, nil, val[2] - } - | kUNDEF undef_list - { - result = @builder.undef_method(val[0], val[1]) - } - | stmt kIF_MOD expr_value - { - result = @builder.condition_mod(val[0], nil, - val[1], val[2]) - } - | stmt kUNLESS_MOD expr_value - { - result = @builder.condition_mod(nil, val[0], - val[1], val[2]) - } - | stmt kWHILE_MOD expr_value - { - result = @builder.loop_mod(:while, val[0], val[1], val[2]) - } - | stmt kUNTIL_MOD expr_value - { - result = @builder.loop_mod(:until, val[0], val[1], val[2]) - } - | stmt kRESCUE_MOD stmt - { - rescue_body = @builder.rescue_body(val[1], - nil, nil, nil, - nil, val[2]) - - result = @builder.begin_body(val[0], [ rescue_body ]) - } - | klEND tLCURLY compstmt tRCURLY - { - result = @builder.postexe(val[0], val[1], val[2], val[3]) - } - | command_asgn - | mlhs tEQL command_call - { - result = @builder.multi_assign(val[0], val[1], val[2]) - } - | var_lhs tOP_ASGN command_call - { - result = @builder.op_assign(val[0], val[1], val[2]) - } - | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN command_call - { - result = @builder.op_assign( - @builder.index( - val[0], val[1], val[2], val[3]), - val[4], val[5]) - } - | primary_value tDOT tIDENTIFIER tOP_ASGN command_call - { - result = @builder.op_assign( - @builder.call_method( - val[0], val[1], val[2]), - val[3], val[4]) - } - | primary_value tDOT tCONSTANT tOP_ASGN command_call - { - result = @builder.op_assign( - @builder.call_method( - val[0], val[1], val[2]), - val[3], val[4]) - } - | primary_value tCOLON2 tCONSTANT tOP_ASGN command_call - { - result = @builder.op_assign( - @builder.call_method( - val[0], val[1], val[2]), - val[3], val[4]) - } - | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_call - { - result = @builder.op_assign( - @builder.call_method( - val[0], val[1], val[2]), - val[3], val[4]) - } - | backref tOP_ASGN command_call - { - @builder.op_assign(val[0], val[1], val[2]) - } - | lhs tEQL mrhs - { - result = @builder.assign(val[0], val[1], - @builder.array(nil, val[2], nil)) - } - | mlhs tEQL arg_value - { - result = @builder.multi_assign(val[0], val[1], val[2]) - } - | mlhs tEQL mrhs - { - result = @builder.multi_assign(val[0], val[1], - @builder.array(nil, val[2], nil)) - } - | expr - - command_asgn: lhs tEQL command_call - { - result = @builder.assign(val[0], val[1], val[2]) - } - | lhs tEQL command_asgn - { - result = @builder.assign(val[0], val[1], val[2]) - } - - expr: command_call - | expr kAND expr - { - result = @builder.logical_op(:and, val[0], val[1], val[2]) - } - | expr kOR expr - { - result = @builder.logical_op(:or, val[0], val[1], val[2]) - } - | kNOT opt_nl expr - { - result = @builder.not_op(val[0], nil, val[2], nil) - } - | tBANG command_call - { - result = @builder.not_op(val[0], nil, val[1], nil) - } - | arg - - expr_value: expr - - command_call: command - | block_command - - block_command: block_call - | block_call tDOT operation2 command_args - { - result = @builder.call_method(val[0], val[1], val[2], - nil, val[3], nil) - } - | block_call tCOLON2 operation2 command_args - { - result = @builder.call_method(val[0], val[1], val[2], - nil, val[3], nil) - } - - cmd_brace_block: tLBRACE_ARG - { - @static_env.extend_dynamic - } - opt_block_param compstmt tRCURLY - { - result = [ val[0], val[2], val[3], val[4] ] - - @static_env.unextend - } - - command: operation command_args =tLOWEST - { - result = @builder.call_method(nil, nil, val[0], - nil, val[1], nil) - } - | operation command_args cmd_brace_block - { - method_call = @builder.call_method(nil, nil, val[0], - nil, val[1], nil) - - begin_t, args, body, end_t = val[2] - result = @builder.block(method_call, - begin_t, args, body, end_t) - } - | primary_value tDOT operation2 command_args =tLOWEST - { - result = @builder.call_method(val[0], val[1], val[2], - nil, val[3], nil) - } - | primary_value tDOT operation2 command_args cmd_brace_block - { - method_call = @builder.call_method(val[0], val[1], val[2], - nil, val[3], nil) - - begin_t, args, body, end_t = val[4] - result = @builder.block(method_call, - begin_t, args, body, end_t) - } - | primary_value tCOLON2 operation2 command_args =tLOWEST - { - result = @builder.call_method(val[0], val[1], val[2], - nil, val[3], nil) - } - | primary_value tCOLON2 operation2 command_args cmd_brace_block - { - method_call = @builder.call_method(val[0], val[1], val[2], - nil, val[3], nil) - - begin_t, args, body, end_t = val[4] - result = @builder.block(method_call, - begin_t, args, body, end_t) - } - | kSUPER command_args - { - result = @builder.keyword_cmd(:super, val[0], - nil, val[1], nil) - } - | kYIELD command_args - { - result = @builder.keyword_cmd(:yield, val[0], - nil, val[1], nil) - } - | kRETURN call_args - { - result = @builder.keyword_cmd(:return, val[0], - nil, val[1], nil) - } - | kBREAK call_args - { - result = @builder.keyword_cmd(:break, val[0], - nil, val[1], nil) - } - | kNEXT call_args - { - result = @builder.keyword_cmd(:next, val[0], - nil, val[1], nil) - } - - mlhs: mlhs_basic - { - result = @builder.multi_lhs(nil, val[0], nil) - } - | tLPAREN mlhs_inner rparen - { - result = @builder.begin(val[0], val[1], val[2]) - } - - mlhs_inner: mlhs_basic - { - result = @builder.multi_lhs(nil, val[0], nil) - } - | tLPAREN mlhs_inner rparen - { - result = @builder.multi_lhs(val[0], val[1], val[2]) - } - - mlhs_basic: mlhs_head - | mlhs_head mlhs_item - { - result = val[0]. - push(val[1]) - } - | mlhs_head tSTAR mlhs_node - { - result = val[0]. - push(@builder.splat(val[1], val[2])) - } - | mlhs_head tSTAR mlhs_node tCOMMA mlhs_post - { - result = val[0]. - push(@builder.splat(val[1], val[2])). - concat(val[4]) - } - | mlhs_head tSTAR - { - result = val[0]. - push(@builder.splat(val[1])) - } - | mlhs_head tSTAR tCOMMA mlhs_post - { - result = val[0]. - push(@builder.splat(val[1])). - concat(val[3]) - } - | tSTAR mlhs_node - { - result = [ @builder.splat(val[0], val[1]) ] - } - | tSTAR mlhs_node tCOMMA mlhs_post - { - result = [ @builder.splat(val[0], val[1]), - *val[3] ] - } - | tSTAR - { - result = [ @builder.splat(val[0]) ] - } - | tSTAR tCOMMA mlhs_post - { - result = [ @builder.splat(val[0]), - *val[2] ] - } - - mlhs_item: mlhs_node - | tLPAREN mlhs_inner rparen - { - result = @builder.begin(val[0], val[1], val[2]) - } - - mlhs_head: mlhs_item tCOMMA - { - result = [ val[0] ] - } - | mlhs_head mlhs_item tCOMMA - { - result = val[0] << val[1] - } - - mlhs_post: mlhs_item - { - result = [ val[0] ] - } - | mlhs_post tCOMMA mlhs_item - { - result = val[0] << val[2] - } - - mlhs_node: user_variable - { - result = @builder.assignable(val[0]) - } - | keyword_variable - { - result = @builder.assignable(val[0]) - } - | primary_value tLBRACK2 opt_call_args rbracket - { - result = @builder.index_asgn(val[0], val[1], val[2], val[3]) - } - | primary_value tDOT tIDENTIFIER - { - result = @builder.attr_asgn(val[0], val[1], val[2]) - } - | primary_value tCOLON2 tIDENTIFIER - { - result = @builder.attr_asgn(val[0], val[1], val[2]) - } - | primary_value tDOT tCONSTANT - { - result = @builder.attr_asgn(val[0], val[1], val[2]) - } - | primary_value tCOLON2 tCONSTANT - { - result = @builder.assignable( - @builder.const_fetch(val[0], val[1], val[2])) - } - | tCOLON3 tCONSTANT - { - result = @builder.assignable( - @builder.const_global(val[0], val[1])) - } - | backref - { - result = @builder.assignable(val[0]) - } - - lhs: user_variable - { - result = @builder.assignable(val[0]) - } - | keyword_variable - { - result = @builder.assignable(val[0]) - } - | primary_value tLBRACK2 opt_call_args rbracket - { - result = @builder.index_asgn(val[0], val[1], val[2], val[3]) - } - | primary_value tDOT tIDENTIFIER - { - result = @builder.attr_asgn(val[0], val[1], val[2]) - } - | primary_value tCOLON2 tIDENTIFIER - { - result = @builder.attr_asgn(val[0], val[1], val[2]) - } - | primary_value tDOT tCONSTANT - { - result = @builder.attr_asgn(val[0], val[1], val[2]) - } - | primary_value tCOLON2 tCONSTANT - { - result = @builder.assignable( - @builder.const_fetch(val[0], val[1], val[2])) - } - | tCOLON3 tCONSTANT - { - result = @builder.assignable( - @builder.const_global(val[0], val[1])) - } - | backref - { - result = @builder.assignable(val[0]) - } - - cname: tIDENTIFIER - { - diagnostic :error, :module_name_const, nil, val[0] - } - | tCONSTANT - - cpath: tCOLON3 cname - { - result = @builder.const_global(val[0], val[1]) - } - | cname - { - result = @builder.const(val[0]) - } - | primary_value tCOLON2 cname - { - result = @builder.const_fetch(val[0], val[1], val[2]) - } - - fname: tIDENTIFIER | tCONSTANT | tFID - | op - | reswords - - fsym: fname - { - result = @builder.symbol(val[0]) - } - | symbol - - fitem: fsym - | dsym - - undef_list: fitem - { - result = [ val[0] ] - } - | undef_list tCOMMA - { - @lexer.state = :expr_fname - } - fitem - { - result = val[0] << val[3] - } - - op: tPIPE | tCARET | tAMPER2 | tCMP | tEQ | tEQQ - | tMATCH | tNMATCH | tGT | tGEQ | tLT | tLEQ - | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2 - | tSTAR | tDIVIDE | tPERCENT | tPOW | tBANG | tTILDE - | tUPLUS | tUMINUS | tAREF | tASET | tBACK_REF2 - - reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND - | kALIAS | kAND | kBEGIN | kBREAK | kCASE - | kCLASS | kDEF | kDEFINED | kDO | kELSE - | kELSIF | kEND | kENSURE | kFALSE | kFOR - | kIN | kMODULE | kNEXT | kNIL | kNOT - | kOR | kREDO | kRESCUE | kRETRY | kRETURN - | kSELF | kSUPER | kTHEN | kTRUE | kUNDEF - | kWHEN | kYIELD | kIF | kUNLESS | kWHILE - | kUNTIL - - arg: lhs tEQL arg - { - result = @builder.assign(val[0], val[1], val[2]) - } - | lhs tEQL arg kRESCUE_MOD arg - { - rescue_body = @builder.rescue_body(val[3], - nil, nil, nil, - nil, val[4]) - - rescue_ = @builder.begin_body(val[2], [ rescue_body ]) - - result = @builder.assign(val[0], val[1], rescue_) - } - | var_lhs tOP_ASGN arg - { - result = @builder.op_assign(val[0], val[1], val[2]) - } - | var_lhs tOP_ASGN arg kRESCUE_MOD arg - { - rescue_body = @builder.rescue_body(val[3], - nil, nil, nil, - nil, val[4]) - - rescue_ = @builder.begin_body(val[2], [ rescue_body ]) - - result = @builder.op_assign(val[0], val[1], rescue_) - } - | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN arg - { - result = @builder.op_assign( - @builder.index( - val[0], val[1], val[2], val[3]), - val[4], val[5]) - } - | primary_value tDOT tIDENTIFIER tOP_ASGN arg - { - result = @builder.op_assign( - @builder.call_method( - val[0], val[1], val[2]), - val[3], val[4]) - } - | primary_value tDOT tCONSTANT tOP_ASGN arg - { - result = @builder.op_assign( - @builder.call_method( - val[0], val[1], val[2]), - val[3], val[4]) - } - | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg - { - result = @builder.op_assign( - @builder.call_method( - val[0], val[1], val[2]), - val[3], val[4]) - } - | primary_value tCOLON2 tCONSTANT tOP_ASGN arg - { - diagnostic :error, :dynamic_const, nil, val[2], [ val[3] ] - } - | tCOLON3 tCONSTANT tOP_ASGN arg - { - diagnostic :error, :dynamic_const, nil, val[1], [ val[2] ] - } - | backref tOP_ASGN arg - { - result = @builder.op_assign(val[0], val[1], val[2]) - } - | arg tDOT2 arg - { - result = @builder.range_inclusive(val[0], val[1], val[2]) - } - | arg tDOT3 arg - { - result = @builder.range_exclusive(val[0], val[1], val[2]) - } - | arg tPLUS arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tMINUS arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tSTAR2 arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tDIVIDE arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tPERCENT arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tPOW arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | tUMINUS_NUM tINTEGER tPOW arg - { - result = @builder.unary_op(val[0], - @builder.binary_op( - @builder.integer(val[1]), - val[2], val[3])) - } - | tUMINUS_NUM tFLOAT tPOW arg - { - result = @builder.unary_op(val[0], - @builder.binary_op( - @builder.float(val[1]), - val[2], val[3])) - } - | tUPLUS arg - { - result = @builder.unary_op(val[0], val[1]) - } - | tUMINUS arg - { - result = @builder.unary_op(val[0], val[1]) - } - | arg tPIPE arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tCARET arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tAMPER2 arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tCMP arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tGT arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tGEQ arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tLT arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tLEQ arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tEQ arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tEQQ arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tNEQ arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tMATCH arg - { - result = @builder.match_op(val[0], val[1], val[2]) - } - | arg tNMATCH arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | tBANG arg - { - result = @builder.not_op(val[0], nil, val[1], nil) - } - | tTILDE arg - { - result = @builder.unary_op(val[0], val[1]) - } - | arg tLSHFT arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tRSHFT arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tANDOP arg - { - result = @builder.logical_op(:and, val[0], val[1], val[2]) - } - | arg tOROP arg - { - result = @builder.logical_op(:or, val[0], val[1], val[2]) - } - | kDEFINED opt_nl arg - { - result = @builder.keyword_cmd(:defined?, val[0], nil, [ val[2] ], nil) - } - - | arg tEH arg opt_nl tCOLON arg - { - result = @builder.ternary(val[0], val[1], - val[2], val[4], val[5]) - } - | primary - - arg_value: arg - - aref_args: none - | args trailer - | args tCOMMA assocs trailer - { - result = val[0] << @builder.associate(nil, val[2], nil) - } - | assocs trailer - { - result = [ @builder.associate(nil, val[0], nil) ] - } - - paren_args: tLPAREN2 opt_call_args rparen - { - result = val - } - - opt_paren_args: # nothing - { - result = [ nil, [], nil ] - } - | paren_args - - opt_call_args: # nothing - { - result = [] - } - | call_args - | args tCOMMA - | args tCOMMA assocs tCOMMA - { - result = val[0] << @builder.associate(nil, val[2], nil) - } - | assocs tCOMMA - { - result = [ @builder.associate(nil, val[0], nil) ] - } - - call_args: command - { - result = [ val[0] ] - } - | args opt_block_arg - { - result = val[0].concat(val[1]) - } - | assocs opt_block_arg - { - result = [ @builder.associate(nil, val[0], nil) ] - result.concat(val[1]) - } - | args tCOMMA assocs opt_block_arg - { - assocs = @builder.associate(nil, val[2], nil) - result = val[0] << assocs - result.concat(val[3]) - } - | block_arg - { - result = [ val[0] ] - } - - command_args: { - result = @lexer.cmdarg.dup - @lexer.cmdarg.push(true) - } - call_args - { - @lexer.cmdarg = val[0] - - result = val[1] - } - - block_arg: tAMPER arg_value - { - result = @builder.block_pass(val[0], val[1]) - } - - opt_block_arg: tCOMMA block_arg - { - result = [ val[1] ] - } - | # nothing - { - result = [] - } - - args: arg_value - { - result = [ val[0] ] - } - | tSTAR arg_value - { - result = [ @builder.splat(val[0], val[1]) ] - } - | args tCOMMA arg_value - { - result = val[0] << val[2] - } - | args tCOMMA tSTAR arg_value - { - result = val[0] << @builder.splat(val[2], val[3]) - } - - mrhs: args tCOMMA arg_value - { - result = val[0] << val[2] - } - | args tCOMMA tSTAR arg_value - { - result = val[0] << @builder.splat(val[2], val[3]) - } - | tSTAR arg_value - { - result = [ @builder.splat(val[0], val[1]) ] - } - - primary: literal - | strings - | xstring - | regexp - | words - | qwords - | var_ref - | backref - | tFID - { - result = @builder.call_method(nil, nil, val[0]) - } - | kBEGIN bodystmt kEND - { - result = @builder.begin_keyword(val[0], val[1], val[2]) - } - | tLPAREN_ARG - { - result = @lexer.cmdarg.dup - @lexer.cmdarg.clear - } - expr - { - @lexer.state = :expr_endarg - } - opt_nl tRPAREN - { - @lexer.cmdarg = val[1] - - result = @builder.begin(val[0], val[2], val[5]) - } - | tLPAREN compstmt tRPAREN - { - result = @builder.begin(val[0], val[1], val[2]) - } - | primary_value tCOLON2 tCONSTANT - { - result = @builder.const_fetch(val[0], val[1], val[2]) - } - | tCOLON3 tCONSTANT - { - result = @builder.const_global(val[0], val[1]) - } - | tLBRACK aref_args tRBRACK - { - result = @builder.array(val[0], val[1], val[2]) - } - | tLBRACE assoc_list tRCURLY - { - result = @builder.associate(val[0], val[1], val[2]) - } - | kRETURN - { - result = @builder.keyword_cmd(:return, val[0]) - } - | kYIELD tLPAREN2 call_args rparen - { - result = @builder.keyword_cmd(:yield, val[0], val[1], val[2], val[3]) - } - | kYIELD tLPAREN2 rparen - { - result = @builder.keyword_cmd(:yield, val[0], val[1], [], val[2]) - } - | kYIELD - { - result = @builder.keyword_cmd(:yield, val[0]) - } - | kDEFINED opt_nl tLPAREN2 expr rparen - { - result = @builder.keyword_cmd(:defined?, val[0], - val[2], [ val[3] ], val[4]) - } - | kNOT tLPAREN2 expr rparen - { - result = @builder.not_op(val[0], val[1], val[2], val[3]) - } - | kNOT tLPAREN2 rparen - { - result = @builder.not_op(val[0], val[1], nil, val[2]) - } - | operation brace_block - { - method_call = @builder.call_method(nil, nil, val[0]) - - begin_t, args, body, end_t = val[1] - result = @builder.block(method_call, - begin_t, args, body, end_t) - } - | method_call - | method_call brace_block - { - begin_t, args, body, end_t = val[1] - result = @builder.block(val[0], - begin_t, args, body, end_t) - } - | tLAMBDA lambda - { - lambda_call = @builder.call_lambda(val[0]) - - args, (begin_t, body, end_t) = val[1] - result = @builder.block(lambda_call, - begin_t, args, body, end_t) - } - | kIF expr_value then compstmt if_tail kEND - { - else_t, else_ = val[4] - result = @builder.condition(val[0], val[1], val[2], - val[3], else_t, - else_, val[5]) - } - | kUNLESS expr_value then compstmt opt_else kEND - { - else_t, else_ = val[4] - result = @builder.condition(val[0], val[1], val[2], - else_, else_t, - val[3], val[5]) - } - | kWHILE - { - @lexer.cond.push(true) - } - expr_value do - { - @lexer.cond.pop - } - compstmt kEND - { - result = @builder.loop(:while, val[0], val[2], val[3], - val[5], val[6]) - } - | kUNTIL - { - @lexer.cond.push(true) - } - expr_value do - { - @lexer.cond.pop - } - compstmt kEND - { - result = @builder.loop(:until, val[0], val[2], val[3], - val[5], val[6]) - } - | kCASE expr_value opt_terms case_body kEND - { - *when_bodies, (else_t, else_body) = *val[3] - - result = @builder.case(val[0], val[1], - when_bodies, else_t, else_body, - val[4]) - } - | kCASE opt_terms case_body kEND - { - *when_bodies, (else_t, else_body) = *val[2] - - result = @builder.case(val[0], nil, - when_bodies, else_t, else_body, - val[3]) - } - | kFOR for_var kIN - { - @lexer.cond.push(true) - } - expr_value do - { - @lexer.cond.pop - } - compstmt kEND - { - result = @builder.for(val[0], val[1], - val[2], val[4], - val[5], val[7], val[8]) - } - | kCLASS cpath superclass - { - @static_env.extend_static - @lexer.push_cmdarg - } - bodystmt kEND - { - if in_def? - diagnostic :error, :class_in_def, nil, val[0] - end - - lt_t, superclass = val[2] - result = @builder.def_class(val[0], val[1], - lt_t, superclass, - val[4], val[5]) - - @lexer.pop_cmdarg - @static_env.unextend - } - | kCLASS tLSHFT expr term - { - result = @def_level - @def_level = 0 - - @static_env.extend_static - @lexer.push_cmdarg - } - bodystmt kEND - { - result = @builder.def_sclass(val[0], val[1], val[2], - val[5], val[6]) - - @lexer.pop_cmdarg - @static_env.unextend - - @def_level = val[4] - } - | kMODULE cpath - { - @static_env.extend_static - @lexer.push_cmdarg - } - bodystmt kEND - { - if in_def? - diagnostic :error, :module_in_def, nil, val[0] - end - - result = @builder.def_module(val[0], val[1], - val[3], val[4]) - - @lexer.pop_cmdarg - @static_env.unextend - } - | kDEF fname - { - @def_level += 1 - @static_env.extend_static - @lexer.push_cmdarg - } - f_arglist bodystmt kEND - { - result = @builder.def_method(val[0], val[1], - val[3], val[4], val[5]) - - @lexer.pop_cmdarg - @static_env.unextend - @def_level -= 1 - } - | kDEF singleton dot_or_colon - { - @lexer.state = :expr_fname - } - fname - { - @def_level += 1 - @static_env.extend_static - @lexer.push_cmdarg - } - f_arglist bodystmt kEND - { - result = @builder.def_singleton(val[0], val[1], val[2], - val[4], val[6], val[7], val[8]) - - @lexer.pop_cmdarg - @static_env.unextend - @def_level -= 1 - } - | kBREAK - { - result = @builder.keyword_cmd(:break, val[0]) - } - | kNEXT - { - result = @builder.keyword_cmd(:next, val[0]) - } - | kREDO - { - result = @builder.keyword_cmd(:redo, val[0]) - } - | kRETRY - { - result = @builder.keyword_cmd(:retry, val[0]) - } - - primary_value: primary - - then: term - | kTHEN - | term kTHEN - { - result = val[1] - } - - do: term - | kDO_COND - - if_tail: opt_else - | kELSIF expr_value then compstmt if_tail - { - else_t, else_ = val[4] - result = [ val[0], - @builder.condition(val[0], val[1], val[2], - val[3], else_t, - else_, nil), - ] - } - - opt_else: none - | kELSE compstmt - { - result = val - } - - for_var: lhs - | mlhs - - f_marg: f_norm_arg - { - @static_env.declare val[0][0] - - result = @builder.arg(val[0]) - } - | tLPAREN f_margs rparen - { - result = @builder.multi_lhs(val[0], val[1], val[2]) - } - - f_marg_list: f_marg - { - result = [ val[0] ] - } - | f_marg_list tCOMMA f_marg - { - result = val[0] << val[2] - } - - f_margs: f_marg_list - | f_marg_list tCOMMA tSTAR f_norm_arg - { - @static_env.declare val[3][0] - - result = val[0]. - push(@builder.restarg(val[2], val[3])) - } - | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list - { - @static_env.declare val[3][0] - - result = val[0]. - push(@builder.restarg(val[2], val[3])). - concat(val[5]) - } - | f_marg_list tCOMMA tSTAR - { - result = val[0]. - push(@builder.restarg(val[2])) - } - | f_marg_list tCOMMA tSTAR tCOMMA f_marg_list - { - result = val[0]. - push(@builder.restarg(val[2])). - concat(val[4]) - } - | tSTAR f_norm_arg - { - @static_env.declare val[1][0] - - result = [ @builder.restarg(val[0], val[1]) ] - } - | tSTAR f_norm_arg tCOMMA f_marg_list - { - @static_env.declare val[1][0] - - result = [ @builder.restarg(val[0], val[1]), - *val[3] ] - } - | tSTAR - { - result = [ @builder.restarg(val[0]) ] - } - | tSTAR tCOMMA f_marg_list - { - result = [ @builder.restarg(val[0]), - *val[2] ] - } - - block_param: f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg opt_f_block_arg - { - result = val[0]. - concat(val[2]). - concat(val[4]). - concat(val[5]) - } - | f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_f_block_arg - { - result = val[0]. - concat(val[2]). - concat(val[4]). - concat(val[6]). - concat(val[7]) - } - | f_arg tCOMMA f_block_optarg opt_f_block_arg - { - result = val[0]. - concat(val[2]). - concat(val[3]) - } - | f_arg tCOMMA f_block_optarg tCOMMA f_arg opt_f_block_arg - { - result = val[0]. - concat(val[2]). - concat(val[4]). - concat(val[5]) - } - | f_arg tCOMMA f_rest_arg opt_f_block_arg - { - result = val[0]. - concat(val[2]). - concat(val[3]) - } - | f_arg tCOMMA - | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_f_block_arg - { - result = val[0]. - concat(val[2]). - concat(val[4]). - concat(val[5]) - } - | f_arg opt_f_block_arg - { - result = val[0].concat(val[1]) - } - | f_block_optarg tCOMMA f_rest_arg opt_f_block_arg - { - result = val[0]. - concat(val[2]). - concat(val[3]) - } - | f_block_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_f_block_arg - { - result = val[0]. - concat(val[2]). - concat(val[4]). - concat(val[5]) - } - | f_block_optarg opt_f_block_arg - { - result = val[0]. - concat(val[1]) - } - | f_block_optarg tCOMMA f_arg opt_f_block_arg - { - result = val[0]. - concat(val[2]). - concat(val[3]) - } - | f_rest_arg opt_f_block_arg - { - result = val[0]. - concat(val[1]) - } - | f_rest_arg tCOMMA f_arg opt_f_block_arg - { - result = val[0]. - concat(val[2]). - concat(val[3]) - } - | f_block_arg - { - result = [ val[0] ] - } - - opt_block_param: # nothing - { - result = @builder.args(nil, [], nil) - } - | block_param_def - { - @lexer.state = :expr_value - } - - block_param_def: tPIPE opt_bv_decl tPIPE - { - result = @builder.args(val[0], val[1], val[2]) - } - | tOROP - { - result = @builder.args(val[0], [], val[0]) - } - | tPIPE block_param opt_bv_decl tPIPE - { - result = @builder.args(val[0], val[1].concat(val[2]), val[3]) - } - - opt_bv_decl: # nothing - { - result = [] - } - | tSEMI bv_decls - { - result = val[1] - } - - bv_decls: bvar - { - result = [ val[0] ] - } - | bv_decls tCOMMA bvar - { - result = val[0] << val[2] - } - - bvar: tIDENTIFIER - { - result = @builder.shadowarg(val[0]) - } - | f_bad_arg - - lambda: { - @static_env.extend_dynamic - } - f_larglist lambda_body - { - result = [ val[1], val[2] ] - - @static_env.unextend - } - - f_larglist: tLPAREN2 f_args opt_bv_decl rparen - { - result = @builder.args(val[0], val[1].concat(val[2]), val[3]) - } - | f_args - { - result = @builder.args(nil, val[0], nil) - } - - lambda_body: tLAMBEG compstmt tRCURLY - { - result = [ val[0], val[1], val[2] ] - } - | kDO_LAMBDA compstmt kEND - { - result = [ val[0], val[1], val[2] ] - } - - do_block: kDO_BLOCK - { - @static_env.extend_dynamic - } - opt_block_param compstmt kEND - { - result = [ val[0], val[2], val[3], val[4] ] - - @static_env.unextend - } - - block_call: command do_block - { - begin_t, block_args, body, end_t = val[1] - result = @builder.block(val[0], - begin_t, block_args, body, end_t) - } - | block_call tDOT operation2 opt_paren_args - { - lparen_t, args, rparen_t = val[3] - result = @builder.call_method(val[0], val[1], val[2], - lparen_t, args, rparen_t) - } - | block_call tCOLON2 operation2 opt_paren_args - { - lparen_t, args, rparen_t = val[3] - result = @builder.call_method(val[0], val[1], val[2], - lparen_t, args, rparen_t) - } - - method_call: operation paren_args - { - lparen_t, args, rparen_t = val[1] - result = @builder.call_method(nil, nil, val[0], - lparen_t, args, rparen_t) - } - | primary_value tDOT operation2 opt_paren_args - { - lparen_t, args, rparen_t = val[3] - result = @builder.call_method(val[0], val[1], val[2], - lparen_t, args, rparen_t) - } - | primary_value tCOLON2 operation2 paren_args - { - lparen_t, args, rparen_t = val[3] - result = @builder.call_method(val[0], val[1], val[2], - lparen_t, args, rparen_t) - } - | primary_value tCOLON2 operation3 - { - result = @builder.call_method(val[0], val[1], val[2]) - } - | primary_value tDOT paren_args - { - lparen_t, args, rparen_t = val[2] - result = @builder.call_method(val[0], val[1], nil, - lparen_t, args, rparen_t) - } - | primary_value tCOLON2 paren_args - { - lparen_t, args, rparen_t = val[2] - result = @builder.call_method(val[0], val[1], nil, - lparen_t, args, rparen_t) - } - | kSUPER paren_args - { - lparen_t, args, rparen_t = val[1] - result = @builder.keyword_cmd(:super, val[0], - lparen_t, args, rparen_t) - } - | kSUPER - { - result = @builder.keyword_cmd(:zsuper, val[0]) - } - | primary_value tLBRACK2 opt_call_args rbracket - { - result = @builder.index(val[0], val[1], val[2], val[3]) - } - - brace_block: tLCURLY - { - @static_env.extend_dynamic - } - opt_block_param compstmt tRCURLY - { - result = [ val[0], val[2], val[3], val[4] ] - - @static_env.unextend - } - | kDO - { - @static_env.extend_dynamic - } - opt_block_param compstmt kEND - { - result = [ val[0], val[2], val[3], val[4] ] - - @static_env.unextend - } - - case_body: kWHEN args then compstmt cases - { - result = [ @builder.when(val[0], val[1], val[2], val[3]), - *val[4] ] - } - - cases: opt_else - { - result = [ val[0] ] - } - | case_body - - opt_rescue: kRESCUE exc_list exc_var then compstmt opt_rescue - { - assoc_t, exc_var = val[2] - - if val[1] - exc_list = @builder.array(nil, val[1], nil) - end - - result = [ @builder.rescue_body(val[0], - exc_list, assoc_t, exc_var, - val[3], val[4]), - *val[5] ] - } - | - { - result = [] - } - - exc_list: arg_value - { - result = [ val[0] ] - } - | mrhs - | none - - exc_var: tASSOC lhs - { - result = [ val[0], val[1] ] - } - | none - - opt_ensure: kENSURE compstmt - { - result = [ val[0], val[1] ] - } - | none - - literal: numeric - | symbol - | dsym - - strings: string - { - result = @builder.string_compose(nil, val[0], nil) - } - - string: string1 - { - result = [ val[0] ] - } - | string string1 - { - result = val[0] << val[1] - } - - string1: tSTRING_BEG string_contents tSTRING_END - { - result = @builder.string_compose(val[0], val[1], val[2]) - } - | tSTRING - { - result = @builder.string(val[0]) - } - | tCHARACTER - { - result = @builder.character(val[0]) - } - - xstring: tXSTRING_BEG xstring_contents tSTRING_END - { - result = @builder.xstring_compose(val[0], val[1], val[2]) - } - - regexp: tREGEXP_BEG regexp_contents tSTRING_END tREGEXP_OPT - { - opts = @builder.regexp_options(val[3]) - result = @builder.regexp_compose(val[0], val[1], val[2], opts) - } - - words: tWORDS_BEG word_list tSTRING_END - { - result = @builder.words_compose(val[0], val[1], val[2]) - } - - word_list: # nothing - { - result = [] - } - | word_list word tSPACE - { - result = val[0] << @builder.word(val[1]) - } - - word: string_content - { - result = [ val[0] ] - } - | word string_content - { - result = val[0] << val[1] - } - - qwords: tQWORDS_BEG qword_list tSTRING_END - { - result = @builder.words_compose(val[0], val[1], val[2]) - } - - qword_list: # nothing - { - result = [] - } - | qword_list tSTRING_CONTENT tSPACE - { - result = val[0] << @builder.string_internal(val[1]) - } - - string_contents: # nothing - { - result = [] - } - | string_contents string_content - { - result = val[0] << val[1] - } - -xstring_contents: # nothing - { - result = [] - } - | xstring_contents string_content - { - result = val[0] << val[1] - } - -regexp_contents: # nothing - { - result = [] - } - | regexp_contents string_content - { - result = val[0] << val[1] - } - - string_content: tSTRING_CONTENT - { - result = @builder.string_internal(val[0]) - } - | tSTRING_DVAR string_dvar - { - result = val[1] - } - | tSTRING_DBEG - { - @lexer.cond.push(false) - @lexer.cmdarg.push(false) - } - compstmt tRCURLY - { - @lexer.cond.lexpop - @lexer.cmdarg.lexpop - - result = @builder.begin(val[0], val[2], val[3]) - } - - string_dvar: tGVAR - { - result = @builder.gvar(val[0]) - } - | tIVAR - { - result = @builder.ivar(val[0]) - } - | tCVAR - { - result = @builder.cvar(val[0]) - } - | backref - - - symbol: tSYMBOL - { - result = @builder.symbol(val[0]) - } - - dsym: tSYMBEG xstring_contents tSTRING_END - { - result = @builder.symbol_compose(val[0], val[1], val[2]) - } - - numeric: tINTEGER - { - result = @builder.integer(val[0]) - } - | tFLOAT - { - result = @builder.float(val[0]) - } - | tUMINUS_NUM tINTEGER =tLOWEST - { - result = @builder.negate(val[0], - @builder.integer(val[1])) - } - | tUMINUS_NUM tFLOAT =tLOWEST - { - result = @builder.negate(val[0], - @builder.float(val[1])) - } - - user_variable: tIDENTIFIER - { - result = @builder.ident(val[0]) - } - | tIVAR - { - result = @builder.ivar(val[0]) - } - | tGVAR - { - result = @builder.gvar(val[0]) - } - | tCONSTANT - { - result = @builder.const(val[0]) - } - | tCVAR - { - result = @builder.cvar(val[0]) - } - -keyword_variable: kNIL - { - result = @builder.nil(val[0]) - } - | kSELF - { - result = @builder.self(val[0]) - } - | kTRUE - { - result = @builder.true(val[0]) - } - | kFALSE - { - result = @builder.false(val[0]) - } - | k__FILE__ - { - result = @builder.__FILE__(val[0]) - } - | k__LINE__ - { - result = @builder.__LINE__(val[0]) - } - | k__ENCODING__ - { - result = @builder.__ENCODING__(val[0]) - } - - var_ref: user_variable - { - result = @builder.accessible(val[0]) - } - | keyword_variable - { - result = @builder.accessible(val[0]) - } - - var_lhs: user_variable - { - result = @builder.assignable(val[0]) - } - | keyword_variable - { - result = @builder.assignable(val[0]) - } - - backref: tNTH_REF - { - result = @builder.nth_ref(val[0]) - } - | tBACK_REF - { - result = @builder.back_ref(val[0]) - } - - superclass: term - { - result = nil - } - | tLT expr_value term - { - result = [ val[0], val[1] ] - } - | error term - { - yyerrok - result = nil - } - - f_arglist: tLPAREN2 f_args rparen - { - result = @builder.args(val[0], val[1], val[2]) - - @lexer.state = :expr_value - } - | f_args term - { - result = @builder.args(nil, val[0], nil) - } - - f_args: f_arg tCOMMA f_optarg tCOMMA f_rest_arg opt_f_block_arg - { - result = val[0]. - concat(val[2]). - concat(val[4]). - concat(val[5]) - } - | f_arg tCOMMA f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_f_block_arg - { - result = val[0]. - concat(val[2]). - concat(val[4]). - concat(val[6]). - concat(val[7]) - } - | f_arg tCOMMA f_optarg opt_f_block_arg - { - result = val[0]. - concat(val[2]). - concat(val[3]) - } - | f_arg tCOMMA f_optarg tCOMMA f_arg opt_f_block_arg - { - result = val[0]. - concat(val[2]). - concat(val[4]). - concat(val[5]) - } - | f_arg tCOMMA f_rest_arg opt_f_block_arg - { - result = val[0]. - concat(val[2]). - concat(val[3]) - } - | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_f_block_arg - { - result = val[0]. - concat(val[2]). - concat(val[4]). - concat(val[5]) - } - | f_arg opt_f_block_arg - { - result = val[0]. - concat(val[1]) - } - | f_optarg tCOMMA f_rest_arg opt_f_block_arg - { - result = val[0]. - concat(val[2]). - concat(val[3]) - } - | f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_f_block_arg - { - result = val[0]. - concat(val[2]). - concat(val[4]). - concat(val[5]) - } - | f_optarg opt_f_block_arg - { - result = val[0]. - concat(val[1]) - } - | f_optarg tCOMMA f_arg opt_f_block_arg - { - result = val[0]. - concat(val[2]). - concat(val[3]) - } - | f_rest_arg opt_f_block_arg - { - result = val[0]. - concat(val[1]) - } - | f_rest_arg tCOMMA f_arg opt_f_block_arg - { - result = val[0]. - concat(val[2]). - concat(val[3]) - } - | f_block_arg - { - result = [ val[0] ] - } - | # nothing - { - result = [] - } - - f_bad_arg: tCONSTANT - { - diagnostic :error, :argument_const, nil, val[0] - } - | tIVAR - { - diagnostic :error, :argument_ivar, nil, val[0] - } - | tGVAR - { - diagnostic :error, :argument_gvar, nil, val[0] - } - | tCVAR - { - diagnostic :error, :argument_cvar, nil, val[0] - } - - f_norm_arg: f_bad_arg - | tIDENTIFIER - - f_arg_item: f_norm_arg - { - @static_env.declare val[0][0] - - result = @builder.arg(val[0]) - } - | tLPAREN f_margs rparen - { - result = @builder.multi_lhs(val[0], val[1], val[2]) - } - - f_arg: f_arg_item - { - result = [ val[0] ] - } - | f_arg tCOMMA f_arg_item - { - result = val[0] << val[2] - } - - f_opt: tIDENTIFIER tEQL arg_value - { - @static_env.declare val[0][0] - - result = @builder.optarg(val[0], val[1], val[2]) - } - - f_block_opt: tIDENTIFIER tEQL primary_value - { - @static_env.declare val[0][0] - - result = @builder.optarg(val[0], val[1], val[2]) - } - - f_block_optarg: f_block_opt - { - result = [ val[0] ] - } - | f_block_optarg tCOMMA f_block_opt - { - result = val[0] << val[2] - } - - f_optarg: f_opt - { - result = [ val[0] ] - } - | f_optarg tCOMMA f_opt - { - result = val[0] << val[2] - } - - restarg_mark: tSTAR2 | tSTAR - - f_rest_arg: restarg_mark tIDENTIFIER - { - @static_env.declare val[1][0] - - result = [ @builder.restarg(val[0], val[1]) ] - } - | restarg_mark - { - result = [ @builder.restarg(val[0]) ] - } - - blkarg_mark: tAMPER2 | tAMPER - - f_block_arg: blkarg_mark tIDENTIFIER - { - @static_env.declare val[1][0] - - result = @builder.blockarg(val[0], val[1]) - } - - opt_f_block_arg: tCOMMA f_block_arg - { - result = [ val[1] ] - } - | # nothing - { - result = [] - } - - singleton: var_ref - | tLPAREN2 expr rparen - { - result = val[1] - } - - assoc_list: # nothing - { - result = [] - } - | assocs trailer - - assocs: assoc - { - result = [ val[0] ] - } - | assocs tCOMMA assoc - { - result = val[0] << val[2] - } - - assoc: arg_value tASSOC arg_value - { - result = @builder.pair(val[0], val[1], val[2]) - } - | tLABEL arg_value - { - result = @builder.pair_keyword(val[0], val[1]) - } - - operation: tIDENTIFIER | tCONSTANT | tFID - operation2: tIDENTIFIER | tCONSTANT | tFID | op - operation3: tIDENTIFIER | tFID | op - dot_or_colon: tDOT | tCOLON2 - opt_terms: | terms - opt_nl: | tNL - rparen: opt_nl tRPAREN - { - result = val[1] - } - rbracket: opt_nl tRBRACK - { - result = val[1] - } - trailer: | tNL | tCOMMA - - term: tSEMI - { - yyerrok - } - | tNL - - terms: term - | terms tSEMI - - none: # nothing - { - result = nil - } -end - ----- header - -require 'parser' - -Parser.check_for_encoding_support - ----- inner - - def version - 19 - end - - def default_encoding - Encoding::BINARY - end diff --git a/test/racc/assets/ruby20.y b/test/racc/assets/ruby20.y deleted file mode 100644 index 6e07734778..0000000000 --- a/test/racc/assets/ruby20.y +++ /dev/null @@ -1,2350 +0,0 @@ -# Copyright (c) 2013 Peter Zotov <whitequark@whitequark.org> -# -# Parts of the source are derived from ruby_parser: -# Copyright (c) Ryan Davis, seattle.rb -# -# MIT License -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -class Parser::Ruby20 - -token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS - kTHEN kELSIF kELSE kCASE kWHEN kWHILE kUNTIL kFOR kBREAK kNEXT - kREDO kRETRY kIN kDO kDO_COND kDO_BLOCK kDO_LAMBDA kRETURN kYIELD kSUPER - kSELF kNIL kTRUE kFALSE kAND kOR kNOT kIF_MOD kUNLESS_MOD kWHILE_MOD - kUNTIL_MOD kRESCUE_MOD kALIAS kDEFINED klBEGIN klEND k__LINE__ - k__FILE__ k__ENCODING__ tIDENTIFIER tFID tGVAR tIVAR tCONSTANT - tLABEL tCVAR tNTH_REF tBACK_REF tSTRING_CONTENT tINTEGER tFLOAT - tREGEXP_END tUPLUS tUMINUS tUMINUS_NUM tPOW tCMP tEQ tEQQ tNEQ - tGEQ tLEQ tANDOP tOROP tMATCH tNMATCH tDOT tDOT2 tDOT3 tAREF - tASET tLSHFT tRSHFT tCOLON2 tCOLON3 tOP_ASGN tASSOC tLPAREN - tLPAREN2 tRPAREN tLPAREN_ARG tLBRACK tLBRACK2 tRBRACK tLBRACE - tLBRACE_ARG tSTAR tSTAR2 tAMPER tAMPER2 tTILDE tPERCENT tDIVIDE - tDSTAR tPLUS tMINUS tLT tGT tPIPE tBANG tCARET tLCURLY tRCURLY - tBACK_REF2 tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG tREGEXP_OPT - tWORDS_BEG tQWORDS_BEG tSYMBOLS_BEG tQSYMBOLS_BEG tSTRING_DBEG - tSTRING_DVAR tSTRING_END tSTRING_DEND tSTRING tSYMBOL - tNL tEH tCOLON tCOMMA tSPACE tSEMI tLAMBDA tLAMBEG tCHARACTER - -prechigh - right tBANG tTILDE tUPLUS - right tPOW - right tUMINUS_NUM tUMINUS - left tSTAR2 tDIVIDE tPERCENT - left tPLUS tMINUS - left tLSHFT tRSHFT - left tAMPER2 - left tPIPE tCARET - left tGT tGEQ tLT tLEQ - nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH - left tANDOP - left tOROP - nonassoc tDOT2 tDOT3 - right tEH tCOLON - left kRESCUE_MOD - right tEQL tOP_ASGN - nonassoc kDEFINED - right kNOT - left kOR kAND - nonassoc kIF_MOD kUNLESS_MOD kWHILE_MOD kUNTIL_MOD - nonassoc tLBRACE_ARG - nonassoc tLOWEST -preclow - -rule - - program: top_compstmt - - top_compstmt: top_stmts opt_terms - { - result = @builder.compstmt(val[0]) - } - - top_stmts: # nothing - { - result = [] - } - | top_stmt - { - result = [ val[0] ] - } - | top_stmts terms top_stmt - { - result = val[0] << val[2] - } - | error top_stmt - { - result = [ val[1] ] - } - - top_stmt: stmt - | klBEGIN tLCURLY top_compstmt tRCURLY - { - result = @builder.preexe(val[0], val[1], val[2], val[3]) - } - - bodystmt: compstmt opt_rescue opt_else opt_ensure - { - rescue_bodies = val[1] - else_t, else_ = val[2] - ensure_t, ensure_ = val[3] - - if rescue_bodies.empty? && !else_.nil? - diagnostic :warning, :useless_else, nil, else_t - end - - result = @builder.begin_body(val[0], - rescue_bodies, - else_t, else_, - ensure_t, ensure_) - } - - compstmt: stmts opt_terms - { - result = @builder.compstmt(val[0]) - } - - stmts: # nothing - { - result = [] - } - | stmt_or_begin - { - result = [ val[0] ] - } - | stmts terms stmt_or_begin - { - result = val[0] << val[2] - } - | error stmt - { - result = [ val[1] ] - } - - stmt_or_begin: stmt - | klBEGIN tLCURLY top_compstmt tRCURLY - { - if in_def? - diagnostic :error, :begin_in_method, nil, val[0] - end - - result = @builder.preexe(val[0], val[1], val[2], val[3]) - } - - stmt: kALIAS fitem - { - @lexer.state = :expr_fname - } - fitem - { - result = @builder.alias(val[0], val[1], val[3]) - } - | kALIAS tGVAR tGVAR - { - result = @builder.alias(val[0], - @builder.gvar(val[1]), - @builder.gvar(val[2])) - } - | kALIAS tGVAR tBACK_REF - { - result = @builder.alias(val[0], - @builder.gvar(val[1]), - @builder.back_ref(val[2])) - } - | kALIAS tGVAR tNTH_REF - { - diagnostic :error, :nth_ref_alias, nil, val[2] - } - | kUNDEF undef_list - { - result = @builder.undef_method(val[0], val[1]) - } - | stmt kIF_MOD expr_value - { - result = @builder.condition_mod(val[0], nil, - val[1], val[2]) - } - | stmt kUNLESS_MOD expr_value - { - result = @builder.condition_mod(nil, val[0], - val[1], val[2]) - } - | stmt kWHILE_MOD expr_value - { - result = @builder.loop_mod(:while, val[0], val[1], val[2]) - } - | stmt kUNTIL_MOD expr_value - { - result = @builder.loop_mod(:until, val[0], val[1], val[2]) - } - | stmt kRESCUE_MOD stmt - { - rescue_body = @builder.rescue_body(val[1], - nil, nil, nil, - nil, val[2]) - - result = @builder.begin_body(val[0], [ rescue_body ]) - } - | klEND tLCURLY compstmt tRCURLY - { - result = @builder.postexe(val[0], val[1], val[2], val[3]) - } - | command_asgn - | mlhs tEQL command_call - { - result = @builder.multi_assign(val[0], val[1], val[2]) - } - | var_lhs tOP_ASGN command_call - { - result = @builder.op_assign(val[0], val[1], val[2]) - } - | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN command_call - { - result = @builder.op_assign( - @builder.index( - val[0], val[1], val[2], val[3]), - val[4], val[5]) - } - | primary_value tDOT tIDENTIFIER tOP_ASGN command_call - { - result = @builder.op_assign( - @builder.call_method( - val[0], val[1], val[2]), - val[3], val[4]) - } - | primary_value tDOT tCONSTANT tOP_ASGN command_call - { - result = @builder.op_assign( - @builder.call_method( - val[0], val[1], val[2]), - val[3], val[4]) - } - | primary_value tCOLON2 tCONSTANT tOP_ASGN command_call - { - result = @builder.op_assign( - @builder.call_method( - val[0], val[1], val[2]), - val[3], val[4]) - } - | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_call - { - result = @builder.op_assign( - @builder.call_method( - val[0], val[1], val[2]), - val[3], val[4]) - } - | backref tOP_ASGN command_call - { - @builder.op_assign(val[0], val[1], val[2]) - } - | lhs tEQL mrhs - { - result = @builder.assign(val[0], val[1], - @builder.array(nil, val[2], nil)) - } - | mlhs tEQL arg_value - { - result = @builder.multi_assign(val[0], val[1], val[2]) - } - | mlhs tEQL mrhs - { - result = @builder.multi_assign(val[0], val[1], - @builder.array(nil, val[2], nil)) - } - | expr - - command_asgn: lhs tEQL command_call - { - result = @builder.assign(val[0], val[1], val[2]) - } - | lhs tEQL command_asgn - { - result = @builder.assign(val[0], val[1], val[2]) - } - - expr: command_call - | expr kAND expr - { - result = @builder.logical_op(:and, val[0], val[1], val[2]) - } - | expr kOR expr - { - result = @builder.logical_op(:or, val[0], val[1], val[2]) - } - | kNOT opt_nl expr - { - result = @builder.not_op(val[0], nil, val[2], nil) - } - | tBANG command_call - { - result = @builder.not_op(val[0], nil, val[1], nil) - } - | arg - - expr_value: expr - - command_call: command - | block_command - - block_command: block_call - | block_call dot_or_colon operation2 command_args - { - result = @builder.call_method(val[0], val[1], val[2], - nil, val[3], nil) - } - - cmd_brace_block: tLBRACE_ARG - { - @static_env.extend_dynamic - } - opt_block_param compstmt tRCURLY - { - result = [ val[0], val[2], val[3], val[4] ] - - @static_env.unextend - } - - fcall: operation - - command: fcall command_args =tLOWEST - { - result = @builder.call_method(nil, nil, val[0], - nil, val[1], nil) - } - | fcall command_args cmd_brace_block - { - method_call = @builder.call_method(nil, nil, val[0], - nil, val[1], nil) - - begin_t, args, body, end_t = val[2] - result = @builder.block(method_call, - begin_t, args, body, end_t) - } - | primary_value tDOT operation2 command_args =tLOWEST - { - result = @builder.call_method(val[0], val[1], val[2], - nil, val[3], nil) - } - | primary_value tDOT operation2 command_args cmd_brace_block - { - method_call = @builder.call_method(val[0], val[1], val[2], - nil, val[3], nil) - - begin_t, args, body, end_t = val[4] - result = @builder.block(method_call, - begin_t, args, body, end_t) - } - | primary_value tCOLON2 operation2 command_args =tLOWEST - { - result = @builder.call_method(val[0], val[1], val[2], - nil, val[3], nil) - } - | primary_value tCOLON2 operation2 command_args cmd_brace_block - { - method_call = @builder.call_method(val[0], val[1], val[2], - nil, val[3], nil) - - begin_t, args, body, end_t = val[4] - result = @builder.block(method_call, - begin_t, args, body, end_t) - } - | kSUPER command_args - { - result = @builder.keyword_cmd(:super, val[0], - nil, val[1], nil) - } - | kYIELD command_args - { - result = @builder.keyword_cmd(:yield, val[0], - nil, val[1], nil) - } - | kRETURN call_args - { - result = @builder.keyword_cmd(:return, val[0], - nil, val[1], nil) - } - | kBREAK call_args - { - result = @builder.keyword_cmd(:break, val[0], - nil, val[1], nil) - } - | kNEXT call_args - { - result = @builder.keyword_cmd(:next, val[0], - nil, val[1], nil) - } - - mlhs: mlhs_basic - { - result = @builder.multi_lhs(nil, val[0], nil) - } - | tLPAREN mlhs_inner rparen - { - result = @builder.begin(val[0], val[1], val[2]) - } - - mlhs_inner: mlhs_basic - { - result = @builder.multi_lhs(nil, val[0], nil) - } - | tLPAREN mlhs_inner rparen - { - result = @builder.multi_lhs(val[0], val[1], val[2]) - } - - mlhs_basic: mlhs_head - | mlhs_head mlhs_item - { - result = val[0]. - push(val[1]) - } - | mlhs_head tSTAR mlhs_node - { - result = val[0]. - push(@builder.splat(val[1], val[2])) - } - | mlhs_head tSTAR mlhs_node tCOMMA mlhs_post - { - result = val[0]. - push(@builder.splat(val[1], val[2])). - concat(val[4]) - } - | mlhs_head tSTAR - { - result = val[0]. - push(@builder.splat(val[1])) - } - | mlhs_head tSTAR tCOMMA mlhs_post - { - result = val[0]. - push(@builder.splat(val[1])). - concat(val[3]) - } - | tSTAR mlhs_node - { - result = [ @builder.splat(val[0], val[1]) ] - } - | tSTAR mlhs_node tCOMMA mlhs_post - { - result = [ @builder.splat(val[0], val[1]), - *val[3] ] - } - | tSTAR - { - result = [ @builder.splat(val[0]) ] - } - | tSTAR tCOMMA mlhs_post - { - result = [ @builder.splat(val[0]), - *val[2] ] - } - - mlhs_item: mlhs_node - | tLPAREN mlhs_inner rparen - { - result = @builder.begin(val[0], val[1], val[2]) - } - - mlhs_head: mlhs_item tCOMMA - { - result = [ val[0] ] - } - | mlhs_head mlhs_item tCOMMA - { - result = val[0] << val[1] - } - - mlhs_post: mlhs_item - { - result = [ val[0] ] - } - | mlhs_post tCOMMA mlhs_item - { - result = val[0] << val[2] - } - - mlhs_node: user_variable - { - result = @builder.assignable(val[0]) - } - | keyword_variable - { - result = @builder.assignable(val[0]) - } - | primary_value tLBRACK2 opt_call_args rbracket - { - result = @builder.index_asgn(val[0], val[1], val[2], val[3]) - } - | primary_value tDOT tIDENTIFIER - { - result = @builder.attr_asgn(val[0], val[1], val[2]) - } - | primary_value tCOLON2 tIDENTIFIER - { - result = @builder.attr_asgn(val[0], val[1], val[2]) - } - | primary_value tDOT tCONSTANT - { - result = @builder.attr_asgn(val[0], val[1], val[2]) - } - | primary_value tCOLON2 tCONSTANT - { - result = @builder.assignable( - @builder.const_fetch(val[0], val[1], val[2])) - } - | tCOLON3 tCONSTANT - { - result = @builder.assignable( - @builder.const_global(val[0], val[1])) - } - | backref - { - result = @builder.assignable(val[0]) - } - - lhs: user_variable - { - result = @builder.assignable(val[0]) - } - | keyword_variable - { - result = @builder.assignable(val[0]) - } - | primary_value tLBRACK2 opt_call_args rbracket - { - result = @builder.index_asgn(val[0], val[1], val[2], val[3]) - } - | primary_value tDOT tIDENTIFIER - { - result = @builder.attr_asgn(val[0], val[1], val[2]) - } - | primary_value tCOLON2 tIDENTIFIER - { - result = @builder.attr_asgn(val[0], val[1], val[2]) - } - | primary_value tDOT tCONSTANT - { - result = @builder.attr_asgn(val[0], val[1], val[2]) - } - | primary_value tCOLON2 tCONSTANT - { - result = @builder.assignable( - @builder.const_fetch(val[0], val[1], val[2])) - } - | tCOLON3 tCONSTANT - { - result = @builder.assignable( - @builder.const_global(val[0], val[1])) - } - | backref - { - result = @builder.assignable(val[0]) - } - - cname: tIDENTIFIER - { - diagnostic :error, :module_name_const, nil, val[0] - } - | tCONSTANT - - cpath: tCOLON3 cname - { - result = @builder.const_global(val[0], val[1]) - } - | cname - { - result = @builder.const(val[0]) - } - | primary_value tCOLON2 cname - { - result = @builder.const_fetch(val[0], val[1], val[2]) - } - - fname: tIDENTIFIER | tCONSTANT | tFID - | op - | reswords - - fsym: fname - { - result = @builder.symbol(val[0]) - } - | symbol - - fitem: fsym - | dsym - - undef_list: fitem - { - result = [ val[0] ] - } - | undef_list tCOMMA - { - @lexer.state = :expr_fname - } - fitem - { - result = val[0] << val[3] - } - - op: tPIPE | tCARET | tAMPER2 | tCMP | tEQ | tEQQ - | tMATCH | tNMATCH | tGT | tGEQ | tLT | tLEQ - | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2 - | tSTAR | tDIVIDE | tPERCENT | tPOW | tBANG | tTILDE - | tUPLUS | tUMINUS | tAREF | tASET | tDSTAR | tBACK_REF2 - - reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND - | kALIAS | kAND | kBEGIN | kBREAK | kCASE - | kCLASS | kDEF | kDEFINED | kDO | kELSE - | kELSIF | kEND | kENSURE | kFALSE | kFOR - | kIN | kMODULE | kNEXT | kNIL | kNOT - | kOR | kREDO | kRESCUE | kRETRY | kRETURN - | kSELF | kSUPER | kTHEN | kTRUE | kUNDEF - | kWHEN | kYIELD | kIF | kUNLESS | kWHILE - | kUNTIL - - arg: lhs tEQL arg - { - result = @builder.assign(val[0], val[1], val[2]) - } - | lhs tEQL arg kRESCUE_MOD arg - { - rescue_body = @builder.rescue_body(val[3], - nil, nil, nil, - nil, val[4]) - - rescue_ = @builder.begin_body(val[2], [ rescue_body ]) - - result = @builder.assign(val[0], val[1], rescue_) - } - | var_lhs tOP_ASGN arg - { - result = @builder.op_assign(val[0], val[1], val[2]) - } - | var_lhs tOP_ASGN arg kRESCUE_MOD arg - { - rescue_body = @builder.rescue_body(val[3], - nil, nil, nil, - nil, val[4]) - - rescue_ = @builder.begin_body(val[2], [ rescue_body ]) - - result = @builder.op_assign(val[0], val[1], rescue_) - } - | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN arg - { - result = @builder.op_assign( - @builder.index( - val[0], val[1], val[2], val[3]), - val[4], val[5]) - } - | primary_value tDOT tIDENTIFIER tOP_ASGN arg - { - result = @builder.op_assign( - @builder.call_method( - val[0], val[1], val[2]), - val[3], val[4]) - } - | primary_value tDOT tCONSTANT tOP_ASGN arg - { - result = @builder.op_assign( - @builder.call_method( - val[0], val[1], val[2]), - val[3], val[4]) - } - | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg - { - result = @builder.op_assign( - @builder.call_method( - val[0], val[1], val[2]), - val[3], val[4]) - } - | primary_value tCOLON2 tCONSTANT tOP_ASGN arg - { - const = @builder.const_op_assignable( - @builder.const_fetch(val[0], val[1], val[2])) - result = @builder.op_assign(const, val[3], val[4]) - } - | tCOLON3 tCONSTANT tOP_ASGN arg - { - const = @builder.const_op_assignable( - @builder.const_global(val[0], val[1])) - result = @builder.op_assign(const, val[2], val[3]) - } - | backref tOP_ASGN arg - { - result = @builder.op_assign(val[0], val[1], val[2]) - } - | arg tDOT2 arg - { - result = @builder.range_inclusive(val[0], val[1], val[2]) - } - | arg tDOT3 arg - { - result = @builder.range_exclusive(val[0], val[1], val[2]) - } - | arg tPLUS arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tMINUS arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tSTAR2 arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tDIVIDE arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tPERCENT arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tPOW arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | tUMINUS_NUM tINTEGER tPOW arg - { - result = @builder.unary_op(val[0], - @builder.binary_op( - @builder.integer(val[1]), - val[2], val[3])) - } - | tUMINUS_NUM tFLOAT tPOW arg - { - result = @builder.unary_op(val[0], - @builder.binary_op( - @builder.float(val[1]), - val[2], val[3])) - } - | tUPLUS arg - { - result = @builder.unary_op(val[0], val[1]) - } - | tUMINUS arg - { - result = @builder.unary_op(val[0], val[1]) - } - | arg tPIPE arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tCARET arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tAMPER2 arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tCMP arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tGT arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tGEQ arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tLT arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tLEQ arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tEQ arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tEQQ arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tNEQ arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tMATCH arg - { - result = @builder.match_op(val[0], val[1], val[2]) - } - | arg tNMATCH arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | tBANG arg - { - result = @builder.not_op(val[0], nil, val[1], nil) - } - | tTILDE arg - { - result = @builder.unary_op(val[0], val[1]) - } - | arg tLSHFT arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tRSHFT arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tANDOP arg - { - result = @builder.logical_op(:and, val[0], val[1], val[2]) - } - | arg tOROP arg - { - result = @builder.logical_op(:or, val[0], val[1], val[2]) - } - | kDEFINED opt_nl arg - { - result = @builder.keyword_cmd(:defined?, val[0], nil, [ val[2] ], nil) - } - - | arg tEH arg opt_nl tCOLON arg - { - result = @builder.ternary(val[0], val[1], - val[2], val[4], val[5]) - } - | primary - - arg_value: arg - - aref_args: none - | args trailer - | args tCOMMA assocs trailer - { - result = val[0] << @builder.associate(nil, val[2], nil) - } - | assocs trailer - { - result = [ @builder.associate(nil, val[0], nil) ] - } - - paren_args: tLPAREN2 opt_call_args rparen - { - result = val - } - - opt_paren_args: # nothing - { - result = [ nil, [], nil ] - } - | paren_args - - opt_call_args: # nothing - { - result = [] - } - | call_args - | args tCOMMA - | args tCOMMA assocs tCOMMA - { - result = val[0] << @builder.associate(nil, val[2], nil) - } - | assocs tCOMMA - { - result = [ @builder.associate(nil, val[0], nil) ] - } - - call_args: command - { - result = [ val[0] ] - } - | args opt_block_arg - { - result = val[0].concat(val[1]) - } - | assocs opt_block_arg - { - result = [ @builder.associate(nil, val[0], nil) ] - result.concat(val[1]) - } - | args tCOMMA assocs opt_block_arg - { - assocs = @builder.associate(nil, val[2], nil) - result = val[0] << assocs - result.concat(val[3]) - } - | block_arg - { - result = [ val[0] ] - } - - command_args: { - result = @lexer.cmdarg.dup - @lexer.cmdarg.push(true) - } - call_args - { - @lexer.cmdarg = val[0] - - result = val[1] - } - - block_arg: tAMPER arg_value - { - result = @builder.block_pass(val[0], val[1]) - } - - opt_block_arg: tCOMMA block_arg - { - result = [ val[1] ] - } - | # nothing - { - result = [] - } - - args: arg_value - { - result = [ val[0] ] - } - | tSTAR arg_value - { - result = [ @builder.splat(val[0], val[1]) ] - } - | args tCOMMA arg_value - { - result = val[0] << val[2] - } - | args tCOMMA tSTAR arg_value - { - result = val[0] << @builder.splat(val[2], val[3]) - } - - mrhs: args tCOMMA arg_value - { - result = val[0] << val[2] - } - | args tCOMMA tSTAR arg_value - { - result = val[0] << @builder.splat(val[2], val[3]) - } - | tSTAR arg_value - { - result = [ @builder.splat(val[0], val[1]) ] - } - - primary: literal - | strings - | xstring - | regexp - | words - | qwords - | symbols - | qsymbols - | var_ref - | backref - | tFID - { - result = @builder.call_method(nil, nil, val[0]) - } - | kBEGIN - { - result = @lexer.cmdarg.dup - @lexer.cmdarg.clear - } - bodystmt kEND - { - @lexer.cmdarg = val[1] - - result = @builder.begin_keyword(val[0], val[2], val[3]) - } - | tLPAREN_ARG - { - result = @lexer.cmdarg.dup - @lexer.cmdarg.clear - } - expr - { - @lexer.state = :expr_endarg - } - opt_nl tRPAREN - { - @lexer.cmdarg = val[1] - - result = @builder.begin(val[0], val[2], val[5]) - } - | tLPAREN_ARG - { - @lexer.state = :expr_endarg - } - opt_nl tRPAREN - { - result = @builder.begin(val[0], nil, val[3]) - } - | tLPAREN compstmt tRPAREN - { - result = @builder.begin(val[0], val[1], val[2]) - } - | primary_value tCOLON2 tCONSTANT - { - result = @builder.const_fetch(val[0], val[1], val[2]) - } - | tCOLON3 tCONSTANT - { - result = @builder.const_global(val[0], val[1]) - } - | tLBRACK aref_args tRBRACK - { - result = @builder.array(val[0], val[1], val[2]) - } - | tLBRACE assoc_list tRCURLY - { - result = @builder.associate(val[0], val[1], val[2]) - } - | kRETURN - { - result = @builder.keyword_cmd(:return, val[0]) - } - | kYIELD tLPAREN2 call_args rparen - { - result = @builder.keyword_cmd(:yield, val[0], val[1], val[2], val[3]) - } - | kYIELD tLPAREN2 rparen - { - result = @builder.keyword_cmd(:yield, val[0], val[1], [], val[2]) - } - | kYIELD - { - result = @builder.keyword_cmd(:yield, val[0]) - } - | kDEFINED opt_nl tLPAREN2 expr rparen - { - result = @builder.keyword_cmd(:defined?, val[0], - val[2], [ val[3] ], val[4]) - } - | kNOT tLPAREN2 expr rparen - { - result = @builder.not_op(val[0], val[1], val[2], val[3]) - } - | kNOT tLPAREN2 rparen - { - result = @builder.not_op(val[0], val[1], nil, val[2]) - } - | fcall brace_block - { - method_call = @builder.call_method(nil, nil, val[0]) - - begin_t, args, body, end_t = val[1] - result = @builder.block(method_call, - begin_t, args, body, end_t) - } - | method_call - | method_call brace_block - { - begin_t, args, body, end_t = val[1] - result = @builder.block(val[0], - begin_t, args, body, end_t) - } - | tLAMBDA lambda - { - lambda_call = @builder.call_lambda(val[0]) - - args, (begin_t, body, end_t) = val[1] - result = @builder.block(lambda_call, - begin_t, args, body, end_t) - } - | kIF expr_value then compstmt if_tail kEND - { - else_t, else_ = val[4] - result = @builder.condition(val[0], val[1], val[2], - val[3], else_t, - else_, val[5]) - } - | kUNLESS expr_value then compstmt opt_else kEND - { - else_t, else_ = val[4] - result = @builder.condition(val[0], val[1], val[2], - else_, else_t, - val[3], val[5]) - } - | kWHILE - { - @lexer.cond.push(true) - } - expr_value do - { - @lexer.cond.pop - } - compstmt kEND - { - result = @builder.loop(:while, val[0], val[2], val[3], - val[5], val[6]) - } - | kUNTIL - { - @lexer.cond.push(true) - } - expr_value do - { - @lexer.cond.pop - } - compstmt kEND - { - result = @builder.loop(:until, val[0], val[2], val[3], - val[5], val[6]) - } - | kCASE expr_value opt_terms case_body kEND - { - *when_bodies, (else_t, else_body) = *val[3] - - result = @builder.case(val[0], val[1], - when_bodies, else_t, else_body, - val[4]) - } - | kCASE opt_terms case_body kEND - { - *when_bodies, (else_t, else_body) = *val[2] - - result = @builder.case(val[0], nil, - when_bodies, else_t, else_body, - val[3]) - } - | kFOR for_var kIN - { - @lexer.cond.push(true) - } - expr_value do - { - @lexer.cond.pop - } - compstmt kEND - { - result = @builder.for(val[0], val[1], - val[2], val[4], - val[5], val[7], val[8]) - } - | kCLASS cpath superclass - { - @static_env.extend_static - @lexer.push_cmdarg - } - bodystmt kEND - { - if in_def? - diagnostic :error, :class_in_def, nil, val[0] - end - - lt_t, superclass = val[2] - result = @builder.def_class(val[0], val[1], - lt_t, superclass, - val[4], val[5]) - - @lexer.pop_cmdarg - @static_env.unextend - } - | kCLASS tLSHFT expr term - { - result = @def_level - @def_level = 0 - - @static_env.extend_static - @lexer.push_cmdarg - } - bodystmt kEND - { - result = @builder.def_sclass(val[0], val[1], val[2], - val[5], val[6]) - - @lexer.pop_cmdarg - @static_env.unextend - - @def_level = val[4] - } - | kMODULE cpath - { - @static_env.extend_static - @lexer.push_cmdarg - } - bodystmt kEND - { - if in_def? - diagnostic :error, :module_in_def, nil, val[0] - end - - result = @builder.def_module(val[0], val[1], - val[3], val[4]) - - @lexer.pop_cmdarg - @static_env.unextend - } - | kDEF fname - { - @def_level += 1 - @static_env.extend_static - @lexer.push_cmdarg - } - f_arglist bodystmt kEND - { - result = @builder.def_method(val[0], val[1], - val[3], val[4], val[5]) - - @lexer.pop_cmdarg - @static_env.unextend - @def_level -= 1 - } - | kDEF singleton dot_or_colon - { - @lexer.state = :expr_fname - } - fname - { - @def_level += 1 - @static_env.extend_static - @lexer.push_cmdarg - } - f_arglist bodystmt kEND - { - result = @builder.def_singleton(val[0], val[1], val[2], - val[4], val[6], val[7], val[8]) - - @lexer.pop_cmdarg - @static_env.unextend - @def_level -= 1 - } - | kBREAK - { - result = @builder.keyword_cmd(:break, val[0]) - } - | kNEXT - { - result = @builder.keyword_cmd(:next, val[0]) - } - | kREDO - { - result = @builder.keyword_cmd(:redo, val[0]) - } - | kRETRY - { - result = @builder.keyword_cmd(:retry, val[0]) - } - - primary_value: primary - - then: term - | kTHEN - | term kTHEN - { - result = val[1] - } - - do: term - | kDO_COND - - if_tail: opt_else - | kELSIF expr_value then compstmt if_tail - { - else_t, else_ = val[4] - result = [ val[0], - @builder.condition(val[0], val[1], val[2], - val[3], else_t, - else_, nil), - ] - } - - opt_else: none - | kELSE compstmt - { - result = val - } - - for_var: lhs - | mlhs - - f_marg: f_norm_arg - { - @static_env.declare val[0][0] - - result = @builder.arg(val[0]) - } - | tLPAREN f_margs rparen - { - result = @builder.multi_lhs(val[0], val[1], val[2]) - } - - f_marg_list: f_marg - { - result = [ val[0] ] - } - | f_marg_list tCOMMA f_marg - { - result = val[0] << val[2] - } - - f_margs: f_marg_list - | f_marg_list tCOMMA tSTAR f_norm_arg - { - @static_env.declare val[3][0] - - result = val[0]. - push(@builder.restarg(val[2], val[3])) - } - | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list - { - @static_env.declare val[3][0] - - result = val[0]. - push(@builder.restarg(val[2], val[3])). - concat(val[5]) - } - | f_marg_list tCOMMA tSTAR - { - result = val[0]. - push(@builder.restarg(val[2])) - } - | f_marg_list tCOMMA tSTAR tCOMMA f_marg_list - { - result = val[0]. - push(@builder.restarg(val[2])). - concat(val[4]) - } - | tSTAR f_norm_arg - { - @static_env.declare val[1][0] - - result = [ @builder.restarg(val[0], val[1]) ] - } - | tSTAR f_norm_arg tCOMMA f_marg_list - { - @static_env.declare val[1][0] - - result = [ @builder.restarg(val[0], val[1]), - *val[3] ] - } - | tSTAR - { - result = [ @builder.restarg(val[0]) ] - } - | tSTAR tCOMMA f_marg_list - { - result = [ @builder.restarg(val[0]), - *val[2] ] - } - - block_args_tail: f_block_kwarg tCOMMA f_kwrest opt_f_block_arg - { - result = val[0].concat(val[2]).concat(val[3]) - } - | f_block_kwarg opt_f_block_arg - { - result = val[0].concat(val[1]) - } - | f_kwrest opt_f_block_arg - { - result = val[0].concat(val[1]) - } - | f_block_arg - { - result = [ val[0] ] - } - -opt_block_args_tail: - tCOMMA block_args_tail - { - result = val[1] - } - | # nothing - { - result = [] - } - - block_param: f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg opt_block_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[4]). - concat(val[5]) - } - | f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[4]). - concat(val[6]). - concat(val[7]) - } - | f_arg tCOMMA f_block_optarg opt_block_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[3]) - } - | f_arg tCOMMA f_block_optarg tCOMMA f_arg opt_block_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[4]). - concat(val[5]) - } - | f_arg tCOMMA f_rest_arg opt_block_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[3]) - } - | f_arg tCOMMA - | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[4]). - concat(val[5]) - } - | f_arg opt_block_args_tail - { - result = val[0].concat(val[1]) - } - | f_block_optarg tCOMMA f_rest_arg opt_block_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[3]) - } - | f_block_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[4]). - concat(val[5]) - } - | f_block_optarg opt_block_args_tail - { - result = val[0]. - concat(val[1]) - } - | f_block_optarg tCOMMA f_arg opt_block_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[3]) - } - | f_rest_arg opt_block_args_tail - { - result = val[0]. - concat(val[1]) - } - | f_rest_arg tCOMMA f_arg opt_block_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[3]) - } - | block_args_tail - - opt_block_param: # nothing - { - result = @builder.args(nil, [], nil) - } - | block_param_def - { - @lexer.state = :expr_value - } - - block_param_def: tPIPE opt_bv_decl tPIPE - { - result = @builder.args(val[0], val[1], val[2]) - } - | tOROP - { - result = @builder.args(val[0], [], val[0]) - } - | tPIPE block_param opt_bv_decl tPIPE - { - result = @builder.args(val[0], val[1].concat(val[2]), val[3]) - } - - opt_bv_decl: opt_nl - { - result = [] - } - | opt_nl tSEMI bv_decls opt_nl - { - result = val[2] - } - - bv_decls: bvar - { - result = [ val[0] ] - } - | bv_decls tCOMMA bvar - { - result = val[0] << val[2] - } - - bvar: tIDENTIFIER - { - result = @builder.shadowarg(val[0]) - } - | f_bad_arg - - lambda: { - @static_env.extend_dynamic - } - f_larglist lambda_body - { - result = [ val[1], val[2] ] - - @static_env.unextend - } - - f_larglist: tLPAREN2 f_args opt_bv_decl tRPAREN - { - result = @builder.args(val[0], val[1].concat(val[2]), val[3]) - } - | f_args - { - result = @builder.args(nil, val[0], nil) - } - - lambda_body: tLAMBEG compstmt tRCURLY - { - result = [ val[0], val[1], val[2] ] - } - | kDO_LAMBDA compstmt kEND - { - result = [ val[0], val[1], val[2] ] - } - - do_block: kDO_BLOCK - { - @static_env.extend_dynamic - } - opt_block_param compstmt kEND - { - result = [ val[0], val[2], val[3], val[4] ] - - @static_env.unextend - } - - block_call: command do_block - { - begin_t, block_args, body, end_t = val[1] - result = @builder.block(val[0], - begin_t, block_args, body, end_t) - } - | block_call dot_or_colon operation2 opt_paren_args - { - lparen_t, args, rparen_t = val[3] - result = @builder.call_method(val[0], val[1], val[2], - lparen_t, args, rparen_t) - } - | block_call dot_or_colon operation2 opt_paren_args brace_block - { - lparen_t, args, rparen_t = val[3] - method_call = @builder.call_method(val[0], val[1], val[2], - lparen_t, args, rparen_t) - - begin_t, args, body, end_t = val[4] - result = @builder.block(method_call, - begin_t, args, body, end_t) - } - | block_call dot_or_colon operation2 command_args do_block - { - method_call = @builder.call_method(val[0], val[1], val[2], - nil, val[3], nil) - - begin_t, args, body, end_t = val[4] - result = @builder.block(method_call, - begin_t, args, body, end_t) - } - - method_call: fcall paren_args - { - lparen_t, args, rparen_t = val[1] - result = @builder.call_method(nil, nil, val[0], - lparen_t, args, rparen_t) - } - | primary_value tDOT operation2 opt_paren_args - { - lparen_t, args, rparen_t = val[3] - result = @builder.call_method(val[0], val[1], val[2], - lparen_t, args, rparen_t) - } - | primary_value tCOLON2 operation2 paren_args - { - lparen_t, args, rparen_t = val[3] - result = @builder.call_method(val[0], val[1], val[2], - lparen_t, args, rparen_t) - } - | primary_value tCOLON2 operation3 - { - result = @builder.call_method(val[0], val[1], val[2]) - } - | primary_value tDOT paren_args - { - lparen_t, args, rparen_t = val[2] - result = @builder.call_method(val[0], val[1], nil, - lparen_t, args, rparen_t) - } - | primary_value tCOLON2 paren_args - { - lparen_t, args, rparen_t = val[2] - result = @builder.call_method(val[0], val[1], nil, - lparen_t, args, rparen_t) - } - | kSUPER paren_args - { - lparen_t, args, rparen_t = val[1] - result = @builder.keyword_cmd(:super, val[0], - lparen_t, args, rparen_t) - } - | kSUPER - { - result = @builder.keyword_cmd(:zsuper, val[0]) - } - | primary_value tLBRACK2 opt_call_args rbracket - { - result = @builder.index(val[0], val[1], val[2], val[3]) - } - - brace_block: tLCURLY - { - @static_env.extend_dynamic - } - opt_block_param compstmt tRCURLY - { - result = [ val[0], val[2], val[3], val[4] ] - - @static_env.unextend - } - | kDO - { - @static_env.extend_dynamic - } - opt_block_param compstmt kEND - { - result = [ val[0], val[2], val[3], val[4] ] - - @static_env.unextend - } - - case_body: kWHEN args then compstmt cases - { - result = [ @builder.when(val[0], val[1], val[2], val[3]), - *val[4] ] - } - - cases: opt_else - { - result = [ val[0] ] - } - | case_body - - opt_rescue: kRESCUE exc_list exc_var then compstmt opt_rescue - { - assoc_t, exc_var = val[2] - - if val[1] - exc_list = @builder.array(nil, val[1], nil) - end - - result = [ @builder.rescue_body(val[0], - exc_list, assoc_t, exc_var, - val[3], val[4]), - *val[5] ] - } - | - { - result = [] - } - - exc_list: arg_value - { - result = [ val[0] ] - } - | mrhs - | none - - exc_var: tASSOC lhs - { - result = [ val[0], val[1] ] - } - | none - - opt_ensure: kENSURE compstmt - { - result = [ val[0], val[1] ] - } - | none - - literal: numeric - | symbol - | dsym - - strings: string - { - result = @builder.string_compose(nil, val[0], nil) - } - - string: string1 - { - result = [ val[0] ] - } - | string string1 - { - result = val[0] << val[1] - } - - string1: tSTRING_BEG string_contents tSTRING_END - { - result = @builder.string_compose(val[0], val[1], val[2]) - } - | tSTRING - { - result = @builder.string(val[0]) - } - | tCHARACTER - { - result = @builder.character(val[0]) - } - - xstring: tXSTRING_BEG xstring_contents tSTRING_END - { - result = @builder.xstring_compose(val[0], val[1], val[2]) - } - - regexp: tREGEXP_BEG regexp_contents tSTRING_END tREGEXP_OPT - { - opts = @builder.regexp_options(val[3]) - result = @builder.regexp_compose(val[0], val[1], val[2], opts) - } - - words: tWORDS_BEG word_list tSTRING_END - { - result = @builder.words_compose(val[0], val[1], val[2]) - } - - word_list: # nothing - { - result = [] - } - | word_list word tSPACE - { - result = val[0] << @builder.word(val[1]) - } - - word: string_content - { - result = [ val[0] ] - } - | word string_content - { - result = val[0] << val[1] - } - - symbols: tSYMBOLS_BEG symbol_list tSTRING_END - { - result = @builder.symbols_compose(val[0], val[1], val[2]) - } - - symbol_list: # nothing - { - result = [] - } - | symbol_list word tSPACE - { - result = val[0] << @builder.word(val[1]) - } - - qwords: tQWORDS_BEG qword_list tSTRING_END - { - result = @builder.words_compose(val[0], val[1], val[2]) - } - - qsymbols: tQSYMBOLS_BEG qsym_list tSTRING_END - { - result = @builder.symbols_compose(val[0], val[1], val[2]) - } - - qword_list: # nothing - { - result = [] - } - | qword_list tSTRING_CONTENT tSPACE - { - result = val[0] << @builder.string_internal(val[1]) - } - - qsym_list: # nothing - { - result = [] - } - | qsym_list tSTRING_CONTENT tSPACE - { - result = val[0] << @builder.symbol_internal(val[1]) - } - - string_contents: # nothing - { - result = [] - } - | string_contents string_content - { - result = val[0] << val[1] - } - -xstring_contents: # nothing - { - result = [] - } - | xstring_contents string_content - { - result = val[0] << val[1] - } - -regexp_contents: # nothing - { - result = [] - } - | regexp_contents string_content - { - result = val[0] << val[1] - } - - string_content: tSTRING_CONTENT - { - result = @builder.string_internal(val[0]) - } - | tSTRING_DVAR string_dvar - { - result = val[1] - } - | tSTRING_DBEG - { - @lexer.cond.push(false) - @lexer.cmdarg.push(false) - } - compstmt tSTRING_DEND - { - @lexer.cond.lexpop - @lexer.cmdarg.lexpop - - result = @builder.begin(val[0], val[2], val[3]) - } - - string_dvar: tGVAR - { - result = @builder.gvar(val[0]) - } - | tIVAR - { - result = @builder.ivar(val[0]) - } - | tCVAR - { - result = @builder.cvar(val[0]) - } - | backref - - - symbol: tSYMBOL - { - result = @builder.symbol(val[0]) - } - - dsym: tSYMBEG xstring_contents tSTRING_END - { - result = @builder.symbol_compose(val[0], val[1], val[2]) - } - - numeric: tINTEGER - { - result = @builder.integer(val[0]) - } - | tFLOAT - { - result = @builder.float(val[0]) - } - | tUMINUS_NUM tINTEGER =tLOWEST - { - result = @builder.negate(val[0], - @builder.integer(val[1])) - } - | tUMINUS_NUM tFLOAT =tLOWEST - { - result = @builder.negate(val[0], - @builder.float(val[1])) - } - - user_variable: tIDENTIFIER - { - result = @builder.ident(val[0]) - } - | tIVAR - { - result = @builder.ivar(val[0]) - } - | tGVAR - { - result = @builder.gvar(val[0]) - } - | tCONSTANT - { - result = @builder.const(val[0]) - } - | tCVAR - { - result = @builder.cvar(val[0]) - } - -keyword_variable: kNIL - { - result = @builder.nil(val[0]) - } - | kSELF - { - result = @builder.self(val[0]) - } - | kTRUE - { - result = @builder.true(val[0]) - } - | kFALSE - { - result = @builder.false(val[0]) - } - | k__FILE__ - { - result = @builder.__FILE__(val[0]) - } - | k__LINE__ - { - result = @builder.__LINE__(val[0]) - } - | k__ENCODING__ - { - result = @builder.__ENCODING__(val[0]) - } - - var_ref: user_variable - { - result = @builder.accessible(val[0]) - } - | keyword_variable - { - result = @builder.accessible(val[0]) - } - - var_lhs: user_variable - { - result = @builder.assignable(val[0]) - } - | keyword_variable - { - result = @builder.assignable(val[0]) - } - - backref: tNTH_REF - { - result = @builder.nth_ref(val[0]) - } - | tBACK_REF - { - result = @builder.back_ref(val[0]) - } - - superclass: term - { - result = nil - } - | tLT - { - @lexer.state = :expr_value - } - expr_value term - { - result = [ val[0], val[2] ] - } - | error term - { - yyerrok - result = nil - } - - f_arglist: tLPAREN2 f_args rparen - { - result = @builder.args(val[0], val[1], val[2]) - - @lexer.state = :expr_value - } - | f_args term - { - result = @builder.args(nil, val[0], nil) - } - - args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg - { - result = val[0].concat(val[2]).concat(val[3]) - } - | f_kwarg opt_f_block_arg - { - result = val[0].concat(val[1]) - } - | f_kwrest opt_f_block_arg - { - result = val[0].concat(val[1]) - } - | f_block_arg - { - result = [ val[0] ] - } - - opt_args_tail: tCOMMA args_tail - { - result = val[1] - } - | # nothing - { - result = [] - } - - f_args: f_arg tCOMMA f_optarg tCOMMA f_rest_arg opt_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[4]). - concat(val[5]) - } - | f_arg tCOMMA f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[4]). - concat(val[6]). - concat(val[7]) - } - | f_arg tCOMMA f_optarg opt_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[3]) - } - | f_arg tCOMMA f_optarg tCOMMA f_arg opt_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[4]). - concat(val[5]) - } - | f_arg tCOMMA f_rest_arg opt_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[3]) - } - | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[4]). - concat(val[5]) - } - | f_arg opt_args_tail - { - result = val[0]. - concat(val[1]) - } - | f_optarg tCOMMA f_rest_arg opt_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[3]) - } - | f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[4]). - concat(val[5]) - } - | f_optarg opt_args_tail - { - result = val[0]. - concat(val[1]) - } - | f_optarg tCOMMA f_arg opt_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[3]) - } - | f_rest_arg opt_args_tail - { - result = val[0]. - concat(val[1]) - } - | f_rest_arg tCOMMA f_arg opt_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[3]) - } - | args_tail - { - result = val[0] - } - | # nothing - { - result = [] - } - - f_bad_arg: tCONSTANT - { - diagnostic :error, :argument_const, nil, val[0] - } - | tIVAR - { - diagnostic :error, :argument_ivar, nil, val[0] - } - | tGVAR - { - diagnostic :error, :argument_gvar, nil, val[0] - } - | tCVAR - { - diagnostic :error, :argument_cvar, nil, val[0] - } - - f_norm_arg: f_bad_arg - | tIDENTIFIER - - f_arg_item: f_norm_arg - { - @static_env.declare val[0][0] - - result = @builder.arg(val[0]) - } - | tLPAREN f_margs rparen - { - result = @builder.multi_lhs(val[0], val[1], val[2]) - } - - f_arg: f_arg_item - { - result = [ val[0] ] - } - | f_arg tCOMMA f_arg_item - { - result = val[0] << val[2] - } - - f_kw: tLABEL arg_value - { - check_kwarg_name(val[0]) - - @static_env.declare val[0][0] - - result = @builder.kwoptarg(val[0], val[1]) - } - - f_block_kw: tLABEL primary_value - { - check_kwarg_name(val[0]) - - @static_env.declare val[0][0] - - result = @builder.kwoptarg(val[0], val[1]) - } - - f_block_kwarg: f_block_kw - { - result = [ val[0] ] - } - | f_block_kwarg tCOMMA f_block_kw - { - result = val[0] << val[2] - } - - f_kwarg: f_kw - { - result = [ val[0] ] - } - | f_kwarg tCOMMA f_kw - { - result = val[0] << val[2] - } - - kwrest_mark: tPOW | tDSTAR - - f_kwrest: kwrest_mark tIDENTIFIER - { - @static_env.declare val[1][0] - - result = [ @builder.kwrestarg(val[0], val[1]) ] - } - | kwrest_mark - { - result = [ @builder.kwrestarg(val[0]) ] - } - - f_opt: tIDENTIFIER tEQL arg_value - { - @static_env.declare val[0][0] - - result = @builder.optarg(val[0], val[1], val[2]) - } - - f_block_opt: tIDENTIFIER tEQL primary_value - { - @static_env.declare val[0][0] - - result = @builder.optarg(val[0], val[1], val[2]) - } - - f_block_optarg: f_block_opt - { - result = [ val[0] ] - } - | f_block_optarg tCOMMA f_block_opt - { - result = val[0] << val[2] - } - - f_optarg: f_opt - { - result = [ val[0] ] - } - | f_optarg tCOMMA f_opt - { - result = val[0] << val[2] - } - - restarg_mark: tSTAR2 | tSTAR - - f_rest_arg: restarg_mark tIDENTIFIER - { - @static_env.declare val[1][0] - - result = [ @builder.restarg(val[0], val[1]) ] - } - | restarg_mark - { - result = [ @builder.restarg(val[0]) ] - } - - blkarg_mark: tAMPER2 | tAMPER - - f_block_arg: blkarg_mark tIDENTIFIER - { - @static_env.declare val[1][0] - - result = @builder.blockarg(val[0], val[1]) - } - - opt_f_block_arg: tCOMMA f_block_arg - { - result = [ val[1] ] - } - | - { - result = [] - } - - singleton: var_ref - | tLPAREN2 expr rparen - { - result = val[1] - } - - assoc_list: # nothing - { - result = [] - } - | assocs trailer - - assocs: assoc - { - result = [ val[0] ] - } - | assocs tCOMMA assoc - { - result = val[0] << val[2] - } - - assoc: arg_value tASSOC arg_value - { - result = @builder.pair(val[0], val[1], val[2]) - } - | tLABEL arg_value - { - result = @builder.pair_keyword(val[0], val[1]) - } - | tDSTAR arg_value - { - result = @builder.kwsplat(val[0], val[1]) - } - - operation: tIDENTIFIER | tCONSTANT | tFID - operation2: tIDENTIFIER | tCONSTANT | tFID | op - operation3: tIDENTIFIER | tFID | op - dot_or_colon: tDOT | tCOLON2 - opt_terms: | terms - opt_nl: | tNL - rparen: opt_nl tRPAREN - { - result = val[1] - } - rbracket: opt_nl tRBRACK - { - result = val[1] - } - trailer: | tNL | tCOMMA - - term: tSEMI - { - yyerrok - } - | tNL - - terms: term - | terms tSEMI - - none: # nothing - { - result = nil - } -end - ----- header - -require 'parser' - -Parser.check_for_encoding_support - ----- inner - - def version - 20 - end - - def default_encoding - Encoding::UTF_8 - end diff --git a/test/racc/assets/ruby21.y b/test/racc/assets/ruby21.y deleted file mode 100644 index 2ac94afb0c..0000000000 --- a/test/racc/assets/ruby21.y +++ /dev/null @@ -1,2359 +0,0 @@ -# Copyright (c) 2013 Peter Zotov <whitequark@whitequark.org> -# -# Parts of the source are derived from ruby_parser: -# Copyright (c) Ryan Davis, seattle.rb -# -# MIT License -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -class Parser::Ruby21 - -token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS - kTHEN kELSIF kELSE kCASE kWHEN kWHILE kUNTIL kFOR kBREAK kNEXT - kREDO kRETRY kIN kDO kDO_COND kDO_BLOCK kDO_LAMBDA kRETURN kYIELD kSUPER - kSELF kNIL kTRUE kFALSE kAND kOR kNOT kIF_MOD kUNLESS_MOD kWHILE_MOD - kUNTIL_MOD kRESCUE_MOD kALIAS kDEFINED klBEGIN klEND k__LINE__ - k__FILE__ k__ENCODING__ tIDENTIFIER tFID tGVAR tIVAR tCONSTANT - tLABEL tCVAR tNTH_REF tBACK_REF tSTRING_CONTENT tINTEGER tFLOAT - tREGEXP_END tUPLUS tUMINUS tUMINUS_NUM tPOW tCMP tEQ tEQQ tNEQ - tGEQ tLEQ tANDOP tOROP tMATCH tNMATCH tDOT tDOT2 tDOT3 tAREF - tASET tLSHFT tRSHFT tCOLON2 tCOLON3 tOP_ASGN tASSOC tLPAREN - tLPAREN2 tRPAREN tLPAREN_ARG tLBRACK tLBRACK2 tRBRACK tLBRACE - tLBRACE_ARG tSTAR tSTAR2 tAMPER tAMPER2 tTILDE tPERCENT tDIVIDE - tDSTAR tPLUS tMINUS tLT tGT tPIPE tBANG tCARET tLCURLY tRCURLY - tBACK_REF2 tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG tREGEXP_OPT - tWORDS_BEG tQWORDS_BEG tSYMBOLS_BEG tQSYMBOLS_BEG tSTRING_DBEG - tSTRING_DVAR tSTRING_END tSTRING_DEND tSTRING tSYMBOL - tNL tEH tCOLON tCOMMA tSPACE tSEMI tLAMBDA tLAMBEG tCHARACTER - tRATIONAL tIMAGINARY - -prechigh - right tBANG tTILDE tUPLUS - right tPOW - right tUMINUS_NUM tUMINUS - left tSTAR2 tDIVIDE tPERCENT - left tPLUS tMINUS - left tLSHFT tRSHFT - left tAMPER2 - left tPIPE tCARET - left tGT tGEQ tLT tLEQ - nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH - left tANDOP - left tOROP - nonassoc tDOT2 tDOT3 - right tEH tCOLON - left kRESCUE_MOD - right tEQL tOP_ASGN - nonassoc kDEFINED - right kNOT - left kOR kAND - nonassoc kIF_MOD kUNLESS_MOD kWHILE_MOD kUNTIL_MOD - nonassoc tLBRACE_ARG - nonassoc tLOWEST -preclow - -rule - - program: top_compstmt - - top_compstmt: top_stmts opt_terms - { - result = @builder.compstmt(val[0]) - } - - top_stmts: # nothing - { - result = [] - } - | top_stmt - { - result = [ val[0] ] - } - | top_stmts terms top_stmt - { - result = val[0] << val[2] - } - | error top_stmt - { - result = [ val[1] ] - } - - top_stmt: stmt - | klBEGIN tLCURLY top_compstmt tRCURLY - { - result = @builder.preexe(val[0], val[1], val[2], val[3]) - } - - bodystmt: compstmt opt_rescue opt_else opt_ensure - { - rescue_bodies = val[1] - else_t, else_ = val[2] - ensure_t, ensure_ = val[3] - - if rescue_bodies.empty? && !else_.nil? - diagnostic :warning, :useless_else, nil, else_t - end - - result = @builder.begin_body(val[0], - rescue_bodies, - else_t, else_, - ensure_t, ensure_) - } - - compstmt: stmts opt_terms - { - result = @builder.compstmt(val[0]) - } - - stmts: # nothing - { - result = [] - } - | stmt_or_begin - { - result = [ val[0] ] - } - | stmts terms stmt_or_begin - { - result = val[0] << val[2] - } - | error stmt - { - result = [ val[1] ] - } - - stmt_or_begin: stmt - | klBEGIN tLCURLY top_compstmt tRCURLY - { - diagnostic :error, :begin_in_method, nil, val[0] - } - - stmt: kALIAS fitem - { - @lexer.state = :expr_fname - } - fitem - { - result = @builder.alias(val[0], val[1], val[3]) - } - | kALIAS tGVAR tGVAR - { - result = @builder.alias(val[0], - @builder.gvar(val[1]), - @builder.gvar(val[2])) - } - | kALIAS tGVAR tBACK_REF - { - result = @builder.alias(val[0], - @builder.gvar(val[1]), - @builder.back_ref(val[2])) - } - | kALIAS tGVAR tNTH_REF - { - diagnostic :error, :nth_ref_alias, nil, val[2] - } - | kUNDEF undef_list - { - result = @builder.undef_method(val[0], val[1]) - } - | stmt kIF_MOD expr_value - { - result = @builder.condition_mod(val[0], nil, - val[1], val[2]) - } - | stmt kUNLESS_MOD expr_value - { - result = @builder.condition_mod(nil, val[0], - val[1], val[2]) - } - | stmt kWHILE_MOD expr_value - { - result = @builder.loop_mod(:while, val[0], val[1], val[2]) - } - | stmt kUNTIL_MOD expr_value - { - result = @builder.loop_mod(:until, val[0], val[1], val[2]) - } - | stmt kRESCUE_MOD stmt - { - rescue_body = @builder.rescue_body(val[1], - nil, nil, nil, - nil, val[2]) - - result = @builder.begin_body(val[0], [ rescue_body ]) - } - | klEND tLCURLY compstmt tRCURLY - { - result = @builder.postexe(val[0], val[1], val[2], val[3]) - } - | command_asgn - | mlhs tEQL command_call - { - result = @builder.multi_assign(val[0], val[1], val[2]) - } - | var_lhs tOP_ASGN command_call - { - result = @builder.op_assign(val[0], val[1], val[2]) - } - | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN command_call - { - result = @builder.op_assign( - @builder.index( - val[0], val[1], val[2], val[3]), - val[4], val[5]) - } - | primary_value tDOT tIDENTIFIER tOP_ASGN command_call - { - result = @builder.op_assign( - @builder.call_method( - val[0], val[1], val[2]), - val[3], val[4]) - } - | primary_value tDOT tCONSTANT tOP_ASGN command_call - { - result = @builder.op_assign( - @builder.call_method( - val[0], val[1], val[2]), - val[3], val[4]) - } - | primary_value tCOLON2 tCONSTANT tOP_ASGN command_call - { - result = @builder.op_assign( - @builder.call_method( - val[0], val[1], val[2]), - val[3], val[4]) - } - | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_call - { - result = @builder.op_assign( - @builder.call_method( - val[0], val[1], val[2]), - val[3], val[4]) - } - | backref tOP_ASGN command_call - { - @builder.op_assign(val[0], val[1], val[2]) - } - | lhs tEQL mrhs - { - result = @builder.assign(val[0], val[1], - @builder.array(nil, val[2], nil)) - } - | mlhs tEQL mrhs_arg - { - result = @builder.multi_assign(val[0], val[1], val[2]) - } - | expr - - command_asgn: lhs tEQL command_call - { - result = @builder.assign(val[0], val[1], val[2]) - } - | lhs tEQL command_asgn - { - result = @builder.assign(val[0], val[1], val[2]) - } - - expr: command_call - | expr kAND expr - { - result = @builder.logical_op(:and, val[0], val[1], val[2]) - } - | expr kOR expr - { - result = @builder.logical_op(:or, val[0], val[1], val[2]) - } - | kNOT opt_nl expr - { - result = @builder.not_op(val[0], nil, val[2], nil) - } - | tBANG command_call - { - result = @builder.not_op(val[0], nil, val[1], nil) - } - | arg - - expr_value: expr - - command_call: command - | block_command - - block_command: block_call - | block_call dot_or_colon operation2 command_args - { - result = @builder.call_method(val[0], val[1], val[2], - nil, val[3], nil) - } - - cmd_brace_block: tLBRACE_ARG - { - @static_env.extend_dynamic - } - opt_block_param compstmt tRCURLY - { - result = [ val[0], val[2], val[3], val[4] ] - - @static_env.unextend - } - - fcall: operation - - command: fcall command_args =tLOWEST - { - result = @builder.call_method(nil, nil, val[0], - nil, val[1], nil) - } - | fcall command_args cmd_brace_block - { - method_call = @builder.call_method(nil, nil, val[0], - nil, val[1], nil) - - begin_t, args, body, end_t = val[2] - result = @builder.block(method_call, - begin_t, args, body, end_t) - } - | primary_value tDOT operation2 command_args =tLOWEST - { - result = @builder.call_method(val[0], val[1], val[2], - nil, val[3], nil) - } - | primary_value tDOT operation2 command_args cmd_brace_block - { - method_call = @builder.call_method(val[0], val[1], val[2], - nil, val[3], nil) - - begin_t, args, body, end_t = val[4] - result = @builder.block(method_call, - begin_t, args, body, end_t) - } - | primary_value tCOLON2 operation2 command_args =tLOWEST - { - result = @builder.call_method(val[0], val[1], val[2], - nil, val[3], nil) - } - | primary_value tCOLON2 operation2 command_args cmd_brace_block - { - method_call = @builder.call_method(val[0], val[1], val[2], - nil, val[3], nil) - - begin_t, args, body, end_t = val[4] - result = @builder.block(method_call, - begin_t, args, body, end_t) - } - | kSUPER command_args - { - result = @builder.keyword_cmd(:super, val[0], - nil, val[1], nil) - } - | kYIELD command_args - { - result = @builder.keyword_cmd(:yield, val[0], - nil, val[1], nil) - } - | kRETURN call_args - { - result = @builder.keyword_cmd(:return, val[0], - nil, val[1], nil) - } - | kBREAK call_args - { - result = @builder.keyword_cmd(:break, val[0], - nil, val[1], nil) - } - | kNEXT call_args - { - result = @builder.keyword_cmd(:next, val[0], - nil, val[1], nil) - } - - mlhs: mlhs_basic - { - result = @builder.multi_lhs(nil, val[0], nil) - } - | tLPAREN mlhs_inner rparen - { - result = @builder.begin(val[0], val[1], val[2]) - } - - mlhs_inner: mlhs_basic - { - result = @builder.multi_lhs(nil, val[0], nil) - } - | tLPAREN mlhs_inner rparen - { - result = @builder.multi_lhs(val[0], val[1], val[2]) - } - - mlhs_basic: mlhs_head - | mlhs_head mlhs_item - { - result = val[0]. - push(val[1]) - } - | mlhs_head tSTAR mlhs_node - { - result = val[0]. - push(@builder.splat(val[1], val[2])) - } - | mlhs_head tSTAR mlhs_node tCOMMA mlhs_post - { - result = val[0]. - push(@builder.splat(val[1], val[2])). - concat(val[4]) - } - | mlhs_head tSTAR - { - result = val[0]. - push(@builder.splat(val[1])) - } - | mlhs_head tSTAR tCOMMA mlhs_post - { - result = val[0]. - push(@builder.splat(val[1])). - concat(val[3]) - } - | tSTAR mlhs_node - { - result = [ @builder.splat(val[0], val[1]) ] - } - | tSTAR mlhs_node tCOMMA mlhs_post - { - result = [ @builder.splat(val[0], val[1]), - *val[3] ] - } - | tSTAR - { - result = [ @builder.splat(val[0]) ] - } - | tSTAR tCOMMA mlhs_post - { - result = [ @builder.splat(val[0]), - *val[2] ] - } - - mlhs_item: mlhs_node - | tLPAREN mlhs_inner rparen - { - result = @builder.begin(val[0], val[1], val[2]) - } - - mlhs_head: mlhs_item tCOMMA - { - result = [ val[0] ] - } - | mlhs_head mlhs_item tCOMMA - { - result = val[0] << val[1] - } - - mlhs_post: mlhs_item - { - result = [ val[0] ] - } - | mlhs_post tCOMMA mlhs_item - { - result = val[0] << val[2] - } - - mlhs_node: user_variable - { - result = @builder.assignable(val[0]) - } - | keyword_variable - { - result = @builder.assignable(val[0]) - } - | primary_value tLBRACK2 opt_call_args rbracket - { - result = @builder.index_asgn(val[0], val[1], val[2], val[3]) - } - | primary_value tDOT tIDENTIFIER - { - result = @builder.attr_asgn(val[0], val[1], val[2]) - } - | primary_value tCOLON2 tIDENTIFIER - { - result = @builder.attr_asgn(val[0], val[1], val[2]) - } - | primary_value tDOT tCONSTANT - { - result = @builder.attr_asgn(val[0], val[1], val[2]) - } - | primary_value tCOLON2 tCONSTANT - { - result = @builder.assignable( - @builder.const_fetch(val[0], val[1], val[2])) - } - | tCOLON3 tCONSTANT - { - result = @builder.assignable( - @builder.const_global(val[0], val[1])) - } - | backref - { - result = @builder.assignable(val[0]) - } - - lhs: user_variable - { - result = @builder.assignable(val[0]) - } - | keyword_variable - { - result = @builder.assignable(val[0]) - } - | primary_value tLBRACK2 opt_call_args rbracket - { - result = @builder.index_asgn(val[0], val[1], val[2], val[3]) - } - | primary_value tDOT tIDENTIFIER - { - result = @builder.attr_asgn(val[0], val[1], val[2]) - } - | primary_value tCOLON2 tIDENTIFIER - { - result = @builder.attr_asgn(val[0], val[1], val[2]) - } - | primary_value tDOT tCONSTANT - { - result = @builder.attr_asgn(val[0], val[1], val[2]) - } - | primary_value tCOLON2 tCONSTANT - { - result = @builder.assignable( - @builder.const_fetch(val[0], val[1], val[2])) - } - | tCOLON3 tCONSTANT - { - result = @builder.assignable( - @builder.const_global(val[0], val[1])) - } - | backref - { - result = @builder.assignable(val[0]) - } - - cname: tIDENTIFIER - { - diagnostic :error, :module_name_const, nil, val[0] - } - | tCONSTANT - - cpath: tCOLON3 cname - { - result = @builder.const_global(val[0], val[1]) - } - | cname - { - result = @builder.const(val[0]) - } - | primary_value tCOLON2 cname - { - result = @builder.const_fetch(val[0], val[1], val[2]) - } - - fname: tIDENTIFIER | tCONSTANT | tFID - | op - | reswords - - fsym: fname - { - result = @builder.symbol(val[0]) - } - | symbol - - fitem: fsym - | dsym - - undef_list: fitem - { - result = [ val[0] ] - } - | undef_list tCOMMA - { - @lexer.state = :expr_fname - } - fitem - { - result = val[0] << val[3] - } - - op: tPIPE | tCARET | tAMPER2 | tCMP | tEQ | tEQQ - | tMATCH | tNMATCH | tGT | tGEQ | tLT | tLEQ - | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2 - | tSTAR | tDIVIDE | tPERCENT | tPOW | tBANG | tTILDE - | tUPLUS | tUMINUS | tAREF | tASET | tDSTAR | tBACK_REF2 - - reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND - | kALIAS | kAND | kBEGIN | kBREAK | kCASE - | kCLASS | kDEF | kDEFINED | kDO | kELSE - | kELSIF | kEND | kENSURE | kFALSE | kFOR - | kIN | kMODULE | kNEXT | kNIL | kNOT - | kOR | kREDO | kRESCUE | kRETRY | kRETURN - | kSELF | kSUPER | kTHEN | kTRUE | kUNDEF - | kWHEN | kYIELD | kIF | kUNLESS | kWHILE - | kUNTIL - - arg: lhs tEQL arg - { - result = @builder.assign(val[0], val[1], val[2]) - } - | lhs tEQL arg kRESCUE_MOD arg - { - rescue_body = @builder.rescue_body(val[3], - nil, nil, nil, - nil, val[4]) - - rescue_ = @builder.begin_body(val[2], [ rescue_body ]) - - result = @builder.assign(val[0], val[1], rescue_) - } - | var_lhs tOP_ASGN arg - { - result = @builder.op_assign(val[0], val[1], val[2]) - } - | var_lhs tOP_ASGN arg kRESCUE_MOD arg - { - rescue_body = @builder.rescue_body(val[3], - nil, nil, nil, - nil, val[4]) - - rescue_ = @builder.begin_body(val[2], [ rescue_body ]) - - result = @builder.op_assign(val[0], val[1], rescue_) - } - | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN arg - { - result = @builder.op_assign( - @builder.index( - val[0], val[1], val[2], val[3]), - val[4], val[5]) - } - | primary_value tDOT tIDENTIFIER tOP_ASGN arg - { - result = @builder.op_assign( - @builder.call_method( - val[0], val[1], val[2]), - val[3], val[4]) - } - | primary_value tDOT tCONSTANT tOP_ASGN arg - { - result = @builder.op_assign( - @builder.call_method( - val[0], val[1], val[2]), - val[3], val[4]) - } - | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg - { - result = @builder.op_assign( - @builder.call_method( - val[0], val[1], val[2]), - val[3], val[4]) - } - | primary_value tCOLON2 tCONSTANT tOP_ASGN arg - { - const = @builder.const_op_assignable( - @builder.const_fetch(val[0], val[1], val[2])) - result = @builder.op_assign(const, val[3], val[4]) - } - | tCOLON3 tCONSTANT tOP_ASGN arg - { - const = @builder.const_op_assignable( - @builder.const_global(val[0], val[1])) - result = @builder.op_assign(const, val[2], val[3]) - } - | backref tOP_ASGN arg - { - result = @builder.op_assign(val[0], val[1], val[2]) - } - | arg tDOT2 arg - { - result = @builder.range_inclusive(val[0], val[1], val[2]) - } - | arg tDOT3 arg - { - result = @builder.range_exclusive(val[0], val[1], val[2]) - } - | arg tPLUS arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tMINUS arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tSTAR2 arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tDIVIDE arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tPERCENT arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tPOW arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | tUMINUS_NUM simple_numeric tPOW arg - { - result = @builder.unary_op(val[0], - @builder.binary_op( - val[1], val[2], val[3])) - } - | tUPLUS arg - { - result = @builder.unary_op(val[0], val[1]) - } - | tUMINUS arg - { - result = @builder.unary_op(val[0], val[1]) - } - | arg tPIPE arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tCARET arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tAMPER2 arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tCMP arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tGT arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tGEQ arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tLT arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tLEQ arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tEQ arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tEQQ arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tNEQ arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tMATCH arg - { - result = @builder.match_op(val[0], val[1], val[2]) - } - | arg tNMATCH arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | tBANG arg - { - result = @builder.not_op(val[0], nil, val[1], nil) - } - | tTILDE arg - { - result = @builder.unary_op(val[0], val[1]) - } - | arg tLSHFT arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tRSHFT arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tANDOP arg - { - result = @builder.logical_op(:and, val[0], val[1], val[2]) - } - | arg tOROP arg - { - result = @builder.logical_op(:or, val[0], val[1], val[2]) - } - | kDEFINED opt_nl arg - { - result = @builder.keyword_cmd(:defined?, val[0], nil, [ val[2] ], nil) - } - - | arg tEH arg opt_nl tCOLON arg - { - result = @builder.ternary(val[0], val[1], - val[2], val[4], val[5]) - } - | primary - - arg_value: arg - - aref_args: none - | args trailer - | args tCOMMA assocs trailer - { - result = val[0] << @builder.associate(nil, val[2], nil) - } - | assocs trailer - { - result = [ @builder.associate(nil, val[0], nil) ] - } - - paren_args: tLPAREN2 opt_call_args rparen - { - result = val - } - - opt_paren_args: # nothing - { - result = [ nil, [], nil ] - } - | paren_args - - opt_call_args: # nothing - { - result = [] - } - | call_args - | args tCOMMA - | args tCOMMA assocs tCOMMA - { - result = val[0] << @builder.associate(nil, val[2], nil) - } - | assocs tCOMMA - { - result = [ @builder.associate(nil, val[0], nil) ] - } - - call_args: command - { - result = [ val[0] ] - } - | args opt_block_arg - { - result = val[0].concat(val[1]) - } - | assocs opt_block_arg - { - result = [ @builder.associate(nil, val[0], nil) ] - result.concat(val[1]) - } - | args tCOMMA assocs opt_block_arg - { - assocs = @builder.associate(nil, val[2], nil) - result = val[0] << assocs - result.concat(val[3]) - } - | block_arg - { - result = [ val[0] ] - } - - command_args: { - result = @lexer.cmdarg.dup - @lexer.cmdarg.push(true) - } - call_args - { - @lexer.cmdarg = val[0] - - result = val[1] - } - - block_arg: tAMPER arg_value - { - result = @builder.block_pass(val[0], val[1]) - } - - opt_block_arg: tCOMMA block_arg - { - result = [ val[1] ] - } - | # nothing - { - result = [] - } - - args: arg_value - { - result = [ val[0] ] - } - | tSTAR arg_value - { - result = [ @builder.splat(val[0], val[1]) ] - } - | args tCOMMA arg_value - { - result = val[0] << val[2] - } - | args tCOMMA tSTAR arg_value - { - result = val[0] << @builder.splat(val[2], val[3]) - } - - mrhs_arg: mrhs - { - result = @builder.array(nil, val[0], nil) - } - | arg_value - - mrhs: args tCOMMA arg_value - { - result = val[0] << val[2] - } - | args tCOMMA tSTAR arg_value - { - result = val[0] << @builder.splat(val[2], val[3]) - } - | tSTAR arg_value - { - result = [ @builder.splat(val[0], val[1]) ] - } - - primary: literal - | strings - | xstring - | regexp - | words - | qwords - | symbols - | qsymbols - | var_ref - | backref - | tFID - { - result = @builder.call_method(nil, nil, val[0]) - } - | kBEGIN - { - result = @lexer.cmdarg.dup - @lexer.cmdarg.clear - } - bodystmt kEND - { - @lexer.cmdarg = val[1] - - result = @builder.begin_keyword(val[0], val[2], val[3]) - } - | tLPAREN_ARG - { - result = @lexer.cmdarg.dup - @lexer.cmdarg.clear - } - expr - { - @lexer.state = :expr_endarg - } - opt_nl tRPAREN - { - @lexer.cmdarg = val[1] - - result = @builder.begin(val[0], val[2], val[5]) - } - | tLPAREN_ARG - { - @lexer.state = :expr_endarg - } - opt_nl tRPAREN - { - result = @builder.begin(val[0], nil, val[3]) - } - | tLPAREN compstmt tRPAREN - { - result = @builder.begin(val[0], val[1], val[2]) - } - | primary_value tCOLON2 tCONSTANT - { - result = @builder.const_fetch(val[0], val[1], val[2]) - } - | tCOLON3 tCONSTANT - { - result = @builder.const_global(val[0], val[1]) - } - | tLBRACK aref_args tRBRACK - { - result = @builder.array(val[0], val[1], val[2]) - } - | tLBRACE assoc_list tRCURLY - { - result = @builder.associate(val[0], val[1], val[2]) - } - | kRETURN - { - result = @builder.keyword_cmd(:return, val[0]) - } - | kYIELD tLPAREN2 call_args rparen - { - result = @builder.keyword_cmd(:yield, val[0], val[1], val[2], val[3]) - } - | kYIELD tLPAREN2 rparen - { - result = @builder.keyword_cmd(:yield, val[0], val[1], [], val[2]) - } - | kYIELD - { - result = @builder.keyword_cmd(:yield, val[0]) - } - | kDEFINED opt_nl tLPAREN2 expr rparen - { - result = @builder.keyword_cmd(:defined?, val[0], - val[2], [ val[3] ], val[4]) - } - | kNOT tLPAREN2 expr rparen - { - result = @builder.not_op(val[0], val[1], val[2], val[3]) - } - | kNOT tLPAREN2 rparen - { - result = @builder.not_op(val[0], val[1], nil, val[2]) - } - | fcall brace_block - { - method_call = @builder.call_method(nil, nil, val[0]) - - begin_t, args, body, end_t = val[1] - result = @builder.block(method_call, - begin_t, args, body, end_t) - } - | method_call - | method_call brace_block - { - begin_t, args, body, end_t = val[1] - result = @builder.block(val[0], - begin_t, args, body, end_t) - } - | tLAMBDA lambda - { - lambda_call = @builder.call_lambda(val[0]) - - args, (begin_t, body, end_t) = val[1] - result = @builder.block(lambda_call, - begin_t, args, body, end_t) - } - | kIF expr_value then compstmt if_tail kEND - { - else_t, else_ = val[4] - result = @builder.condition(val[0], val[1], val[2], - val[3], else_t, - else_, val[5]) - } - | kUNLESS expr_value then compstmt opt_else kEND - { - else_t, else_ = val[4] - result = @builder.condition(val[0], val[1], val[2], - else_, else_t, - val[3], val[5]) - } - | kWHILE - { - @lexer.cond.push(true) - } - expr_value do - { - @lexer.cond.pop - } - compstmt kEND - { - result = @builder.loop(:while, val[0], val[2], val[3], - val[5], val[6]) - } - | kUNTIL - { - @lexer.cond.push(true) - } - expr_value do - { - @lexer.cond.pop - } - compstmt kEND - { - result = @builder.loop(:until, val[0], val[2], val[3], - val[5], val[6]) - } - | kCASE expr_value opt_terms case_body kEND - { - *when_bodies, (else_t, else_body) = *val[3] - - result = @builder.case(val[0], val[1], - when_bodies, else_t, else_body, - val[4]) - } - | kCASE opt_terms case_body kEND - { - *when_bodies, (else_t, else_body) = *val[2] - - result = @builder.case(val[0], nil, - when_bodies, else_t, else_body, - val[3]) - } - | kFOR for_var kIN - { - @lexer.cond.push(true) - } - expr_value do - { - @lexer.cond.pop - } - compstmt kEND - { - result = @builder.for(val[0], val[1], - val[2], val[4], - val[5], val[7], val[8]) - } - | kCLASS cpath superclass - { - @static_env.extend_static - @lexer.push_cmdarg - } - bodystmt kEND - { - if in_def? - diagnostic :error, :class_in_def, nil, val[0] - end - - lt_t, superclass = val[2] - result = @builder.def_class(val[0], val[1], - lt_t, superclass, - val[4], val[5]) - - @lexer.pop_cmdarg - @static_env.unextend - } - | kCLASS tLSHFT expr term - { - result = @def_level - @def_level = 0 - - @static_env.extend_static - @lexer.push_cmdarg - } - bodystmt kEND - { - result = @builder.def_sclass(val[0], val[1], val[2], - val[5], val[6]) - - @lexer.pop_cmdarg - @static_env.unextend - - @def_level = val[4] - } - | kMODULE cpath - { - @static_env.extend_static - @lexer.push_cmdarg - } - bodystmt kEND - { - if in_def? - diagnostic :error, :module_in_def, nil, val[0] - end - - result = @builder.def_module(val[0], val[1], - val[3], val[4]) - - @lexer.pop_cmdarg - @static_env.unextend - } - | kDEF fname - { - @def_level += 1 - @static_env.extend_static - @lexer.push_cmdarg - } - f_arglist bodystmt kEND - { - result = @builder.def_method(val[0], val[1], - val[3], val[4], val[5]) - - @lexer.pop_cmdarg - @static_env.unextend - @def_level -= 1 - } - | kDEF singleton dot_or_colon - { - @lexer.state = :expr_fname - } - fname - { - @def_level += 1 - @static_env.extend_static - @lexer.push_cmdarg - } - f_arglist bodystmt kEND - { - result = @builder.def_singleton(val[0], val[1], val[2], - val[4], val[6], val[7], val[8]) - - @lexer.pop_cmdarg - @static_env.unextend - @def_level -= 1 - } - | kBREAK - { - result = @builder.keyword_cmd(:break, val[0]) - } - | kNEXT - { - result = @builder.keyword_cmd(:next, val[0]) - } - | kREDO - { - result = @builder.keyword_cmd(:redo, val[0]) - } - | kRETRY - { - result = @builder.keyword_cmd(:retry, val[0]) - } - - primary_value: primary - - then: term - | kTHEN - | term kTHEN - { - result = val[1] - } - - do: term - | kDO_COND - - if_tail: opt_else - | kELSIF expr_value then compstmt if_tail - { - else_t, else_ = val[4] - result = [ val[0], - @builder.condition(val[0], val[1], val[2], - val[3], else_t, - else_, nil), - ] - } - - opt_else: none - | kELSE compstmt - { - result = val - } - - for_var: lhs - | mlhs - - f_marg: f_norm_arg - { - result = @builder.arg(val[0]) - } - | tLPAREN f_margs rparen - { - result = @builder.multi_lhs(val[0], val[1], val[2]) - } - - f_marg_list: f_marg - { - result = [ val[0] ] - } - | f_marg_list tCOMMA f_marg - { - result = val[0] << val[2] - } - - f_margs: f_marg_list - | f_marg_list tCOMMA tSTAR f_norm_arg - { - result = val[0]. - push(@builder.restarg(val[2], val[3])) - } - | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list - { - result = val[0]. - push(@builder.restarg(val[2], val[3])). - concat(val[5]) - } - | f_marg_list tCOMMA tSTAR - { - result = val[0]. - push(@builder.restarg(val[2])) - } - | f_marg_list tCOMMA tSTAR tCOMMA f_marg_list - { - result = val[0]. - push(@builder.restarg(val[2])). - concat(val[4]) - } - | tSTAR f_norm_arg - { - result = [ @builder.restarg(val[0], val[1]) ] - } - | tSTAR f_norm_arg tCOMMA f_marg_list - { - result = [ @builder.restarg(val[0], val[1]), - *val[3] ] - } - | tSTAR - { - result = [ @builder.restarg(val[0]) ] - } - | tSTAR tCOMMA f_marg_list - { - result = [ @builder.restarg(val[0]), - *val[2] ] - } - - block_args_tail: f_block_kwarg tCOMMA f_kwrest opt_f_block_arg - { - result = val[0].concat(val[2]).concat(val[3]) - } - | f_block_kwarg opt_f_block_arg - { - result = val[0].concat(val[1]) - } - | f_kwrest opt_f_block_arg - { - result = val[0].concat(val[1]) - } - | f_block_arg - { - result = [ val[0] ] - } - -opt_block_args_tail: - tCOMMA block_args_tail - { - result = val[1] - } - | # nothing - { - result = [] - } - - block_param: f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg opt_block_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[4]). - concat(val[5]) - } - | f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[4]). - concat(val[6]). - concat(val[7]) - } - | f_arg tCOMMA f_block_optarg opt_block_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[3]) - } - | f_arg tCOMMA f_block_optarg tCOMMA f_arg opt_block_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[4]). - concat(val[5]) - } - | f_arg tCOMMA f_rest_arg opt_block_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[3]) - } - | f_arg tCOMMA - | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[4]). - concat(val[5]) - } - | f_arg opt_block_args_tail - { - result = val[0].concat(val[1]) - } - | f_block_optarg tCOMMA f_rest_arg opt_block_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[3]) - } - | f_block_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[4]). - concat(val[5]) - } - | f_block_optarg opt_block_args_tail - { - result = val[0]. - concat(val[1]) - } - | f_block_optarg tCOMMA f_arg opt_block_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[3]) - } - | f_rest_arg opt_block_args_tail - { - result = val[0]. - concat(val[1]) - } - | f_rest_arg tCOMMA f_arg opt_block_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[3]) - } - | block_args_tail - - opt_block_param: # nothing - { - result = @builder.args(nil, [], nil) - } - | block_param_def - { - @lexer.state = :expr_value - } - - block_param_def: tPIPE opt_bv_decl tPIPE - { - result = @builder.args(val[0], val[1], val[2]) - } - | tOROP - { - result = @builder.args(val[0], [], val[0]) - } - | tPIPE block_param opt_bv_decl tPIPE - { - result = @builder.args(val[0], val[1].concat(val[2]), val[3]) - } - - opt_bv_decl: opt_nl - { - result = [] - } - | opt_nl tSEMI bv_decls opt_nl - { - result = val[2] - } - - bv_decls: bvar - { - result = [ val[0] ] - } - | bv_decls tCOMMA bvar - { - result = val[0] << val[2] - } - - bvar: tIDENTIFIER - { - result = @builder.shadowarg(val[0]) - } - | f_bad_arg - - lambda: { - @static_env.extend_dynamic - } - f_larglist - { - result = @lexer.cmdarg.dup - @lexer.cmdarg.clear - } - lambda_body - { - @lexer.cmdarg = val[2] - @lexer.cmdarg.lexpop - - result = [ val[1], val[3] ] - - @static_env.unextend - } - - f_larglist: tLPAREN2 f_args opt_bv_decl tRPAREN - { - result = @builder.args(val[0], val[1].concat(val[2]), val[3]) - } - | f_args - { - result = @builder.args(nil, val[0], nil) - } - - lambda_body: tLAMBEG compstmt tRCURLY - { - result = [ val[0], val[1], val[2] ] - } - | kDO_LAMBDA compstmt kEND - { - result = [ val[0], val[1], val[2] ] - } - - do_block: kDO_BLOCK - { - @static_env.extend_dynamic - } - opt_block_param compstmt kEND - { - result = [ val[0], val[2], val[3], val[4] ] - - @static_env.unextend - } - - block_call: command do_block - { - begin_t, block_args, body, end_t = val[1] - result = @builder.block(val[0], - begin_t, block_args, body, end_t) - } - | block_call dot_or_colon operation2 opt_paren_args - { - lparen_t, args, rparen_t = val[3] - result = @builder.call_method(val[0], val[1], val[2], - lparen_t, args, rparen_t) - } - | block_call dot_or_colon operation2 opt_paren_args brace_block - { - lparen_t, args, rparen_t = val[3] - method_call = @builder.call_method(val[0], val[1], val[2], - lparen_t, args, rparen_t) - - begin_t, args, body, end_t = val[4] - result = @builder.block(method_call, - begin_t, args, body, end_t) - } - | block_call dot_or_colon operation2 command_args do_block - { - method_call = @builder.call_method(val[0], val[1], val[2], - nil, val[3], nil) - - begin_t, args, body, end_t = val[4] - result = @builder.block(method_call, - begin_t, args, body, end_t) - } - - method_call: fcall paren_args - { - lparen_t, args, rparen_t = val[1] - result = @builder.call_method(nil, nil, val[0], - lparen_t, args, rparen_t) - } - | primary_value tDOT operation2 opt_paren_args - { - lparen_t, args, rparen_t = val[3] - result = @builder.call_method(val[0], val[1], val[2], - lparen_t, args, rparen_t) - } - | primary_value tCOLON2 operation2 paren_args - { - lparen_t, args, rparen_t = val[3] - result = @builder.call_method(val[0], val[1], val[2], - lparen_t, args, rparen_t) - } - | primary_value tCOLON2 operation3 - { - result = @builder.call_method(val[0], val[1], val[2]) - } - | primary_value tDOT paren_args - { - lparen_t, args, rparen_t = val[2] - result = @builder.call_method(val[0], val[1], nil, - lparen_t, args, rparen_t) - } - | primary_value tCOLON2 paren_args - { - lparen_t, args, rparen_t = val[2] - result = @builder.call_method(val[0], val[1], nil, - lparen_t, args, rparen_t) - } - | kSUPER paren_args - { - lparen_t, args, rparen_t = val[1] - result = @builder.keyword_cmd(:super, val[0], - lparen_t, args, rparen_t) - } - | kSUPER - { - result = @builder.keyword_cmd(:zsuper, val[0]) - } - | primary_value tLBRACK2 opt_call_args rbracket - { - result = @builder.index(val[0], val[1], val[2], val[3]) - } - - brace_block: tLCURLY - { - @static_env.extend_dynamic - } - opt_block_param compstmt tRCURLY - { - result = [ val[0], val[2], val[3], val[4] ] - - @static_env.unextend - } - | kDO - { - @static_env.extend_dynamic - } - opt_block_param compstmt kEND - { - result = [ val[0], val[2], val[3], val[4] ] - - @static_env.unextend - } - - case_body: kWHEN args then compstmt cases - { - result = [ @builder.when(val[0], val[1], val[2], val[3]), - *val[4] ] - } - - cases: opt_else - { - result = [ val[0] ] - } - | case_body - - opt_rescue: kRESCUE exc_list exc_var then compstmt opt_rescue - { - assoc_t, exc_var = val[2] - - if val[1] - exc_list = @builder.array(nil, val[1], nil) - end - - result = [ @builder.rescue_body(val[0], - exc_list, assoc_t, exc_var, - val[3], val[4]), - *val[5] ] - } - | - { - result = [] - } - - exc_list: arg_value - { - result = [ val[0] ] - } - | mrhs - | none - - exc_var: tASSOC lhs - { - result = [ val[0], val[1] ] - } - | none - - opt_ensure: kENSURE compstmt - { - result = [ val[0], val[1] ] - } - | none - - literal: numeric - | symbol - | dsym - - strings: string - { - result = @builder.string_compose(nil, val[0], nil) - } - - string: string1 - { - result = [ val[0] ] - } - | string string1 - { - result = val[0] << val[1] - } - - string1: tSTRING_BEG string_contents tSTRING_END - { - result = @builder.string_compose(val[0], val[1], val[2]) - } - | tSTRING - { - result = @builder.string(val[0]) - } - | tCHARACTER - { - result = @builder.character(val[0]) - } - - xstring: tXSTRING_BEG xstring_contents tSTRING_END - { - result = @builder.xstring_compose(val[0], val[1], val[2]) - } - - regexp: tREGEXP_BEG regexp_contents tSTRING_END tREGEXP_OPT - { - opts = @builder.regexp_options(val[3]) - result = @builder.regexp_compose(val[0], val[1], val[2], opts) - } - - words: tWORDS_BEG word_list tSTRING_END - { - result = @builder.words_compose(val[0], val[1], val[2]) - } - - word_list: # nothing - { - result = [] - } - | word_list word tSPACE - { - result = val[0] << @builder.word(val[1]) - } - - word: string_content - { - result = [ val[0] ] - } - | word string_content - { - result = val[0] << val[1] - } - - symbols: tSYMBOLS_BEG symbol_list tSTRING_END - { - result = @builder.symbols_compose(val[0], val[1], val[2]) - } - - symbol_list: # nothing - { - result = [] - } - | symbol_list word tSPACE - { - result = val[0] << @builder.word(val[1]) - } - - qwords: tQWORDS_BEG qword_list tSTRING_END - { - result = @builder.words_compose(val[0], val[1], val[2]) - } - - qsymbols: tQSYMBOLS_BEG qsym_list tSTRING_END - { - result = @builder.symbols_compose(val[0], val[1], val[2]) - } - - qword_list: # nothing - { - result = [] - } - | qword_list tSTRING_CONTENT tSPACE - { - result = val[0] << @builder.string_internal(val[1]) - } - - qsym_list: # nothing - { - result = [] - } - | qsym_list tSTRING_CONTENT tSPACE - { - result = val[0] << @builder.symbol_internal(val[1]) - } - - string_contents: # nothing - { - result = [] - } - | string_contents string_content - { - result = val[0] << val[1] - } - -xstring_contents: # nothing - { - result = [] - } - | xstring_contents string_content - { - result = val[0] << val[1] - } - -regexp_contents: # nothing - { - result = [] - } - | regexp_contents string_content - { - result = val[0] << val[1] - } - - string_content: tSTRING_CONTENT - { - result = @builder.string_internal(val[0]) - } - | tSTRING_DVAR string_dvar - { - result = val[1] - } - | tSTRING_DBEG - { - @lexer.cond.push(false) - @lexer.cmdarg.push(false) - } - compstmt tSTRING_DEND - { - @lexer.cond.lexpop - @lexer.cmdarg.lexpop - - result = @builder.begin(val[0], val[2], val[3]) - } - - string_dvar: tGVAR - { - result = @builder.gvar(val[0]) - } - | tIVAR - { - result = @builder.ivar(val[0]) - } - | tCVAR - { - result = @builder.cvar(val[0]) - } - | backref - - - symbol: tSYMBOL - { - result = @builder.symbol(val[0]) - } - - dsym: tSYMBEG xstring_contents tSTRING_END - { - result = @builder.symbol_compose(val[0], val[1], val[2]) - } - - numeric: simple_numeric - { - result = val[0] - } - | tUMINUS_NUM simple_numeric =tLOWEST - { - result = @builder.negate(val[0], val[1]) - } - - simple_numeric: tINTEGER - { - result = @builder.integer(val[0]) - } - | tFLOAT - { - result = @builder.float(val[0]) - } - | tRATIONAL - { - result = @builder.rational(val[0]) - } - | tIMAGINARY - { - result = @builder.complex(val[0]) - } - - user_variable: tIDENTIFIER - { - result = @builder.ident(val[0]) - } - | tIVAR - { - result = @builder.ivar(val[0]) - } - | tGVAR - { - result = @builder.gvar(val[0]) - } - | tCONSTANT - { - result = @builder.const(val[0]) - } - | tCVAR - { - result = @builder.cvar(val[0]) - } - -keyword_variable: kNIL - { - result = @builder.nil(val[0]) - } - | kSELF - { - result = @builder.self(val[0]) - } - | kTRUE - { - result = @builder.true(val[0]) - } - | kFALSE - { - result = @builder.false(val[0]) - } - | k__FILE__ - { - result = @builder.__FILE__(val[0]) - } - | k__LINE__ - { - result = @builder.__LINE__(val[0]) - } - | k__ENCODING__ - { - result = @builder.__ENCODING__(val[0]) - } - - var_ref: user_variable - { - result = @builder.accessible(val[0]) - } - | keyword_variable - { - result = @builder.accessible(val[0]) - } - - var_lhs: user_variable - { - result = @builder.assignable(val[0]) - } - | keyword_variable - { - result = @builder.assignable(val[0]) - } - - backref: tNTH_REF - { - result = @builder.nth_ref(val[0]) - } - | tBACK_REF - { - result = @builder.back_ref(val[0]) - } - - superclass: term - { - result = nil - } - | tLT - { - @lexer.state = :expr_value - } - expr_value term - { - result = [ val[0], val[2] ] - } - | error term - { - yyerrok - result = nil - } - - f_arglist: tLPAREN2 f_args rparen - { - result = @builder.args(val[0], val[1], val[2]) - - @lexer.state = :expr_value - } - | { - result = @lexer.in_kwarg - @lexer.in_kwarg = true - } - f_args term - { - @lexer.in_kwarg = val[0] - result = @builder.args(nil, val[1], nil) - } - - - args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg - { - result = val[0].concat(val[2]).concat(val[3]) - } - | f_kwarg opt_f_block_arg - { - result = val[0].concat(val[1]) - } - | f_kwrest opt_f_block_arg - { - result = val[0].concat(val[1]) - } - | f_block_arg - { - result = [ val[0] ] - } - - opt_args_tail: tCOMMA args_tail - { - result = val[1] - } - | # nothing - { - result = [] - } - - f_args: f_arg tCOMMA f_optarg tCOMMA f_rest_arg opt_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[4]). - concat(val[5]) - } - | f_arg tCOMMA f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[4]). - concat(val[6]). - concat(val[7]) - } - | f_arg tCOMMA f_optarg opt_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[3]) - } - | f_arg tCOMMA f_optarg tCOMMA f_arg opt_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[4]). - concat(val[5]) - } - | f_arg tCOMMA f_rest_arg opt_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[3]) - } - | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[4]). - concat(val[5]) - } - | f_arg opt_args_tail - { - result = val[0]. - concat(val[1]) - } - | f_optarg tCOMMA f_rest_arg opt_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[3]) - } - | f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[4]). - concat(val[5]) - } - | f_optarg opt_args_tail - { - result = val[0]. - concat(val[1]) - } - | f_optarg tCOMMA f_arg opt_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[3]) - } - | f_rest_arg opt_args_tail - { - result = val[0]. - concat(val[1]) - } - | f_rest_arg tCOMMA f_arg opt_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[3]) - } - | args_tail - { - result = val[0] - } - | # nothing - { - result = [] - } - - f_bad_arg: tCONSTANT - { - diagnostic :error, :argument_const, nil, val[0] - } - | tIVAR - { - diagnostic :error, :argument_ivar, nil, val[0] - } - | tGVAR - { - diagnostic :error, :argument_gvar, nil, val[0] - } - | tCVAR - { - diagnostic :error, :argument_cvar, nil, val[0] - } - - f_norm_arg: f_bad_arg - | tIDENTIFIER - { - @static_env.declare val[0][0] - - result = val[0] - } - - f_arg_item: f_norm_arg - { - result = @builder.arg(val[0]) - } - | tLPAREN f_margs rparen - { - result = @builder.multi_lhs(val[0], val[1], val[2]) - } - - f_arg: f_arg_item - { - result = [ val[0] ] - } - | f_arg tCOMMA f_arg_item - { - result = val[0] << val[2] - } - - f_label: tLABEL - { - check_kwarg_name(val[0]) - - @static_env.declare val[0][0] - - result = val[0] - } - - f_kw: f_label arg_value - { - result = @builder.kwoptarg(val[0], val[1]) - } - | f_label - { - result = @builder.kwarg(val[0]) - } - - f_block_kw: f_label primary_value - { - result = @builder.kwoptarg(val[0], val[1]) - } - | f_label - { - result = @builder.kwarg(val[0]) - } - - f_block_kwarg: f_block_kw - { - result = [ val[0] ] - } - | f_block_kwarg tCOMMA f_block_kw - { - result = val[0] << val[2] - } - - f_kwarg: f_kw - { - result = [ val[0] ] - } - | f_kwarg tCOMMA f_kw - { - result = val[0] << val[2] - } - - kwrest_mark: tPOW | tDSTAR - - f_kwrest: kwrest_mark tIDENTIFIER - { - @static_env.declare val[1][0] - - result = [ @builder.kwrestarg(val[0], val[1]) ] - } - | kwrest_mark - { - result = [ @builder.kwrestarg(val[0]) ] - } - - f_opt: f_norm_arg tEQL arg_value - { - result = @builder.optarg(val[0], val[1], val[2]) - } - - f_block_opt: f_norm_arg tEQL primary_value - { - result = @builder.optarg(val[0], val[1], val[2]) - } - - f_block_optarg: f_block_opt - { - result = [ val[0] ] - } - | f_block_optarg tCOMMA f_block_opt - { - result = val[0] << val[2] - } - - f_optarg: f_opt - { - result = [ val[0] ] - } - | f_optarg tCOMMA f_opt - { - result = val[0] << val[2] - } - - restarg_mark: tSTAR2 | tSTAR - - f_rest_arg: restarg_mark tIDENTIFIER - { - @static_env.declare val[1][0] - - result = [ @builder.restarg(val[0], val[1]) ] - } - | restarg_mark - { - result = [ @builder.restarg(val[0]) ] - } - - blkarg_mark: tAMPER2 | tAMPER - - f_block_arg: blkarg_mark tIDENTIFIER - { - @static_env.declare val[1][0] - - result = @builder.blockarg(val[0], val[1]) - } - - opt_f_block_arg: tCOMMA f_block_arg - { - result = [ val[1] ] - } - | - { - result = [] - } - - singleton: var_ref - | tLPAREN2 expr rparen - { - result = val[1] - } - - assoc_list: # nothing - { - result = [] - } - | assocs trailer - - assocs: assoc - { - result = [ val[0] ] - } - | assocs tCOMMA assoc - { - result = val[0] << val[2] - } - - assoc: arg_value tASSOC arg_value - { - result = @builder.pair(val[0], val[1], val[2]) - } - | tLABEL arg_value - { - result = @builder.pair_keyword(val[0], val[1]) - } - | tDSTAR arg_value - { - result = @builder.kwsplat(val[0], val[1]) - } - - operation: tIDENTIFIER | tCONSTANT | tFID - operation2: tIDENTIFIER | tCONSTANT | tFID | op - operation3: tIDENTIFIER | tFID | op - dot_or_colon: tDOT | tCOLON2 - opt_terms: | terms - opt_nl: | tNL - rparen: opt_nl tRPAREN - { - result = val[1] - } - rbracket: opt_nl tRBRACK - { - result = val[1] - } - trailer: | tNL | tCOMMA - - term: tSEMI - { - yyerrok - } - | tNL - - terms: term - | terms tSEMI - - none: # nothing - { - result = nil - } -end - ----- header - -require 'parser' - -Parser.check_for_encoding_support - ----- inner - - def version - 21 - end - - def default_encoding - Encoding::UTF_8 - end diff --git a/test/racc/assets/ruby22.y b/test/racc/assets/ruby22.y deleted file mode 100644 index 751c0e866b..0000000000 --- a/test/racc/assets/ruby22.y +++ /dev/null @@ -1,2381 +0,0 @@ -# Copyright (c) 2013 Peter Zotov <whitequark@whitequark.org> -# -# Parts of the source are derived from ruby_parser: -# Copyright (c) Ryan Davis, seattle.rb -# -# MIT License -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -class Parser::Ruby22 - -token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS - kTHEN kELSIF kELSE kCASE kWHEN kWHILE kUNTIL kFOR kBREAK kNEXT - kREDO kRETRY kIN kDO kDO_COND kDO_BLOCK kDO_LAMBDA kRETURN kYIELD kSUPER - kSELF kNIL kTRUE kFALSE kAND kOR kNOT kIF_MOD kUNLESS_MOD kWHILE_MOD - kUNTIL_MOD kRESCUE_MOD kALIAS kDEFINED klBEGIN klEND k__LINE__ - k__FILE__ k__ENCODING__ tIDENTIFIER tFID tGVAR tIVAR tCONSTANT - tLABEL tCVAR tNTH_REF tBACK_REF tSTRING_CONTENT tINTEGER tFLOAT - tREGEXP_END tUPLUS tUMINUS tUMINUS_NUM tPOW tCMP tEQ tEQQ tNEQ - tGEQ tLEQ tANDOP tOROP tMATCH tNMATCH tDOT tDOT2 tDOT3 tAREF - tASET tLSHFT tRSHFT tCOLON2 tCOLON3 tOP_ASGN tASSOC tLPAREN - tLPAREN2 tRPAREN tLPAREN_ARG tLBRACK tLBRACK2 tRBRACK tLBRACE - tLBRACE_ARG tSTAR tSTAR2 tAMPER tAMPER2 tTILDE tPERCENT tDIVIDE - tDSTAR tPLUS tMINUS tLT tGT tPIPE tBANG tCARET tLCURLY tRCURLY - tBACK_REF2 tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG tREGEXP_OPT - tWORDS_BEG tQWORDS_BEG tSYMBOLS_BEG tQSYMBOLS_BEG tSTRING_DBEG - tSTRING_DVAR tSTRING_END tSTRING_DEND tSTRING tSYMBOL - tNL tEH tCOLON tCOMMA tSPACE tSEMI tLAMBDA tLAMBEG tCHARACTER - tRATIONAL tIMAGINARY tLABEL_END - -prechigh - right tBANG tTILDE tUPLUS - right tPOW - right tUMINUS_NUM tUMINUS - left tSTAR2 tDIVIDE tPERCENT - left tPLUS tMINUS - left tLSHFT tRSHFT - left tAMPER2 - left tPIPE tCARET - left tGT tGEQ tLT tLEQ - nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH - left tANDOP - left tOROP - nonassoc tDOT2 tDOT3 - right tEH tCOLON - left kRESCUE_MOD - right tEQL tOP_ASGN - nonassoc kDEFINED - right kNOT - left kOR kAND - nonassoc kIF_MOD kUNLESS_MOD kWHILE_MOD kUNTIL_MOD - nonassoc tLBRACE_ARG - nonassoc tLOWEST -preclow - -rule - - program: top_compstmt - - top_compstmt: top_stmts opt_terms - { - result = @builder.compstmt(val[0]) - } - - top_stmts: # nothing - { - result = [] - } - | top_stmt - { - result = [ val[0] ] - } - | top_stmts terms top_stmt - { - result = val[0] << val[2] - } - | error top_stmt - { - result = [ val[1] ] - } - - top_stmt: stmt - | klBEGIN tLCURLY top_compstmt tRCURLY - { - result = @builder.preexe(val[0], val[1], val[2], val[3]) - } - - bodystmt: compstmt opt_rescue opt_else opt_ensure - { - rescue_bodies = val[1] - else_t, else_ = val[2] - ensure_t, ensure_ = val[3] - - if rescue_bodies.empty? && !else_.nil? - diagnostic :warning, :useless_else, nil, else_t - end - - result = @builder.begin_body(val[0], - rescue_bodies, - else_t, else_, - ensure_t, ensure_) - } - - compstmt: stmts opt_terms - { - result = @builder.compstmt(val[0]) - } - - stmts: # nothing - { - result = [] - } - | stmt_or_begin - { - result = [ val[0] ] - } - | stmts terms stmt_or_begin - { - result = val[0] << val[2] - } - | error stmt - { - result = [ val[1] ] - } - - stmt_or_begin: stmt - | klBEGIN tLCURLY top_compstmt tRCURLY - { - diagnostic :error, :begin_in_method, nil, val[0] - } - - stmt: kALIAS fitem - { - @lexer.state = :expr_fname - } - fitem - { - result = @builder.alias(val[0], val[1], val[3]) - } - | kALIAS tGVAR tGVAR - { - result = @builder.alias(val[0], - @builder.gvar(val[1]), - @builder.gvar(val[2])) - } - | kALIAS tGVAR tBACK_REF - { - result = @builder.alias(val[0], - @builder.gvar(val[1]), - @builder.back_ref(val[2])) - } - | kALIAS tGVAR tNTH_REF - { - diagnostic :error, :nth_ref_alias, nil, val[2] - } - | kUNDEF undef_list - { - result = @builder.undef_method(val[0], val[1]) - } - | stmt kIF_MOD expr_value - { - result = @builder.condition_mod(val[0], nil, - val[1], val[2]) - } - | stmt kUNLESS_MOD expr_value - { - result = @builder.condition_mod(nil, val[0], - val[1], val[2]) - } - | stmt kWHILE_MOD expr_value - { - result = @builder.loop_mod(:while, val[0], val[1], val[2]) - } - | stmt kUNTIL_MOD expr_value - { - result = @builder.loop_mod(:until, val[0], val[1], val[2]) - } - | stmt kRESCUE_MOD stmt - { - rescue_body = @builder.rescue_body(val[1], - nil, nil, nil, - nil, val[2]) - - result = @builder.begin_body(val[0], [ rescue_body ]) - } - | klEND tLCURLY compstmt tRCURLY - { - result = @builder.postexe(val[0], val[1], val[2], val[3]) - } - | command_asgn - | mlhs tEQL command_call - { - result = @builder.multi_assign(val[0], val[1], val[2]) - } - | var_lhs tOP_ASGN command_call - { - result = @builder.op_assign(val[0], val[1], val[2]) - } - | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN command_call - { - result = @builder.op_assign( - @builder.index( - val[0], val[1], val[2], val[3]), - val[4], val[5]) - } - | primary_value tDOT tIDENTIFIER tOP_ASGN command_call - { - result = @builder.op_assign( - @builder.call_method( - val[0], val[1], val[2]), - val[3], val[4]) - } - | primary_value tDOT tCONSTANT tOP_ASGN command_call - { - result = @builder.op_assign( - @builder.call_method( - val[0], val[1], val[2]), - val[3], val[4]) - } - | primary_value tCOLON2 tCONSTANT tOP_ASGN command_call - { - result = @builder.op_assign( - @builder.call_method( - val[0], val[1], val[2]), - val[3], val[4]) - } - | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_call - { - result = @builder.op_assign( - @builder.call_method( - val[0], val[1], val[2]), - val[3], val[4]) - } - | backref tOP_ASGN command_call - { - @builder.op_assign(val[0], val[1], val[2]) - } - | lhs tEQL mrhs - { - result = @builder.assign(val[0], val[1], - @builder.array(nil, val[2], nil)) - } - | mlhs tEQL mrhs_arg - { - result = @builder.multi_assign(val[0], val[1], val[2]) - } - | expr - - command_asgn: lhs tEQL command_call - { - result = @builder.assign(val[0], val[1], val[2]) - } - | lhs tEQL command_asgn - { - result = @builder.assign(val[0], val[1], val[2]) - } - - expr: command_call - | expr kAND expr - { - result = @builder.logical_op(:and, val[0], val[1], val[2]) - } - | expr kOR expr - { - result = @builder.logical_op(:or, val[0], val[1], val[2]) - } - | kNOT opt_nl expr - { - result = @builder.not_op(val[0], nil, val[2], nil) - } - | tBANG command_call - { - result = @builder.not_op(val[0], nil, val[1], nil) - } - | arg - - expr_value: expr - - command_call: command - | block_command - - block_command: block_call - | block_call dot_or_colon operation2 command_args - { - result = @builder.call_method(val[0], val[1], val[2], - nil, val[3], nil) - } - - cmd_brace_block: tLBRACE_ARG - { - @static_env.extend_dynamic - } - opt_block_param compstmt tRCURLY - { - result = [ val[0], val[2], val[3], val[4] ] - - @static_env.unextend - } - - fcall: operation - - command: fcall command_args =tLOWEST - { - result = @builder.call_method(nil, nil, val[0], - nil, val[1], nil) - } - | fcall command_args cmd_brace_block - { - method_call = @builder.call_method(nil, nil, val[0], - nil, val[1], nil) - - begin_t, args, body, end_t = val[2] - result = @builder.block(method_call, - begin_t, args, body, end_t) - } - | primary_value tDOT operation2 command_args =tLOWEST - { - result = @builder.call_method(val[0], val[1], val[2], - nil, val[3], nil) - } - | primary_value tDOT operation2 command_args cmd_brace_block - { - method_call = @builder.call_method(val[0], val[1], val[2], - nil, val[3], nil) - - begin_t, args, body, end_t = val[4] - result = @builder.block(method_call, - begin_t, args, body, end_t) - } - | primary_value tCOLON2 operation2 command_args =tLOWEST - { - result = @builder.call_method(val[0], val[1], val[2], - nil, val[3], nil) - } - | primary_value tCOLON2 operation2 command_args cmd_brace_block - { - method_call = @builder.call_method(val[0], val[1], val[2], - nil, val[3], nil) - - begin_t, args, body, end_t = val[4] - result = @builder.block(method_call, - begin_t, args, body, end_t) - } - | kSUPER command_args - { - result = @builder.keyword_cmd(:super, val[0], - nil, val[1], nil) - } - | kYIELD command_args - { - result = @builder.keyword_cmd(:yield, val[0], - nil, val[1], nil) - } - | kRETURN call_args - { - result = @builder.keyword_cmd(:return, val[0], - nil, val[1], nil) - } - | kBREAK call_args - { - result = @builder.keyword_cmd(:break, val[0], - nil, val[1], nil) - } - | kNEXT call_args - { - result = @builder.keyword_cmd(:next, val[0], - nil, val[1], nil) - } - - mlhs: mlhs_basic - { - result = @builder.multi_lhs(nil, val[0], nil) - } - | tLPAREN mlhs_inner rparen - { - result = @builder.begin(val[0], val[1], val[2]) - } - - mlhs_inner: mlhs_basic - { - result = @builder.multi_lhs(nil, val[0], nil) - } - | tLPAREN mlhs_inner rparen - { - result = @builder.multi_lhs(val[0], val[1], val[2]) - } - - mlhs_basic: mlhs_head - | mlhs_head mlhs_item - { - result = val[0]. - push(val[1]) - } - | mlhs_head tSTAR mlhs_node - { - result = val[0]. - push(@builder.splat(val[1], val[2])) - } - | mlhs_head tSTAR mlhs_node tCOMMA mlhs_post - { - result = val[0]. - push(@builder.splat(val[1], val[2])). - concat(val[4]) - } - | mlhs_head tSTAR - { - result = val[0]. - push(@builder.splat(val[1])) - } - | mlhs_head tSTAR tCOMMA mlhs_post - { - result = val[0]. - push(@builder.splat(val[1])). - concat(val[3]) - } - | tSTAR mlhs_node - { - result = [ @builder.splat(val[0], val[1]) ] - } - | tSTAR mlhs_node tCOMMA mlhs_post - { - result = [ @builder.splat(val[0], val[1]), - *val[3] ] - } - | tSTAR - { - result = [ @builder.splat(val[0]) ] - } - | tSTAR tCOMMA mlhs_post - { - result = [ @builder.splat(val[0]), - *val[2] ] - } - - mlhs_item: mlhs_node - | tLPAREN mlhs_inner rparen - { - result = @builder.begin(val[0], val[1], val[2]) - } - - mlhs_head: mlhs_item tCOMMA - { - result = [ val[0] ] - } - | mlhs_head mlhs_item tCOMMA - { - result = val[0] << val[1] - } - - mlhs_post: mlhs_item - { - result = [ val[0] ] - } - | mlhs_post tCOMMA mlhs_item - { - result = val[0] << val[2] - } - - mlhs_node: user_variable - { - result = @builder.assignable(val[0]) - } - | keyword_variable - { - result = @builder.assignable(val[0]) - } - | primary_value tLBRACK2 opt_call_args rbracket - { - result = @builder.index_asgn(val[0], val[1], val[2], val[3]) - } - | primary_value tDOT tIDENTIFIER - { - result = @builder.attr_asgn(val[0], val[1], val[2]) - } - | primary_value tCOLON2 tIDENTIFIER - { - result = @builder.attr_asgn(val[0], val[1], val[2]) - } - | primary_value tDOT tCONSTANT - { - result = @builder.attr_asgn(val[0], val[1], val[2]) - } - | primary_value tCOLON2 tCONSTANT - { - result = @builder.assignable( - @builder.const_fetch(val[0], val[1], val[2])) - } - | tCOLON3 tCONSTANT - { - result = @builder.assignable( - @builder.const_global(val[0], val[1])) - } - | backref - { - result = @builder.assignable(val[0]) - } - - lhs: user_variable - { - result = @builder.assignable(val[0]) - } - | keyword_variable - { - result = @builder.assignable(val[0]) - } - | primary_value tLBRACK2 opt_call_args rbracket - { - result = @builder.index_asgn(val[0], val[1], val[2], val[3]) - } - | primary_value tDOT tIDENTIFIER - { - result = @builder.attr_asgn(val[0], val[1], val[2]) - } - | primary_value tCOLON2 tIDENTIFIER - { - result = @builder.attr_asgn(val[0], val[1], val[2]) - } - | primary_value tDOT tCONSTANT - { - result = @builder.attr_asgn(val[0], val[1], val[2]) - } - | primary_value tCOLON2 tCONSTANT - { - result = @builder.assignable( - @builder.const_fetch(val[0], val[1], val[2])) - } - | tCOLON3 tCONSTANT - { - result = @builder.assignable( - @builder.const_global(val[0], val[1])) - } - | backref - { - result = @builder.assignable(val[0]) - } - - cname: tIDENTIFIER - { - diagnostic :error, :module_name_const, nil, val[0] - } - | tCONSTANT - - cpath: tCOLON3 cname - { - result = @builder.const_global(val[0], val[1]) - } - | cname - { - result = @builder.const(val[0]) - } - | primary_value tCOLON2 cname - { - result = @builder.const_fetch(val[0], val[1], val[2]) - } - - fname: tIDENTIFIER | tCONSTANT | tFID - | op - | reswords - - fsym: fname - { - result = @builder.symbol(val[0]) - } - | symbol - - fitem: fsym - | dsym - - undef_list: fitem - { - result = [ val[0] ] - } - | undef_list tCOMMA - { - @lexer.state = :expr_fname - } - fitem - { - result = val[0] << val[3] - } - - op: tPIPE | tCARET | tAMPER2 | tCMP | tEQ | tEQQ - | tMATCH | tNMATCH | tGT | tGEQ | tLT | tLEQ - | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2 - | tSTAR | tDIVIDE | tPERCENT | tPOW | tBANG | tTILDE - | tUPLUS | tUMINUS | tAREF | tASET | tDSTAR | tBACK_REF2 - - reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND - | kALIAS | kAND | kBEGIN | kBREAK | kCASE - | kCLASS | kDEF | kDEFINED | kDO | kELSE - | kELSIF | kEND | kENSURE | kFALSE | kFOR - | kIN | kMODULE | kNEXT | kNIL | kNOT - | kOR | kREDO | kRESCUE | kRETRY | kRETURN - | kSELF | kSUPER | kTHEN | kTRUE | kUNDEF - | kWHEN | kYIELD | kIF | kUNLESS | kWHILE - | kUNTIL - - arg: lhs tEQL arg - { - result = @builder.assign(val[0], val[1], val[2]) - } - | lhs tEQL arg kRESCUE_MOD arg - { - rescue_body = @builder.rescue_body(val[3], - nil, nil, nil, - nil, val[4]) - - rescue_ = @builder.begin_body(val[2], [ rescue_body ]) - - result = @builder.assign(val[0], val[1], rescue_) - } - | var_lhs tOP_ASGN arg - { - result = @builder.op_assign(val[0], val[1], val[2]) - } - | var_lhs tOP_ASGN arg kRESCUE_MOD arg - { - rescue_body = @builder.rescue_body(val[3], - nil, nil, nil, - nil, val[4]) - - rescue_ = @builder.begin_body(val[2], [ rescue_body ]) - - result = @builder.op_assign(val[0], val[1], rescue_) - } - | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN arg - { - result = @builder.op_assign( - @builder.index( - val[0], val[1], val[2], val[3]), - val[4], val[5]) - } - | primary_value tDOT tIDENTIFIER tOP_ASGN arg - { - result = @builder.op_assign( - @builder.call_method( - val[0], val[1], val[2]), - val[3], val[4]) - } - | primary_value tDOT tCONSTANT tOP_ASGN arg - { - result = @builder.op_assign( - @builder.call_method( - val[0], val[1], val[2]), - val[3], val[4]) - } - | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg - { - result = @builder.op_assign( - @builder.call_method( - val[0], val[1], val[2]), - val[3], val[4]) - } - | primary_value tCOLON2 tCONSTANT tOP_ASGN arg - { - const = @builder.const_op_assignable( - @builder.const_fetch(val[0], val[1], val[2])) - result = @builder.op_assign(const, val[3], val[4]) - } - | tCOLON3 tCONSTANT tOP_ASGN arg - { - const = @builder.const_op_assignable( - @builder.const_global(val[0], val[1])) - result = @builder.op_assign(const, val[2], val[3]) - } - | backref tOP_ASGN arg - { - result = @builder.op_assign(val[0], val[1], val[2]) - } - | arg tDOT2 arg - { - result = @builder.range_inclusive(val[0], val[1], val[2]) - } - | arg tDOT3 arg - { - result = @builder.range_exclusive(val[0], val[1], val[2]) - } - | arg tPLUS arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tMINUS arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tSTAR2 arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tDIVIDE arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tPERCENT arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tPOW arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | tUMINUS_NUM simple_numeric tPOW arg - { - result = @builder.unary_op(val[0], - @builder.binary_op( - val[1], val[2], val[3])) - } - | tUPLUS arg - { - result = @builder.unary_op(val[0], val[1]) - } - | tUMINUS arg - { - result = @builder.unary_op(val[0], val[1]) - } - | arg tPIPE arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tCARET arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tAMPER2 arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tCMP arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tGT arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tGEQ arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tLT arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tLEQ arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tEQ arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tEQQ arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tNEQ arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tMATCH arg - { - result = @builder.match_op(val[0], val[1], val[2]) - } - | arg tNMATCH arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | tBANG arg - { - result = @builder.not_op(val[0], nil, val[1], nil) - } - | tTILDE arg - { - result = @builder.unary_op(val[0], val[1]) - } - | arg tLSHFT arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tRSHFT arg - { - result = @builder.binary_op(val[0], val[1], val[2]) - } - | arg tANDOP arg - { - result = @builder.logical_op(:and, val[0], val[1], val[2]) - } - | arg tOROP arg - { - result = @builder.logical_op(:or, val[0], val[1], val[2]) - } - | kDEFINED opt_nl arg - { - result = @builder.keyword_cmd(:defined?, val[0], nil, [ val[2] ], nil) - } - - # Note: MRI eventually came to rely on disambiguation based on - # the lexer state, but it is too contrived with the Ragel lexer, - # so we kept this approach. See ruby/ruby@b0c03f63e5 for - # the initial commit, and ruby/ruby@23352f62a for MRI revert, - # which we decided not to track. - | arg tEH - { - @lexer.push_cond - @lexer.cond.push(true) - } - arg opt_nl tCOLON - { - @lexer.pop_cond - } - arg - { - result = @builder.ternary(val[0], val[1], - val[3], val[5], val[7]) - } - | primary - - arg_value: arg - - aref_args: none - | args trailer - | args tCOMMA assocs trailer - { - result = val[0] << @builder.associate(nil, val[2], nil) - } - | assocs trailer - { - result = [ @builder.associate(nil, val[0], nil) ] - } - - paren_args: tLPAREN2 opt_call_args rparen - { - result = val - } - - opt_paren_args: # nothing - { - result = [ nil, [], nil ] - } - | paren_args - - opt_call_args: # nothing - { - result = [] - } - | call_args - | args tCOMMA - | args tCOMMA assocs tCOMMA - { - result = val[0] << @builder.associate(nil, val[2], nil) - } - | assocs tCOMMA - { - result = [ @builder.associate(nil, val[0], nil) ] - } - - call_args: command - { - result = [ val[0] ] - } - | args opt_block_arg - { - result = val[0].concat(val[1]) - } - | assocs opt_block_arg - { - result = [ @builder.associate(nil, val[0], nil) ] - result.concat(val[1]) - } - | args tCOMMA assocs opt_block_arg - { - assocs = @builder.associate(nil, val[2], nil) - result = val[0] << assocs - result.concat(val[3]) - } - | block_arg - { - result = [ val[0] ] - } - - command_args: { - result = @lexer.cmdarg.dup - @lexer.cmdarg.push(true) - } - call_args - { - @lexer.cmdarg = val[0] - - result = val[1] - } - - block_arg: tAMPER arg_value - { - result = @builder.block_pass(val[0], val[1]) - } - - opt_block_arg: tCOMMA block_arg - { - result = [ val[1] ] - } - | # nothing - { - result = [] - } - - args: arg_value - { - result = [ val[0] ] - } - | tSTAR arg_value - { - result = [ @builder.splat(val[0], val[1]) ] - } - | args tCOMMA arg_value - { - result = val[0] << val[2] - } - | args tCOMMA tSTAR arg_value - { - result = val[0] << @builder.splat(val[2], val[3]) - } - - mrhs_arg: mrhs - { - result = @builder.array(nil, val[0], nil) - } - | arg_value - - mrhs: args tCOMMA arg_value - { - result = val[0] << val[2] - } - | args tCOMMA tSTAR arg_value - { - result = val[0] << @builder.splat(val[2], val[3]) - } - | tSTAR arg_value - { - result = [ @builder.splat(val[0], val[1]) ] - } - - primary: literal - | strings - | xstring - | regexp - | words - | qwords - | symbols - | qsymbols - | var_ref - | backref - | tFID - { - result = @builder.call_method(nil, nil, val[0]) - } - | kBEGIN - { - result = @lexer.cmdarg.dup - @lexer.cmdarg.clear - } - bodystmt kEND - { - @lexer.cmdarg = val[1] - - result = @builder.begin_keyword(val[0], val[2], val[3]) - } - | tLPAREN_ARG - { - result = @lexer.cmdarg.dup - @lexer.cmdarg.clear - } - expr - { - @lexer.state = :expr_endarg - } - opt_nl tRPAREN - { - @lexer.cmdarg = val[1] - - result = @builder.begin(val[0], val[2], val[5]) - } - | tLPAREN_ARG - { - @lexer.state = :expr_endarg - } - opt_nl tRPAREN - { - result = @builder.begin(val[0], nil, val[3]) - } - | tLPAREN compstmt tRPAREN - { - result = @builder.begin(val[0], val[1], val[2]) - } - | primary_value tCOLON2 tCONSTANT - { - result = @builder.const_fetch(val[0], val[1], val[2]) - } - | tCOLON3 tCONSTANT - { - result = @builder.const_global(val[0], val[1]) - } - | tLBRACK aref_args tRBRACK - { - result = @builder.array(val[0], val[1], val[2]) - } - | tLBRACE assoc_list tRCURLY - { - result = @builder.associate(val[0], val[1], val[2]) - } - | kRETURN - { - result = @builder.keyword_cmd(:return, val[0]) - } - | kYIELD tLPAREN2 call_args rparen - { - result = @builder.keyword_cmd(:yield, val[0], val[1], val[2], val[3]) - } - | kYIELD tLPAREN2 rparen - { - result = @builder.keyword_cmd(:yield, val[0], val[1], [], val[2]) - } - | kYIELD - { - result = @builder.keyword_cmd(:yield, val[0]) - } - | kDEFINED opt_nl tLPAREN2 expr rparen - { - result = @builder.keyword_cmd(:defined?, val[0], - val[2], [ val[3] ], val[4]) - } - | kNOT tLPAREN2 expr rparen - { - result = @builder.not_op(val[0], val[1], val[2], val[3]) - } - | kNOT tLPAREN2 rparen - { - result = @builder.not_op(val[0], val[1], nil, val[2]) - } - | fcall brace_block - { - method_call = @builder.call_method(nil, nil, val[0]) - - begin_t, args, body, end_t = val[1] - result = @builder.block(method_call, - begin_t, args, body, end_t) - } - | method_call - | method_call brace_block - { - begin_t, args, body, end_t = val[1] - result = @builder.block(val[0], - begin_t, args, body, end_t) - } - | tLAMBDA lambda - { - lambda_call = @builder.call_lambda(val[0]) - - args, (begin_t, body, end_t) = val[1] - result = @builder.block(lambda_call, - begin_t, args, body, end_t) - } - | kIF expr_value then compstmt if_tail kEND - { - else_t, else_ = val[4] - result = @builder.condition(val[0], val[1], val[2], - val[3], else_t, - else_, val[5]) - } - | kUNLESS expr_value then compstmt opt_else kEND - { - else_t, else_ = val[4] - result = @builder.condition(val[0], val[1], val[2], - else_, else_t, - val[3], val[5]) - } - | kWHILE - { - @lexer.cond.push(true) - } - expr_value do - { - @lexer.cond.pop - } - compstmt kEND - { - result = @builder.loop(:while, val[0], val[2], val[3], - val[5], val[6]) - } - | kUNTIL - { - @lexer.cond.push(true) - } - expr_value do - { - @lexer.cond.pop - } - compstmt kEND - { - result = @builder.loop(:until, val[0], val[2], val[3], - val[5], val[6]) - } - | kCASE expr_value opt_terms case_body kEND - { - *when_bodies, (else_t, else_body) = *val[3] - - result = @builder.case(val[0], val[1], - when_bodies, else_t, else_body, - val[4]) - } - | kCASE opt_terms case_body kEND - { - *when_bodies, (else_t, else_body) = *val[2] - - result = @builder.case(val[0], nil, - when_bodies, else_t, else_body, - val[3]) - } - | kFOR for_var kIN - { - @lexer.cond.push(true) - } - expr_value do - { - @lexer.cond.pop - } - compstmt kEND - { - result = @builder.for(val[0], val[1], - val[2], val[4], - val[5], val[7], val[8]) - } - | kCLASS cpath superclass - { - @static_env.extend_static - @lexer.push_cmdarg - } - bodystmt kEND - { - if in_def? - diagnostic :error, :class_in_def, nil, val[0] - end - - lt_t, superclass = val[2] - result = @builder.def_class(val[0], val[1], - lt_t, superclass, - val[4], val[5]) - - @lexer.pop_cmdarg - @static_env.unextend - } - | kCLASS tLSHFT expr term - { - result = @def_level - @def_level = 0 - - @static_env.extend_static - @lexer.push_cmdarg - } - bodystmt kEND - { - result = @builder.def_sclass(val[0], val[1], val[2], - val[5], val[6]) - - @lexer.pop_cmdarg - @static_env.unextend - - @def_level = val[4] - } - | kMODULE cpath - { - @static_env.extend_static - @lexer.push_cmdarg - } - bodystmt kEND - { - if in_def? - diagnostic :error, :module_in_def, nil, val[0] - end - - result = @builder.def_module(val[0], val[1], - val[3], val[4]) - - @lexer.pop_cmdarg - @static_env.unextend - } - | kDEF fname - { - @def_level += 1 - @static_env.extend_static - @lexer.push_cmdarg - } - f_arglist bodystmt kEND - { - result = @builder.def_method(val[0], val[1], - val[3], val[4], val[5]) - - @lexer.pop_cmdarg - @static_env.unextend - @def_level -= 1 - } - | kDEF singleton dot_or_colon - { - @lexer.state = :expr_fname - } - fname - { - @def_level += 1 - @static_env.extend_static - @lexer.push_cmdarg - } - f_arglist bodystmt kEND - { - result = @builder.def_singleton(val[0], val[1], val[2], - val[4], val[6], val[7], val[8]) - - @lexer.pop_cmdarg - @static_env.unextend - @def_level -= 1 - } - | kBREAK - { - result = @builder.keyword_cmd(:break, val[0]) - } - | kNEXT - { - result = @builder.keyword_cmd(:next, val[0]) - } - | kREDO - { - result = @builder.keyword_cmd(:redo, val[0]) - } - | kRETRY - { - result = @builder.keyword_cmd(:retry, val[0]) - } - - primary_value: primary - - then: term - | kTHEN - | term kTHEN - { - result = val[1] - } - - do: term - | kDO_COND - - if_tail: opt_else - | kELSIF expr_value then compstmt if_tail - { - else_t, else_ = val[4] - result = [ val[0], - @builder.condition(val[0], val[1], val[2], - val[3], else_t, - else_, nil), - ] - } - - opt_else: none - | kELSE compstmt - { - result = val - } - - for_var: lhs - | mlhs - - f_marg: f_norm_arg - { - result = @builder.arg(val[0]) - } - | tLPAREN f_margs rparen - { - result = @builder.multi_lhs(val[0], val[1], val[2]) - } - - f_marg_list: f_marg - { - result = [ val[0] ] - } - | f_marg_list tCOMMA f_marg - { - result = val[0] << val[2] - } - - f_margs: f_marg_list - | f_marg_list tCOMMA tSTAR f_norm_arg - { - result = val[0]. - push(@builder.restarg(val[2], val[3])) - } - | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list - { - result = val[0]. - push(@builder.restarg(val[2], val[3])). - concat(val[5]) - } - | f_marg_list tCOMMA tSTAR - { - result = val[0]. - push(@builder.restarg(val[2])) - } - | f_marg_list tCOMMA tSTAR tCOMMA f_marg_list - { - result = val[0]. - push(@builder.restarg(val[2])). - concat(val[4]) - } - | tSTAR f_norm_arg - { - result = [ @builder.restarg(val[0], val[1]) ] - } - | tSTAR f_norm_arg tCOMMA f_marg_list - { - result = [ @builder.restarg(val[0], val[1]), - *val[3] ] - } - | tSTAR - { - result = [ @builder.restarg(val[0]) ] - } - | tSTAR tCOMMA f_marg_list - { - result = [ @builder.restarg(val[0]), - *val[2] ] - } - - block_args_tail: f_block_kwarg tCOMMA f_kwrest opt_f_block_arg - { - result = val[0].concat(val[2]).concat(val[3]) - } - | f_block_kwarg opt_f_block_arg - { - result = val[0].concat(val[1]) - } - | f_kwrest opt_f_block_arg - { - result = val[0].concat(val[1]) - } - | f_block_arg - { - result = [ val[0] ] - } - -opt_block_args_tail: - tCOMMA block_args_tail - { - result = val[1] - } - | # nothing - { - result = [] - } - - block_param: f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg opt_block_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[4]). - concat(val[5]) - } - | f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[4]). - concat(val[6]). - concat(val[7]) - } - | f_arg tCOMMA f_block_optarg opt_block_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[3]) - } - | f_arg tCOMMA f_block_optarg tCOMMA f_arg opt_block_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[4]). - concat(val[5]) - } - | f_arg tCOMMA f_rest_arg opt_block_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[3]) - } - | f_arg tCOMMA - | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[4]). - concat(val[5]) - } - | f_arg opt_block_args_tail - { - result = val[0].concat(val[1]) - } - | f_block_optarg tCOMMA f_rest_arg opt_block_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[3]) - } - | f_block_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[4]). - concat(val[5]) - } - | f_block_optarg opt_block_args_tail - { - result = val[0]. - concat(val[1]) - } - | f_block_optarg tCOMMA f_arg opt_block_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[3]) - } - | f_rest_arg opt_block_args_tail - { - result = val[0]. - concat(val[1]) - } - | f_rest_arg tCOMMA f_arg opt_block_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[3]) - } - | block_args_tail - - opt_block_param: # nothing - { - result = @builder.args(nil, [], nil) - } - | block_param_def - { - @lexer.state = :expr_value - } - - block_param_def: tPIPE opt_bv_decl tPIPE - { - result = @builder.args(val[0], val[1], val[2]) - } - | tOROP - { - result = @builder.args(val[0], [], val[0]) - } - | tPIPE block_param opt_bv_decl tPIPE - { - result = @builder.args(val[0], val[1].concat(val[2]), val[3]) - } - - opt_bv_decl: opt_nl - { - result = [] - } - | opt_nl tSEMI bv_decls opt_nl - { - result = val[2] - } - - bv_decls: bvar - { - result = [ val[0] ] - } - | bv_decls tCOMMA bvar - { - result = val[0] << val[2] - } - - bvar: tIDENTIFIER - { - result = @builder.shadowarg(val[0]) - } - | f_bad_arg - - lambda: { - @static_env.extend_dynamic - } - f_larglist - { - result = @lexer.cmdarg.dup - @lexer.cmdarg.clear - } - lambda_body - { - @lexer.cmdarg = val[2] - @lexer.cmdarg.lexpop - - result = [ val[1], val[3] ] - - @static_env.unextend - } - - f_larglist: tLPAREN2 f_args opt_bv_decl tRPAREN - { - result = @builder.args(val[0], val[1].concat(val[2]), val[3]) - } - | f_args - { - result = @builder.args(nil, val[0], nil) - } - - lambda_body: tLAMBEG compstmt tRCURLY - { - result = [ val[0], val[1], val[2] ] - } - | kDO_LAMBDA compstmt kEND - { - result = [ val[0], val[1], val[2] ] - } - - do_block: kDO_BLOCK - { - @static_env.extend_dynamic - } - opt_block_param compstmt kEND - { - result = [ val[0], val[2], val[3], val[4] ] - - @static_env.unextend - } - - block_call: command do_block - { - begin_t, block_args, body, end_t = val[1] - result = @builder.block(val[0], - begin_t, block_args, body, end_t) - } - | block_call dot_or_colon operation2 opt_paren_args - { - lparen_t, args, rparen_t = val[3] - result = @builder.call_method(val[0], val[1], val[2], - lparen_t, args, rparen_t) - } - | block_call dot_or_colon operation2 opt_paren_args brace_block - { - lparen_t, args, rparen_t = val[3] - method_call = @builder.call_method(val[0], val[1], val[2], - lparen_t, args, rparen_t) - - begin_t, args, body, end_t = val[4] - result = @builder.block(method_call, - begin_t, args, body, end_t) - } - | block_call dot_or_colon operation2 command_args do_block - { - method_call = @builder.call_method(val[0], val[1], val[2], - nil, val[3], nil) - - begin_t, args, body, end_t = val[4] - result = @builder.block(method_call, - begin_t, args, body, end_t) - } - - method_call: fcall paren_args - { - lparen_t, args, rparen_t = val[1] - result = @builder.call_method(nil, nil, val[0], - lparen_t, args, rparen_t) - } - | primary_value tDOT operation2 opt_paren_args - { - lparen_t, args, rparen_t = val[3] - result = @builder.call_method(val[0], val[1], val[2], - lparen_t, args, rparen_t) - } - | primary_value tCOLON2 operation2 paren_args - { - lparen_t, args, rparen_t = val[3] - result = @builder.call_method(val[0], val[1], val[2], - lparen_t, args, rparen_t) - } - | primary_value tCOLON2 operation3 - { - result = @builder.call_method(val[0], val[1], val[2]) - } - | primary_value tDOT paren_args - { - lparen_t, args, rparen_t = val[2] - result = @builder.call_method(val[0], val[1], nil, - lparen_t, args, rparen_t) - } - | primary_value tCOLON2 paren_args - { - lparen_t, args, rparen_t = val[2] - result = @builder.call_method(val[0], val[1], nil, - lparen_t, args, rparen_t) - } - | kSUPER paren_args - { - lparen_t, args, rparen_t = val[1] - result = @builder.keyword_cmd(:super, val[0], - lparen_t, args, rparen_t) - } - | kSUPER - { - result = @builder.keyword_cmd(:zsuper, val[0]) - } - | primary_value tLBRACK2 opt_call_args rbracket - { - result = @builder.index(val[0], val[1], val[2], val[3]) - } - - brace_block: tLCURLY - { - @static_env.extend_dynamic - } - opt_block_param compstmt tRCURLY - { - result = [ val[0], val[2], val[3], val[4] ] - - @static_env.unextend - } - | kDO - { - @static_env.extend_dynamic - } - opt_block_param compstmt kEND - { - result = [ val[0], val[2], val[3], val[4] ] - - @static_env.unextend - } - - case_body: kWHEN args then compstmt cases - { - result = [ @builder.when(val[0], val[1], val[2], val[3]), - *val[4] ] - } - - cases: opt_else - { - result = [ val[0] ] - } - | case_body - - opt_rescue: kRESCUE exc_list exc_var then compstmt opt_rescue - { - assoc_t, exc_var = val[2] - - if val[1] - exc_list = @builder.array(nil, val[1], nil) - end - - result = [ @builder.rescue_body(val[0], - exc_list, assoc_t, exc_var, - val[3], val[4]), - *val[5] ] - } - | - { - result = [] - } - - exc_list: arg_value - { - result = [ val[0] ] - } - | mrhs - | none - - exc_var: tASSOC lhs - { - result = [ val[0], val[1] ] - } - | none - - opt_ensure: kENSURE compstmt - { - result = [ val[0], val[1] ] - } - | none - - literal: numeric - | symbol - | dsym - - strings: string - { - result = @builder.string_compose(nil, val[0], nil) - } - - string: string1 - { - result = [ val[0] ] - } - | string string1 - { - result = val[0] << val[1] - } - - string1: tSTRING_BEG string_contents tSTRING_END - { - result = @builder.string_compose(val[0], val[1], val[2]) - } - | tSTRING - { - result = @builder.string(val[0]) - } - | tCHARACTER - { - result = @builder.character(val[0]) - } - - xstring: tXSTRING_BEG xstring_contents tSTRING_END - { - result = @builder.xstring_compose(val[0], val[1], val[2]) - } - - regexp: tREGEXP_BEG regexp_contents tSTRING_END tREGEXP_OPT - { - opts = @builder.regexp_options(val[3]) - result = @builder.regexp_compose(val[0], val[1], val[2], opts) - } - - words: tWORDS_BEG word_list tSTRING_END - { - result = @builder.words_compose(val[0], val[1], val[2]) - } - - word_list: # nothing - { - result = [] - } - | word_list word tSPACE - { - result = val[0] << @builder.word(val[1]) - } - - word: string_content - { - result = [ val[0] ] - } - | word string_content - { - result = val[0] << val[1] - } - - symbols: tSYMBOLS_BEG symbol_list tSTRING_END - { - result = @builder.symbols_compose(val[0], val[1], val[2]) - } - - symbol_list: # nothing - { - result = [] - } - | symbol_list word tSPACE - { - result = val[0] << @builder.word(val[1]) - } - - qwords: tQWORDS_BEG qword_list tSTRING_END - { - result = @builder.words_compose(val[0], val[1], val[2]) - } - - qsymbols: tQSYMBOLS_BEG qsym_list tSTRING_END - { - result = @builder.symbols_compose(val[0], val[1], val[2]) - } - - qword_list: # nothing - { - result = [] - } - | qword_list tSTRING_CONTENT tSPACE - { - result = val[0] << @builder.string_internal(val[1]) - } - - qsym_list: # nothing - { - result = [] - } - | qsym_list tSTRING_CONTENT tSPACE - { - result = val[0] << @builder.symbol_internal(val[1]) - } - - string_contents: # nothing - { - result = [] - } - | string_contents string_content - { - result = val[0] << val[1] - } - -xstring_contents: # nothing - { - result = [] - } - | xstring_contents string_content - { - result = val[0] << val[1] - } - -regexp_contents: # nothing - { - result = [] - } - | regexp_contents string_content - { - result = val[0] << val[1] - } - - string_content: tSTRING_CONTENT - { - result = @builder.string_internal(val[0]) - } - | tSTRING_DVAR string_dvar - { - result = val[1] - } - | tSTRING_DBEG - { - @lexer.cond.push(false) - @lexer.cmdarg.push(false) - } - compstmt tSTRING_DEND - { - @lexer.cond.lexpop - @lexer.cmdarg.lexpop - - result = @builder.begin(val[0], val[2], val[3]) - } - - string_dvar: tGVAR - { - result = @builder.gvar(val[0]) - } - | tIVAR - { - result = @builder.ivar(val[0]) - } - | tCVAR - { - result = @builder.cvar(val[0]) - } - | backref - - - symbol: tSYMBOL - { - result = @builder.symbol(val[0]) - } - - dsym: tSYMBEG xstring_contents tSTRING_END - { - result = @builder.symbol_compose(val[0], val[1], val[2]) - } - - numeric: simple_numeric - { - result = val[0] - } - | tUMINUS_NUM simple_numeric =tLOWEST - { - result = @builder.negate(val[0], val[1]) - } - - simple_numeric: tINTEGER - { - result = @builder.integer(val[0]) - } - | tFLOAT - { - result = @builder.float(val[0]) - } - | tRATIONAL - { - result = @builder.rational(val[0]) - } - | tIMAGINARY - { - result = @builder.complex(val[0]) - } - - user_variable: tIDENTIFIER - { - result = @builder.ident(val[0]) - } - | tIVAR - { - result = @builder.ivar(val[0]) - } - | tGVAR - { - result = @builder.gvar(val[0]) - } - | tCONSTANT - { - result = @builder.const(val[0]) - } - | tCVAR - { - result = @builder.cvar(val[0]) - } - -keyword_variable: kNIL - { - result = @builder.nil(val[0]) - } - | kSELF - { - result = @builder.self(val[0]) - } - | kTRUE - { - result = @builder.true(val[0]) - } - | kFALSE - { - result = @builder.false(val[0]) - } - | k__FILE__ - { - result = @builder.__FILE__(val[0]) - } - | k__LINE__ - { - result = @builder.__LINE__(val[0]) - } - | k__ENCODING__ - { - result = @builder.__ENCODING__(val[0]) - } - - var_ref: user_variable - { - result = @builder.accessible(val[0]) - } - | keyword_variable - { - result = @builder.accessible(val[0]) - } - - var_lhs: user_variable - { - result = @builder.assignable(val[0]) - } - | keyword_variable - { - result = @builder.assignable(val[0]) - } - - backref: tNTH_REF - { - result = @builder.nth_ref(val[0]) - } - | tBACK_REF - { - result = @builder.back_ref(val[0]) - } - - superclass: term - { - result = nil - } - | tLT - { - @lexer.state = :expr_value - } - expr_value term - { - result = [ val[0], val[2] ] - } - | error term - { - yyerrok - result = nil - } - - f_arglist: tLPAREN2 f_args rparen - { - result = @builder.args(val[0], val[1], val[2]) - - @lexer.state = :expr_value - } - | { - result = @lexer.in_kwarg - @lexer.in_kwarg = true - } - f_args term - { - @lexer.in_kwarg = val[0] - result = @builder.args(nil, val[1], nil) - } - - args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg - { - result = val[0].concat(val[2]).concat(val[3]) - } - | f_kwarg opt_f_block_arg - { - result = val[0].concat(val[1]) - } - | f_kwrest opt_f_block_arg - { - result = val[0].concat(val[1]) - } - | f_block_arg - { - result = [ val[0] ] - } - - opt_args_tail: tCOMMA args_tail - { - result = val[1] - } - | # nothing - { - result = [] - } - - f_args: f_arg tCOMMA f_optarg tCOMMA f_rest_arg opt_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[4]). - concat(val[5]) - } - | f_arg tCOMMA f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[4]). - concat(val[6]). - concat(val[7]) - } - | f_arg tCOMMA f_optarg opt_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[3]) - } - | f_arg tCOMMA f_optarg tCOMMA f_arg opt_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[4]). - concat(val[5]) - } - | f_arg tCOMMA f_rest_arg opt_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[3]) - } - | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[4]). - concat(val[5]) - } - | f_arg opt_args_tail - { - result = val[0]. - concat(val[1]) - } - | f_optarg tCOMMA f_rest_arg opt_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[3]) - } - | f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[4]). - concat(val[5]) - } - | f_optarg opt_args_tail - { - result = val[0]. - concat(val[1]) - } - | f_optarg tCOMMA f_arg opt_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[3]) - } - | f_rest_arg opt_args_tail - { - result = val[0]. - concat(val[1]) - } - | f_rest_arg tCOMMA f_arg opt_args_tail - { - result = val[0]. - concat(val[2]). - concat(val[3]) - } - | args_tail - { - result = val[0] - } - | # nothing - { - result = [] - } - - f_bad_arg: tCONSTANT - { - diagnostic :error, :argument_const, nil, val[0] - } - | tIVAR - { - diagnostic :error, :argument_ivar, nil, val[0] - } - | tGVAR - { - diagnostic :error, :argument_gvar, nil, val[0] - } - | tCVAR - { - diagnostic :error, :argument_cvar, nil, val[0] - } - - f_norm_arg: f_bad_arg - | tIDENTIFIER - { - @static_env.declare val[0][0] - - result = val[0] - } - - f_arg_asgn: f_norm_arg - { - result = val[0] - } - - f_arg_item: f_arg_asgn - { - result = @builder.arg(val[0]) - } - | tLPAREN f_margs rparen - { - result = @builder.multi_lhs(val[0], val[1], val[2]) - } - - f_arg: f_arg_item - { - result = [ val[0] ] - } - | f_arg tCOMMA f_arg_item - { - result = val[0] << val[2] - } - - f_label: tLABEL - { - check_kwarg_name(val[0]) - - @static_env.declare val[0][0] - - result = val[0] - } - - f_kw: f_label arg_value - { - result = @builder.kwoptarg(val[0], val[1]) - } - | f_label - { - result = @builder.kwarg(val[0]) - } - - f_block_kw: f_label primary_value - { - result = @builder.kwoptarg(val[0], val[1]) - } - | f_label - { - result = @builder.kwarg(val[0]) - } - - f_block_kwarg: f_block_kw - { - result = [ val[0] ] - } - | f_block_kwarg tCOMMA f_block_kw - { - result = val[0] << val[2] - } - - f_kwarg: f_kw - { - result = [ val[0] ] - } - | f_kwarg tCOMMA f_kw - { - result = val[0] << val[2] - } - - kwrest_mark: tPOW | tDSTAR - - f_kwrest: kwrest_mark tIDENTIFIER - { - @static_env.declare val[1][0] - - result = [ @builder.kwrestarg(val[0], val[1]) ] - } - | kwrest_mark - { - result = [ @builder.kwrestarg(val[0]) ] - } - - f_opt: f_arg_asgn tEQL arg_value - { - result = @builder.optarg(val[0], val[1], val[2]) - } - - f_block_opt: f_arg_asgn tEQL primary_value - { - result = @builder.optarg(val[0], val[1], val[2]) - } - - f_block_optarg: f_block_opt - { - result = [ val[0] ] - } - | f_block_optarg tCOMMA f_block_opt - { - result = val[0] << val[2] - } - - f_optarg: f_opt - { - result = [ val[0] ] - } - | f_optarg tCOMMA f_opt - { - result = val[0] << val[2] - } - - restarg_mark: tSTAR2 | tSTAR - - f_rest_arg: restarg_mark tIDENTIFIER - { - @static_env.declare val[1][0] - - result = [ @builder.restarg(val[0], val[1]) ] - } - | restarg_mark - { - result = [ @builder.restarg(val[0]) ] - } - - blkarg_mark: tAMPER2 | tAMPER - - f_block_arg: blkarg_mark tIDENTIFIER - { - @static_env.declare val[1][0] - - result = @builder.blockarg(val[0], val[1]) - } - - opt_f_block_arg: tCOMMA f_block_arg - { - result = [ val[1] ] - } - | - { - result = [] - } - - singleton: var_ref - | tLPAREN2 expr rparen - { - result = val[1] - } - - assoc_list: # nothing - { - result = [] - } - | assocs trailer - - assocs: assoc - { - result = [ val[0] ] - } - | assocs tCOMMA assoc - { - result = val[0] << val[2] - } - - assoc: arg_value tASSOC arg_value - { - result = @builder.pair(val[0], val[1], val[2]) - } - | tLABEL arg_value - { - result = @builder.pair_keyword(val[0], val[1]) - } - | tSTRING_BEG string_contents tLABEL_END arg_value - { - result = @builder.pair_quoted(val[0], val[1], val[2], val[3]) - } - | tDSTAR arg_value - { - result = @builder.kwsplat(val[0], val[1]) - } - - operation: tIDENTIFIER | tCONSTANT | tFID - operation2: tIDENTIFIER | tCONSTANT | tFID | op - operation3: tIDENTIFIER | tFID | op - dot_or_colon: tDOT | tCOLON2 - opt_terms: | terms - opt_nl: | tNL - rparen: opt_nl tRPAREN - { - result = val[1] - } - rbracket: opt_nl tRBRACK - { - result = val[1] - } - trailer: | tNL | tCOMMA - - term: tSEMI - { - yyerrok - } - | tNL - - terms: term - | terms tSEMI - - none: # nothing - { - result = nil - } -end - ----- header - -require 'parser' - -Parser.check_for_encoding_support - ----- inner - - def version - 22 - end - - def default_encoding - Encoding::UTF_8 - end diff --git a/test/racc/assets/scan.y b/test/racc/assets/scan.y deleted file mode 100644 index 709254ed66..0000000000 --- a/test/racc/assets/scan.y +++ /dev/null @@ -1,72 +0,0 @@ -class P - -rule - - a: A - { - # comment test - - # comment test - - # string - @sstring = 'squote string' - @dstring = 'dquote string' - - # regexp - @regexp = /some regexp with spaces/ - - # gvar - /regexp/ === 'some regexp matches to this string' - @pre_match = $` - @matched = $& - @post_match = $' - @m = $~ - - # braces - @array = [] - [1,2,3].each {|i| - @array.push i - } - 3.times { @array.push 10 } - } - -end - ----- inner - - def parse - @sstring = @dstring = nil - @regexp = nil - @pre_match = @matched = @post_match = @m = nil - - @src = [[:A, 'A'], [false, '$']] - do_parse - - assert_equal 'squote string', @sstring - assert_equal 'dquote string', @dstring - assert_equal(/some regexp with spaces/, @regexp) - assert_equal 'some ', @pre_match - assert_equal 'regexp', @matched - assert_equal ' matches to this string', @post_match - assert_instance_of MatchData, @m - end - - def assert_equal(ok, data) - unless ok == data - raise "expected <#{ok.inspect}> but is <#{data.inspect}>" - end - end - - def assert_instance_of(klass, obj) - unless obj.instance_of?(klass) - raise "expected #{klass} but is #{obj.class}" - end - end - - def next_token - @src.shift - end - ----- footer - -P.new.parse diff --git a/test/racc/assets/syntax.y b/test/racc/assets/syntax.y deleted file mode 100644 index 727f74a29d..0000000000 --- a/test/racc/assets/syntax.y +++ /dev/null @@ -1,50 +0,0 @@ -# -# racc syntax checker -# - -class M1::M2::ParserClass < S1::S2::SuperClass - - token A - | B C - - convert - A '5' - end - - prechigh - left B - preclow - - start target - - expect 0 - -rule - - target: A B C - { - print 'abc' - } - | B C A - | C B A - { - print 'cba' - } - | cont - - cont : A c2 B c2 C - - c2 : C C C C C - -end - ----- inner - - junk code !!!! - -kjaljlajrlaolanbla /// %%% (*((( token rule -akiurtlajluealjflaj @@@@ end end end end __END__ - laieu2o879urkq96ga(Q#*&%Q# - #&lkji END - - q395q?/// liutjqlkr7 diff --git a/test/racc/assets/tp_plus.y b/test/racc/assets/tp_plus.y deleted file mode 100644 index 388ed1302d..0000000000 --- a/test/racc/assets/tp_plus.y +++ /dev/null @@ -1,622 +0,0 @@ -# Released under an MIT License (http://www.opensource.org/licenses/MIT) -# By Jay Strybis (https://github.com/unreal) - -class TPPlus::Parser -token ASSIGN AT_SYM COMMENT JUMP IO_METHOD INPUT OUTPUT -token NUMREG POSREG VREG SREG TIME_SEGMENT ARG UALM -token MOVE DOT TO AT TERM OFFSET SKIP GROUP -token SEMICOLON NEWLINE STRING -token REAL DIGIT WORD EQUAL -token EEQUAL NOTEQUAL GTE LTE LT GT BANG -token PLUS MINUS STAR SLASH DIV AND OR MOD -token IF ELSE END UNLESS FOR IN WHILE -token WAIT_FOR WAIT_UNTIL TIMEOUT AFTER -token FANUC_USE SET_SKIP_CONDITION NAMESPACE -token CASE WHEN INDIRECT POSITION -token EVAL TIMER TIMER_METHOD RAISE ABORT -token POSITION_DATA TRUE_FALSE RUN TP_HEADER PAUSE -token LPAREN RPAREN COLON COMMA LBRACK RBRACK LBRACE RBRACE -token LABEL ADDRESS -token false - -prechigh - right BANG - left STAR SLASH DIV MOD - left PLUS MINUS - left GT GTE LT LTE - left EEQUAL NOTEQUAL - left AND - left OR - right EQUAL -preclow - -rule - program - #: statements { @interpreter.nodes = val[0].flatten } - : statements { @interpreter.nodes = val[0] } - | - ; - - - statements - : statement terminator { - result = [val[0]] - result << val[1] unless val[1].nil? - } - | statements statement terminator { - result = val[0] << val[1] - result << val[2] unless val[2].nil? - } - ; - - block - : NEWLINE statements { result = val[1] } - ; - - optional_newline - : NEWLINE - | - ; - - statement - : comment - | definition - | namespace - #| assignment - | motion_statement - #| jump - #| io_method - | label_definition - | address - | conditional - | inline_conditional - | forloop - | while_loop - #| program_call - | use_statement - | set_skip_statement - | wait_statement - | case_statement - | fanuc_eval - | timer_method - | position_data - | raise - | tp_header_definition - | empty_stmt - | PAUSE { result = PauseNode.new } - | ABORT { result = AbortNode.new } - ; - - empty_stmt - : NEWLINE { result = EmptyStmtNode.new() } - ; - - tp_header_definition - : TP_HEADER EQUAL tp_header_value { result = HeaderNode.new(val[0],val[2]) } - ; - - tp_header_value - : STRING - | TRUE_FALSE - ; - - raise - : RAISE var_or_indirect { result = RaiseNode.new(val[1]) } - ; - - timer_method - : TIMER_METHOD var_or_indirect { result = TimerMethodNode.new(val[0],val[1]) } - ; - - fanuc_eval - : EVAL STRING { result = EvalNode.new(val[1]) } - ; - - wait_statement - : WAIT_FOR LPAREN indirectable COMMA STRING RPAREN - { result = WaitForNode.new(val[2], val[4]) } - | WAIT_UNTIL LPAREN expression RPAREN - { result = WaitUntilNode.new(val[2], nil) } - | WAIT_UNTIL LPAREN expression RPAREN DOT wait_modifier - { result = WaitUntilNode.new(val[2],val[5]) } - | WAIT_UNTIL LPAREN expression RPAREN DOT wait_modifier DOT wait_modifier - { result = WaitUntilNode.new(val[2],val[5].merge(val[7])) } - ; - - wait_modifier - : timeout_modifier - | after_modifier - ; - - timeout_modifier - : swallow_newlines TIMEOUT LPAREN label RPAREN - { result = { label: val[3] } } - ; - - after_modifier - : swallow_newlines AFTER LPAREN indirectable COMMA STRING RPAREN - { result = { timeout: [val[3],val[5]] } } - ; - - label - : LABEL { result = val[0] } - ; - - use_statement - : FANUC_USE indirectable { result = UseNode.new(val[0],val[1]) } - ; - - # set_skip_condition x - set_skip_statement - : SET_SKIP_CONDITION expression { result = SetSkipNode.new(val[1]) } - ; - - program_call - : WORD LPAREN args RPAREN { result = CallNode.new(val[0],val[2]) } - | RUN WORD LPAREN args RPAREN { result = CallNode.new(val[1],val[3],async: true) } - ; - - args - : arg { result = [val[0]] } - | args COMMA arg { result = val[0] << val[2] } - | { result = [] } - ; - - arg - : number - | var - | string - | address - ; - - string - : STRING { result = StringNode.new(val[0]) } - ; - - io_method - : IO_METHOD var_or_indirect { result = IOMethodNode.new(val[0],val[1]) } - | IO_METHOD LPAREN var_or_indirect RPAREN - { result = IOMethodNode.new(val[0],val[2]) } - | IO_METHOD LPAREN var_or_indirect COMMA number COMMA STRING RPAREN - { result = IOMethodNode.new(val[0],val[2],{ pulse_time: val[4], pulse_units: val[6] }) } - ; - - var_or_indirect - : var - | indirect_thing - ; - - - jump - : JUMP label { result = JumpNode.new(val[1]) } - ; - - conditional - : IF expression block else_block END - { result = ConditionalNode.new("if",val[1],val[2],val[3]) } - | UNLESS expression block else_block END - { result = ConditionalNode.new("unless",val[1],val[2],val[3]) } - ; - - forloop - : FOR var IN LPAREN minmax_val TO minmax_val RPAREN block END - { result = ForNode.new(val[1],val[4],val[6],val[8]) } - ; - - while_loop - : WHILE expression block END { result = WhileNode.new(val[1],val[2]) } - ; - - minmax_val - : integer - | var - ; - - namespace - : NAMESPACE WORD block END { result = NamespaceNode.new(val[1],val[2]) } - ; - - case_statement - : CASE var swallow_newlines - case_conditions - case_else - END { result = CaseNode.new(val[1],val[3],val[4]) } - ; - - case_conditions - : case_condition { result = val } - | case_conditions case_condition - { result = val[0] << val[1] << val[2] } - ; - - case_condition - : WHEN case_allowed_condition swallow_newlines case_allowed_statement - terminator { result = CaseConditionNode.new(val[1],val[3]) } - ; - - case_allowed_condition - : number - | var - ; - - case_else - : ELSE swallow_newlines case_allowed_statement terminator - { result = CaseConditionNode.new(nil,val[2]) } - | - ; - - case_allowed_statement - : program_call - | jump - ; - - inline_conditional - : inlineable - | inlineable IF expression { result = InlineConditionalNode.new(val[1], val[2], val[0]) } - | inlineable UNLESS expression { result = InlineConditionalNode.new(val[1], val[2], val[0]) } - ; - - inlineable - : jump - | assignment - | io_method - | program_call - ; - - else_block - : ELSE block { result = val[1] } - | { result = [] } - ; - - motion_statement - : MOVE DOT swallow_newlines TO LPAREN var RPAREN motion_modifiers - { result = MotionNode.new(val[0],val[5],val[7]) } - ; - - motion_modifiers - : motion_modifier { result = val } - | motion_modifiers motion_modifier - { result = val[0] << val[1] } - ; - - motion_modifier - : DOT swallow_newlines AT LPAREN speed RPAREN - { result = SpeedNode.new(val[4]) } - | DOT swallow_newlines TERM LPAREN valid_terminations RPAREN - { result = TerminationNode.new(val[4]) } - | DOT swallow_newlines OFFSET LPAREN var RPAREN - { result = OffsetNode.new(val[2],val[4]) } - | DOT swallow_newlines TIME_SEGMENT LPAREN time COMMA time_seg_actions RPAREN - { result = TimeNode.new(val[2],val[4],val[6]) } - | DOT swallow_newlines SKIP LPAREN label optional_lpos_arg RPAREN - { result = SkipNode.new(val[4],val[5]) } - ; - - valid_terminations - : integer - | var - | MINUS DIGIT { - raise Racc::ParseError, sprintf("\ninvalid termination type: (%s)", val[1]) if val[1] != 1 - - result = DigitNode.new(val[1].to_i * -1) - } - ; - - optional_lpos_arg - : COMMA var { result = val[1] } - | - ; - - indirectable - : number - | var - ; - - time_seg_actions - : program_call - | io_method - ; - - time - : var - | number - ; - - speed - : indirectable COMMA STRING { result = { speed: val[0], units: val[2] } } - | STRING { result = { speed: val[0], units: nil } } - ; - - label_definition - : label { result = LabelDefinitionNode.new(val[0]) }#@interpreter.add_label(val[1]) } - ; - - definition - : WORD ASSIGN definable { result = DefinitionNode.new(val[0],val[2]) } - ; - - assignment - : var_or_indirect EQUAL expression { result = AssignmentNode.new(val[0],val[2]) } - | var_or_indirect PLUS EQUAL expression { result = AssignmentNode.new( - val[0], - ExpressionNode.new(val[0],"+",val[3]) - ) - } - | var_or_indirect MINUS EQUAL expression { result = AssignmentNode.new( - val[0], - ExpressionNode.new(val[0],"-",val[3]) - ) - } - ; - - var - : var_without_namespaces - | var_with_namespaces - ; - - var_without_namespaces - : WORD { result = VarNode.new(val[0]) } - | WORD var_method_modifiers { result = VarMethodNode.new(val[0],val[1]) } - ; - - var_with_namespaces - : namespaces var_without_namespaces - { result = NamespacedVarNode.new(val[0],val[1]) } - ; - - var_method_modifiers - : var_method_modifier { result = val[0] } - | var_method_modifiers var_method_modifier - { result = val[0].merge(val[1]) } - ; - - var_method_modifier - : DOT swallow_newlines WORD { result = { method: val[2] } } - | DOT swallow_newlines GROUP LPAREN integer RPAREN - { result = { group: val[4] } } - ; - - namespaces - : ns { result = [val[0]] } - | namespaces ns { result = val[0] << val[1] } - ; - - ns - : WORD COLON COLON { result = val[0] } - ; - - - expression - : unary_expression - | binary_expression - ; - - unary_expression - : factor { result = val[0] } - | address - | BANG factor { result = ExpressionNode.new(val[1], "!", nil) } - ; - - binary_expression - : expression operator expression - { result = ExpressionNode.new(val[0], val[1], val[2]) } - ; - - operator - : EEQUAL { result = "==" } - | NOTEQUAL { result = "<>" } - | LT { result = "<" } - | GT { result = ">" } - | GTE { result = ">=" } - | LTE { result = "<=" } - | PLUS { result = "+" } - | MINUS { result = "-" } - | OR { result = "||" } - | STAR { result = "*" } - | SLASH { result = "/" } - | DIV { result = "DIV" } - | MOD { result = "%" } - | AND { result = "&&" } - ; - - factor - : number - | signed_number - | var - | indirect_thing - | paren_expr - ; - - paren_expr - : LPAREN expression RPAREN { result = ParenExpressionNode.new(val[1]) } - ; - - indirect_thing - : INDIRECT LPAREN STRING COMMA indirectable RPAREN - { result = IndirectNode.new(val[2].to_sym, val[4]) } - ; - - signed_number - : sign DIGIT { - val[1] = val[1].to_i * -1 if val[0] == "-" - result = DigitNode.new(val[1]) - } - | sign REAL { val[1] = val[1].to_f * -1 if val[0] == "-"; result = RealNode.new(val[1]) } - ; - - sign - : MINUS { result = "-" } - ; - - number - : integer - | REAL { result = RealNode.new(val[0]) } - ; - - integer - : DIGIT { result = DigitNode.new(val[0]) } - ; - - definable - : numreg - | output - | input - | posreg - | position - | vreg - | number - | signed_number - | argument - | timer - | ualm - | sreg - ; - - - sreg - : SREG LBRACK DIGIT RBRACK { result = StringRegisterNode.new(val[2].to_i) } - ; - - ualm - : UALM LBRACK DIGIT RBRACK { result = UserAlarmNode.new(val[2].to_i) } - ; - - timer - : TIMER LBRACK DIGIT RBRACK { result = TimerNode.new(val[2].to_i) } - ; - - argument - : ARG LBRACK DIGIT RBRACK { result = ArgumentNode.new(val[2].to_i) } - ; - - vreg - : VREG LBRACK DIGIT RBRACK { result = VisionRegisterNode.new(val[2].to_i) } - ; - - position - : POSITION LBRACK DIGIT RBRACK { result = PositionNode.new(val[2].to_i) } - ; - - numreg - : NUMREG LBRACK DIGIT RBRACK { result = NumregNode.new(val[2].to_i) } - ; - - posreg - : POSREG LBRACK DIGIT RBRACK { result = PosregNode.new(val[2].to_i) } - ; - - output - : OUTPUT LBRACK DIGIT RBRACK { result = IONode.new(val[0], val[2].to_i) } - ; - - input - : INPUT LBRACK DIGIT RBRACK { result = IONode.new(val[0], val[2].to_i) } - ; - - address - : ADDRESS { result = AddressNode.new(val[0]) } - ; - - comment - : COMMENT { result = CommentNode.new(val[0]) } - ; - - terminator - : NEWLINE { result = TerminatorNode.new } - | comment optional_newline { result = val[0] } - # ^-- consume newlines or else we will get an extra space from EmptyStmt in the output - | false - | - ; - - swallow_newlines - : NEWLINE { result = TerminatorNode.new } - | - ; - - position_data - : POSITION_DATA sn hash sn END - { result = PositionDataNode.new(val[2]) } - ; - - sn - : swallow_newlines - ; - - hash - : LBRACE sn hash_attributes sn RBRACE { result = val[2] } - | LBRACE sn RBRACE { result = {} } - ; - - hash_attributes - : hash_attribute { result = val[0] } - | hash_attributes COMMA sn hash_attribute - { result = val[0].merge(val[3]) } - ; - - hash_attribute - : STRING COLON hash_value { result = { val[0].to_sym => val[2] } } - ; - - hash_value - : STRING - | hash - | array - | optional_sign DIGIT { val[1] = val[1].to_i * -1 if val[0] == "-"; result = val[1] } - | optional_sign REAL { val[1] = val[1].to_f * -1 if val[0] == "-"; result = val[1] } - | TRUE_FALSE { result = val[0] == "true" } - ; - - optional_sign - : sign - | - ; - - array - : LBRACK sn array_values sn RBRACK { result = val[2] } - ; - - array_values - : array_value { result = val } - | array_values COMMA sn array_value { result = val[0] << val[3] } - ; - - array_value - : hash_value - ; - - -end - ----- inner - - include TPPlus::Nodes - - attr_reader :interpreter - def initialize(scanner, interpreter = TPPlus::Interpreter.new) - @scanner = scanner - @interpreter = interpreter - super() - end - - def next_token - t = @scanner.next_token - @interpreter.line_count += 1 if t && t[0] == :NEWLINE - - #puts t.inspect - t - end - - def parse - #@yydebug =true - - do_parse - @interpreter - end - - def on_error(t, val, vstack) - raise ParseError, sprintf("Parse error on line #{@scanner.tok_line} column #{@scanner.tok_col}: %s (%s)", - val.inspect, token_to_str(t) || '?') - end - - class ParseError < StandardError ; end diff --git a/test/racc/assets/twowaysql.y b/test/racc/assets/twowaysql.y deleted file mode 100644 index d3bc748d3a..0000000000 --- a/test/racc/assets/twowaysql.y +++ /dev/null @@ -1,278 +0,0 @@ -# Copyright 2008-2015 Takuto Wada -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -class TwoWaySQL::Parser - -rule - -sql : stmt_list - { - result = RootNode.new( val[0] ) - } - -stmt_list : - { - result = [] - } - | stmt_list stmt - { - result.push val[1] - } - -stmt : primary - | if_stmt - | begin_stmt - -begin_stmt : BEGIN stmt_list END - { - result = BeginNode.new( val[1] ) - } - -if_stmt : IF sub_stmt else_stmt END - { - result = IfNode.new( val[0][1], val[1], val[2] ) - } - -else_stmt : ELSE sub_stmt - { - result = val[1] - } - | - { - result = nil - } - -sub_stmt : and_stmt - | or_stmt - | stmt_list - -and_stmt : AND stmt_list - { - result = SubStatementNode.new( val[0][1], val[1] ) - } - -or_stmt : OR stmt_list - { - result = SubStatementNode.new( val[0][1], val[1] ) - } - -primary : IDENT - { - result = LiteralNode.new( val[0][1] ) - } - | STRING_LITERAL - { - result = LiteralNode.new( val[0][1] ) - } - | AND - { - result = LiteralNode.new( val[0][1] ) - } - | OR - { - result = LiteralNode.new( val[0][1] ) - } - | SPACES - { - result = WhiteSpaceNode.new( val[0][1], @preserve_space ) - } - | COMMA - { - result = LiteralNode.new( val[0][1] ) - } - | LPAREN - { - result = LiteralNode.new( val[0][1] ) - } - | RPAREN - { - result = LiteralNode.new( val[0][1] ) - } - | QUESTION - { - @num_questions += 1 - result = QuestionNode.new( @num_questions ) - } - | ACTUAL_COMMENT - { - result = ActualCommentNode.new( val[0][1] , val[0][2] ) - } - | bind_var - | embed_var - -bind_var : BIND_VARIABLE STRING_LITERAL - { - result = BindVariableNode.new( val[0][1] ) - } - | BIND_VARIABLE SPACES STRING_LITERAL - { - result = BindVariableNode.new( val[0][1] ) - } - | BIND_VARIABLE IDENT - { - result = BindVariableNode.new( val[0][1] ) - } - | BIND_VARIABLE SPACES IDENT - { - result = BindVariableNode.new( val[0][1] ) - } - | PAREN_BIND_VARIABLE - { - result = ParenBindVariableNode.new( val[0][1] ) - } - -embed_var : EMBED_VARIABLE IDENT - { - result = EmbedVariableNode.new( val[0][1] ) - } - | EMBED_VARIABLE SPACES IDENT - { - result = EmbedVariableNode.new( val[0][1] ) - } - -end - - ----- inner - -require 'strscan' - -def initialize(opts={}) - opts = { - :debug => false, - :preserve_space => true, - :preserve_comment => false - }.merge(opts) - @yydebug = opts[:debug] - @preserve_space = opts[:preserve_space] - @preserve_comment = opts[:preserve_comment] - @num_questions = 0 -end - - -PAREN_EXAMPLE = '\([^\)]+\)' -BEGIN_BIND_VARIABLE = '(\/|\#)\*([^\*]+)\*\1' -BIND_VARIABLE_PATTERN = /\A#{BEGIN_BIND_VARIABLE}\s*/ -PAREN_BIND_VARIABLE_PATTERN = /\A#{BEGIN_BIND_VARIABLE}\s*#{PAREN_EXAMPLE}/ -EMBED_VARIABLE_PATTERN = /\A(\/|\#)\*\$([^\*]+)\*\1\s*/ - -CONDITIONAL_PATTERN = /\A(\/|\#)\*(IF)\s+([^\*]+)\s*\*\1/ -BEGIN_END_PATTERN = /\A(\/|\#)\*(BEGIN|END)\s*\*\1/ -STRING_LITERAL_PATTERN = /\A(\'(?:[^\']+|\'\')*\')/ ## quoted string -SPLIT_TOKEN_PATTERN = /\A(\S+?)(?=\s*(?:(?:\/|\#)\*|-{2,}|\(|\)|\,))/ ## stop on delimiters --,/*,#*,',',(,) -LITERAL_PATTERN = /\A([^;\s]+)/ -SPACES_PATTERN = /\A(\s+)/ -QUESTION_PATTERN = /\A\?/ -COMMA_PATTERN = /\A\,/ -LPAREN_PATTERN = /\A\(/ -RPAREN_PATTERN = /\A\)/ -ACTUAL_COMMENT_PATTERN = /\A(\/|\#)\*(\s{1,}(?:.*?))\*\1/m ## start with spaces -SEMICOLON_AT_INPUT_END_PATTERN = /\A\;\s*\Z/ -UNMATCHED_COMMENT_START_PATTERN = /\A(?:(?:\/|\#)\*)/ - -#TODO: remove trailing spaces for S2Dao compatibility, but this spec sometimes causes SQL bugs... -ELSE_PATTERN = /\A\-{2,}\s*ELSE\s*/ -AND_PATTERN = /\A(\ *AND)\b/i -OR_PATTERN = /\A(\ *OR)\b/i - - -def parse( io ) - @q = [] - io.each_line(nil) do |whole| - @s = StringScanner.new(whole) - end - scan_str - - # @q.push [ false, nil ] - @q.push [ false, [@s.pos, nil] ] - - ## call racc's private parse method - do_parse -end - - -## called by racc -def next_token - @q.shift -end - - -def scan_str - until @s.eos? do - case - when @s.scan(AND_PATTERN) - @q.push [ :AND, [@s.pos, @s[1]] ] - when @s.scan(OR_PATTERN) - @q.push [ :OR, [@s.pos, @s[1]] ] - when @s.scan(SPACES_PATTERN) - @q.push [ :SPACES, [@s.pos, @s[1]] ] - when @s.scan(QUESTION_PATTERN) - @q.push [ :QUESTION, [@s.pos, nil] ] - when @s.scan(COMMA_PATTERN) - @q.push [ :COMMA, [@s.pos, ','] ] - when @s.scan(LPAREN_PATTERN) - @q.push [ :LPAREN, [@s.pos, '('] ] - when @s.scan(RPAREN_PATTERN) - @q.push [ :RPAREN, [@s.pos, ')'] ] - when @s.scan(ELSE_PATTERN) - @q.push [ :ELSE, [@s.pos, nil] ] - when @s.scan(ACTUAL_COMMENT_PATTERN) - @q.push [ :ACTUAL_COMMENT, [@s.pos, @s[1], @s[2]] ] if @preserve_comment - when @s.scan(BEGIN_END_PATTERN) - @q.push [ @s[2].intern, [@s.pos, nil] ] - when @s.scan(CONDITIONAL_PATTERN) - @q.push [ @s[2].intern, [@s.pos, @s[3]] ] - when @s.scan(EMBED_VARIABLE_PATTERN) - @q.push [ :EMBED_VARIABLE, [@s.pos, @s[2]] ] - when @s.scan(PAREN_BIND_VARIABLE_PATTERN) - @q.push [ :PAREN_BIND_VARIABLE, [@s.pos, @s[2]] ] - when @s.scan(BIND_VARIABLE_PATTERN) - @q.push [ :BIND_VARIABLE, [@s.pos, @s[2]] ] - when @s.scan(STRING_LITERAL_PATTERN) - @q.push [ :STRING_LITERAL, [@s.pos, @s[1]] ] - when @s.scan(SPLIT_TOKEN_PATTERN) - @q.push [ :IDENT, [@s.pos, @s[1]] ] - when @s.scan(UNMATCHED_COMMENT_START_PATTERN) ## unmatched comment start, '/*','#*' - raise Racc::ParseError, "unmatched comment. line:[#{line_no(@s.pos)}], str:[#{@s.rest}]" - when @s.scan(LITERAL_PATTERN) ## other string token - @q.push [ :IDENT, [@s.pos, @s[1]] ] - when @s.scan(SEMICOLON_AT_INPUT_END_PATTERN) - #drop semicolon at input end - else - raise Racc::ParseError, "syntax error at or near line:[#{line_no(@s.pos)}], str:[#{@s.rest}]" - end - end -end - - -## override racc's default on_error method -def on_error(t, v, vstack) - ## cursor in value-stack is an array of two items, - ## that have position value as 0th item. like [731, "ctx[:limit] "] - cursor = vstack.find do |tokens| - tokens.size == 2 and tokens[0].kind_of?(Fixnum) - end - pos = cursor[0] - line = line_no(pos) - rest = @s.string[pos .. -1] - raise Racc::ParseError, "syntax error at or near line:[#{line}], str:[#{rest}]" -end - - -def line_no(pos) - lines = 0 - scanned = @s.string[0..(pos)] - scanned.each_line { lines += 1 } - lines -end diff --git a/test/racc/assets/unterm.y b/test/racc/assets/unterm.y deleted file mode 100644 index 518acc7f31..0000000000 --- a/test/racc/assets/unterm.y +++ /dev/null @@ -1,5 +0,0 @@ -# unterminated action - -class A -rule - a: A { diff --git a/test/racc/assets/useless.y b/test/racc/assets/useless.y deleted file mode 100644 index 3f172e341c..0000000000 --- a/test/racc/assets/useless.y +++ /dev/null @@ -1,12 +0,0 @@ - - -class A -token A B C X -rule - -targ : A list B - | A B C - -list: list X - -end diff --git a/test/racc/assets/yyerr.y b/test/racc/assets/yyerr.y deleted file mode 100644 index 9faae89a79..0000000000 --- a/test/racc/assets/yyerr.y +++ /dev/null @@ -1,46 +0,0 @@ -# -# yyerror/yyerrok/yyaccept test -# - -class A -rule - -target: a b c - -a: - { - yyerror - raise ArgumentError, "yyerror failed" - } - | error - -b: - { - yyerrok - } - -c: - { - yyaccept - raise ArgumentError, "yyaccept failed" - } - -end - ----- inner - - def parse - do_parse - end - - def next_token - [false, '$end'] - end - - def on_error( *args ) - $stderr.puts "on_error called: args=#{args.inspect}" - end - ----- footer - -A.new.parse |