diff --git a/code/parser/bison_source.txt b/code/parser/bison_source.txt index d58522db..b3ba1d42 100644 --- a/code/parser/bison_source.txt +++ b/code/parser/bison_source.txt @@ -1,7 +1,7 @@ %{ /* * =========================================================================== -* Copyright (C) 2015 the OpenMoHAA team +* Copyright (C) 2025 the OpenMoHAA team * * This file is part of OpenMoHAA source code. * @@ -57,7 +57,7 @@ int success_pos; %precedence TOKEN_EOL %union { - stype_t s; + stype_t s; } %left TOKEN_COMMA @@ -71,11 +71,11 @@ int success_pos; %left TOKEN_LEFT_BRACKET TOKEN_RIGHT_BRACKET %token TOKEN_LEFT_SQUARE_BRACKET TOKEN_RIGHT_SQUARE_BRACKET -%right TOKEN_ASSIGNMENT - TOKEN_PLUS_EQUALS TOKEN_MINUS_EQUALS TOKEN_MULTIPLY_EQUALS TOKEN_DIVIDE_EQUALS TOKEN_MODULUS_EQUALS - TOKEN_AND_EQUALS TOKEN_EXCL_OR_EQUALS TOKEN_OR_EQUALS - TOKEN_SHIFT_LEFT_EQUALS TOKEN_SHIFT_RIGHT_EQUALS - TOKEN_TERNARY TOKEN_COLON +%right TOKEN_ASSIGNMENT + TOKEN_PLUS_EQUALS TOKEN_MINUS_EQUALS TOKEN_MULTIPLY_EQUALS TOKEN_DIVIDE_EQUALS TOKEN_MODULUS_EQUALS + TOKEN_AND_EQUALS TOKEN_EXCL_OR_EQUALS TOKEN_OR_EQUALS + TOKEN_SHIFT_LEFT_EQUALS TOKEN_SHIFT_RIGHT_EQUALS + TOKEN_TERNARY TOKEN_COLON %left TOKEN_LOGICAL_OR %left TOKEN_LOGICAL_AND @@ -109,12 +109,12 @@ int success_pos; %right TOKEN_INCREMENT TOKEN_DECREMENT TOKEN_NEG TOKEN_NOT TOKEN_COMPLEMENT %left TOKEN_LEFT_SQUARE_BRACKET TOKEN_RIGHT_SQUARE_BRACKET TOKEN_PERIOD -%precedence TOKEN_CATCH TOKEN_TRY - TOKEN_SWITCH TOKEN_CASE - TOKEN_BREAK TOKEN_CONTINUE - TOKEN_SIZE - TOKEN_END TOKEN_RETURN - TOKEN_MAKEARRAY TOKEN_ENDARRAY +%precedence TOKEN_CATCH TOKEN_TRY + TOKEN_SWITCH TOKEN_CASE + TOKEN_BREAK TOKEN_CONTINUE + TOKEN_SIZE + TOKEN_END TOKEN_RETURN + TOKEN_MAKEARRAY TOKEN_ENDARRAY %type event_parameter_list event_parameter_list_need event_parameter %type statement_list statement statement_declaration makearray_statement_list makearray_statement statement_for_condition @@ -135,207 +135,207 @@ int success_pos; %% program - : statement_list[list] { parsedata.val = node1(ENUM_statement_list, $list); } - | line_opt { parsedata.val = node0(ENUM_NOP); } - ; + : statement_list[list] { parsedata.val = node1(ENUM_statement_list, $list); } + | line_opt { parsedata.val = node0(ENUM_NOP); } + ; statement_list - : statement { $$ = linked_list_end($1); } - | statement_list statement[stmt] { $$ = append_node($1, $stmt); } - ; + : statement { $$ = linked_list_end($1); } + | statement_list statement[stmt] { $$ = append_node($1, $stmt); } + ; statement - : line_opt statement_declaration[stmt_decl] line_opt { $$ = $stmt_decl; } - ; + : line_opt statement_declaration[stmt_decl] line_opt { $$ = $stmt_decl; } + ; statement_declaration - : TOKEN_IDENTIFIER event_parameter_list TOKEN_COLON { $$ = node3(ENUM_labeled_statement, $1, $2, TOKPOS(@1)); } - | TOKEN_CASE prim_expr event_parameter_list TOKEN_COLON { $$ = node3(ENUM_int_labeled_statement, $2, $3, TOKPOS(@1)); } - | compound_statement - | selection_statement - | iteration_statement - | TOKEN_TRY compound_statement[C1] TOKEN_CATCH compound_statement[C2] { $$ = node3(ENUM_try, $C1, $C2, TOKPOS(@1)); } - | TOKEN_BREAK { $$ = node1(ENUM_break, TOKPOS(@1)); } - | TOKEN_CONTINUE { $$ = node1(ENUM_continue, TOKPOS(@1)); } - | TOKEN_IDENTIFIER event_parameter_list { $$ = node3(ENUM_cmd_event_statement, $1, $2, TOKPOS(@1)); } - | nonident_prim_expr TOKEN_IDENTIFIER event_parameter_list { $$ = node4(ENUM_method_event_statement, $1, $2, $3, TOKPOS(@2)); } - | nonident_prim_expr TOKEN_ASSIGNMENT expr { $$ = node3(ENUM_assignment_statement, $1, $3, TOKPOS(@2)); } - | nonident_prim_expr TOKEN_PLUS_EQUALS expr { $$ = node3(ENUM_assignment_statement, $1, node4(ENUM_func2_expr, node1b(OP_BIN_PLUS), $1, $3, TOKPOS(@2)), TOKPOS(@2)); } - | nonident_prim_expr TOKEN_MINUS_EQUALS expr { $$ = node3(ENUM_assignment_statement, $1, node4(ENUM_func2_expr, node1b(OP_BIN_MINUS), $1, $3, TOKPOS(@2)), TOKPOS(@2)); } - | nonident_prim_expr TOKEN_MULTIPLY_EQUALS expr { $$ = node3(ENUM_assignment_statement, $1, node4(ENUM_func2_expr, node1b(OP_BIN_MULTIPLY), $1, $3, TOKPOS(@2)), TOKPOS(@2)); } - | nonident_prim_expr TOKEN_DIVIDE_EQUALS expr { $$ = node3(ENUM_assignment_statement, $1, node4(ENUM_func2_expr, node1b(OP_BIN_DIVIDE), $1, $3, TOKPOS(@2)), TOKPOS(@2)); } - | nonident_prim_expr TOKEN_MODULUS_EQUALS expr { $$ = node3(ENUM_assignment_statement, $1, node4(ENUM_func2_expr, node1b(OP_BIN_PERCENTAGE), $1, $3, TOKPOS(@2)), TOKPOS(@2)); } - | nonident_prim_expr TOKEN_AND_EQUALS expr { $$ = node3(ENUM_assignment_statement, $1, node4(ENUM_func2_expr, node1b(OP_BIN_BITWISE_AND), $1, $3, TOKPOS(@2)), TOKPOS(@2)); } - | nonident_prim_expr TOKEN_EXCL_OR_EQUALS expr { $$ = node3(ENUM_assignment_statement, $1, node4(ENUM_func2_expr, node1b(OP_BIN_BITWISE_EXCL_OR), $1, $3, TOKPOS(@2)), TOKPOS(@2)); } - | nonident_prim_expr TOKEN_OR_EQUALS expr { $$ = node3(ENUM_assignment_statement, $1, node4(ENUM_func2_expr, node1b(OP_BIN_BITWISE_OR), $1, $3, TOKPOS(@2)), TOKPOS(@2)); } - | nonident_prim_expr TOKEN_SHIFT_LEFT_EQUALS expr { $$ = node3(ENUM_assignment_statement, $1, node4(ENUM_func2_expr, node1b(OP_BIN_SHIFT_LEFT), $1, $3, TOKPOS(@2)), TOKPOS(@2)); } - | nonident_prim_expr TOKEN_SHIFT_RIGHT_EQUALS expr { $$ = node3(ENUM_assignment_statement, $1, node4(ENUM_func2_expr, node1b(OP_BIN_SHIFT_RIGHT), $1, $3, TOKPOS(@2)), TOKPOS(@2)); } - | nonident_prim_expr TOKEN_INCREMENT { $$ = node3(ENUM_assignment_statement, $1, node3(ENUM_func1_expr, node1b(OP_UN_INC), $1, TOKPOS(@2)), TOKPOS(@2)); } - | nonident_prim_expr TOKEN_DECREMENT { $$ = node3(ENUM_assignment_statement, $1, node3(ENUM_func1_expr, node1b(OP_UN_DEC), $1, TOKPOS(@2)), TOKPOS(@2)); } - | TOKEN_SEMICOLON { $$ = node0(ENUM_NOP); } - //| TOKEN_IDENTIFIER TOKEN_DOUBLE_COLON TOKEN_IDENTIFIER event_parameter_list { $$ = node3( ENUM_method_event_statement, node_string( parsetree_string( str( $1.stringValue ) + "::" + $3.stringValue ) ), node1( ENUM_NOP, $4 ), TOKPOS(@1) ); } - //| nonident_prim_expr TOKEN_IDENTIFIER TOKEN_DOUBLE_COLON TOKEN_IDENTIFIER event_parameter_list { $$ = node4( ENUM_method_event_statement, $1, node_string( parsetree_string( str( $2.stringValue ) + "::" + $4.stringValue ) ), node1( ENUM_NOP, $5 ), TOKPOS(@2) ); } - ; - + : TOKEN_IDENTIFIER event_parameter_list TOKEN_COLON { $$ = node3(ENUM_labeled_statement, $1, $2, TOKPOS(@1)); } + | TOKEN_CASE prim_expr event_parameter_list TOKEN_COLON { $$ = node3(ENUM_int_labeled_statement, $2, $3, TOKPOS(@1)); } + | compound_statement + | selection_statement + | iteration_statement + | TOKEN_TRY compound_statement[C1] TOKEN_CATCH compound_statement[C2] { $$ = node3(ENUM_try, $C1, $C2, TOKPOS(@1)); } + | TOKEN_BREAK { $$ = node1(ENUM_break, TOKPOS(@1)); } + | TOKEN_CONTINUE { $$ = node1(ENUM_continue, TOKPOS(@1)); } + | TOKEN_IDENTIFIER event_parameter_list { $$ = node3(ENUM_cmd_event_statement, $1, $2, TOKPOS(@1)); } + | nonident_prim_expr TOKEN_IDENTIFIER event_parameter_list { $$ = node4(ENUM_method_event_statement, $1, $2, $3, TOKPOS(@2)); } + | nonident_prim_expr TOKEN_ASSIGNMENT expr { $$ = node3(ENUM_assignment_statement, $1, $3, TOKPOS(@2)); } + | nonident_prim_expr TOKEN_PLUS_EQUALS expr { $$ = node3(ENUM_assignment_statement, $1, node4(ENUM_func2_expr, node1b(OP_BIN_PLUS), $1, $3, TOKPOS(@2)), TOKPOS(@2)); } + | nonident_prim_expr TOKEN_MINUS_EQUALS expr { $$ = node3(ENUM_assignment_statement, $1, node4(ENUM_func2_expr, node1b(OP_BIN_MINUS), $1, $3, TOKPOS(@2)), TOKPOS(@2)); } + | nonident_prim_expr TOKEN_MULTIPLY_EQUALS expr { $$ = node3(ENUM_assignment_statement, $1, node4(ENUM_func2_expr, node1b(OP_BIN_MULTIPLY), $1, $3, TOKPOS(@2)), TOKPOS(@2)); } + | nonident_prim_expr TOKEN_DIVIDE_EQUALS expr { $$ = node3(ENUM_assignment_statement, $1, node4(ENUM_func2_expr, node1b(OP_BIN_DIVIDE), $1, $3, TOKPOS(@2)), TOKPOS(@2)); } + | nonident_prim_expr TOKEN_MODULUS_EQUALS expr { $$ = node3(ENUM_assignment_statement, $1, node4(ENUM_func2_expr, node1b(OP_BIN_PERCENTAGE), $1, $3, TOKPOS(@2)), TOKPOS(@2)); } + | nonident_prim_expr TOKEN_AND_EQUALS expr { $$ = node3(ENUM_assignment_statement, $1, node4(ENUM_func2_expr, node1b(OP_BIN_BITWISE_AND), $1, $3, TOKPOS(@2)), TOKPOS(@2)); } + | nonident_prim_expr TOKEN_EXCL_OR_EQUALS expr { $$ = node3(ENUM_assignment_statement, $1, node4(ENUM_func2_expr, node1b(OP_BIN_BITWISE_EXCL_OR), $1, $3, TOKPOS(@2)), TOKPOS(@2)); } + | nonident_prim_expr TOKEN_OR_EQUALS expr { $$ = node3(ENUM_assignment_statement, $1, node4(ENUM_func2_expr, node1b(OP_BIN_BITWISE_OR), $1, $3, TOKPOS(@2)), TOKPOS(@2)); } + | nonident_prim_expr TOKEN_SHIFT_LEFT_EQUALS expr { $$ = node3(ENUM_assignment_statement, $1, node4(ENUM_func2_expr, node1b(OP_BIN_SHIFT_LEFT), $1, $3, TOKPOS(@2)), TOKPOS(@2)); } + | nonident_prim_expr TOKEN_SHIFT_RIGHT_EQUALS expr { $$ = node3(ENUM_assignment_statement, $1, node4(ENUM_func2_expr, node1b(OP_BIN_SHIFT_RIGHT), $1, $3, TOKPOS(@2)), TOKPOS(@2)); } + | nonident_prim_expr TOKEN_INCREMENT { $$ = node3(ENUM_assignment_statement, $1, node3(ENUM_func1_expr, node1b(OP_UN_INC), $1, TOKPOS(@2)), TOKPOS(@2)); } + | nonident_prim_expr TOKEN_DECREMENT { $$ = node3(ENUM_assignment_statement, $1, node3(ENUM_func1_expr, node1b(OP_UN_DEC), $1, TOKPOS(@2)), TOKPOS(@2)); } + | TOKEN_SEMICOLON { $$ = node0(ENUM_NOP); } + //| TOKEN_IDENTIFIER TOKEN_DOUBLE_COLON TOKEN_IDENTIFIER event_parameter_list { $$ = node3( ENUM_method_event_statement, node_string( parsetree_string( str( $1.stringValue ) + "::" + $3.stringValue ) ), node1( ENUM_NOP, $4 ), TOKPOS(@1) ); } + //| nonident_prim_expr TOKEN_IDENTIFIER TOKEN_DOUBLE_COLON TOKEN_IDENTIFIER event_parameter_list { $$ = node4( ENUM_method_event_statement, $1, node_string( parsetree_string( str( $2.stringValue ) + "::" + $4.stringValue ) ), node1( ENUM_NOP, $5 ), TOKPOS(@2) ); } + ; + statement_for_condition - : line_opt statement_declaration[stmt_decl] line_opt { $$ = $stmt_decl; } - | line_opt statement_declaration[stmt_decl] TOKEN_SEMICOLON line_opt { $$ = $stmt_decl; } - ; + : line_opt statement_declaration[stmt_decl] line_opt { $$ = $stmt_decl; } + | line_opt statement_declaration[stmt_decl] TOKEN_SEMICOLON line_opt { $$ = $stmt_decl; } + ; compound_statement - : TOKEN_LEFT_BRACES statement_list TOKEN_RIGHT_BRACES { $$ = node1(ENUM_statement_list, $2); } - | TOKEN_LEFT_BRACES line_opt TOKEN_RIGHT_BRACES { $$ = node0(ENUM_NOP); } - | line_opt compound_statement[comp_stmt] line_opt { $$ = $comp_stmt; } - ; + : TOKEN_LEFT_BRACES statement_list TOKEN_RIGHT_BRACES { $$ = node1(ENUM_statement_list, $2); } + | TOKEN_LEFT_BRACES line_opt TOKEN_RIGHT_BRACES { $$ = node0(ENUM_NOP); } + | line_opt compound_statement[comp_stmt] line_opt { $$ = $comp_stmt; } + ; selection_statement - : TOKEN_IF prim_expr[exp] statement_for_condition[stmt] %prec THEN { $$ = node3(ENUM_if_statement, $exp, $stmt, TOKPOS(@1)); } - | TOKEN_IF prim_expr[exp] statement_for_condition[if_stmt] TOKEN_ELSE statement_for_condition[else_stmt] { $$ = node4(ENUM_if_else_statement, $exp, $if_stmt, $else_stmt, TOKPOS(@1)); } - | TOKEN_SWITCH prim_expr[exp] compound_statement[comp_stmt] { $$ = node3(ENUM_switch, $exp, $comp_stmt, TOKPOS(@1)); } - ; + : TOKEN_IF prim_expr[exp] statement_for_condition[stmt] %prec THEN { $$ = node3(ENUM_if_statement, $exp, $stmt, TOKPOS(@1)); } + | TOKEN_IF prim_expr[exp] statement_for_condition[if_stmt] TOKEN_ELSE statement_for_condition[else_stmt] { $$ = node4(ENUM_if_else_statement, $exp, $if_stmt, $else_stmt, TOKPOS(@1)); } + | TOKEN_SWITCH prim_expr[exp] compound_statement[comp_stmt] { $$ = node3(ENUM_switch, $exp, $comp_stmt, TOKPOS(@1)); } + ; iteration_statement - : TOKEN_WHILE prim_expr[exp] statement_for_condition[stmt]{ $$ = node4(ENUM_while_statement, $exp, $stmt, node0(ENUM_NOP), TOKPOS(@1)); } - | TOKEN_FOR TOKEN_LEFT_BRACKET statement[init_stmt] TOKEN_SEMICOLON expr[exp] TOKEN_SEMICOLON statement_list[inc_stmt] TOKEN_RIGHT_BRACKET statement_for_condition[stmt] - { - sval_t while_stmt = node4(ENUM_while_statement, $exp, $stmt, node1(ENUM_statement_list, $inc_stmt), TOKPOS(@1)); - $$ = node1(ENUM_statement_list, append_node(linked_list_end($init_stmt), while_stmt)); - } - | TOKEN_FOR TOKEN_LEFT_BRACKET TOKEN_SEMICOLON expr[exp] TOKEN_SEMICOLON statement_list[inc_stmt] TOKEN_RIGHT_BRACKET statement_for_condition[stmt] - { - $$ = node4(ENUM_while_statement, $exp, $stmt, node1(ENUM_statement_list, $inc_stmt), TOKPOS(@1)); - } - | TOKEN_DO statement_for_condition[stmt] TOKEN_WHILE prim_expr[exp]{ $$ = node3(ENUM_do, $stmt, $exp, TOKPOS(@1)); } - ; + : TOKEN_WHILE prim_expr[exp] statement_for_condition[stmt]{ $$ = node4(ENUM_while_statement, $exp, $stmt, node0(ENUM_NOP), TOKPOS(@1)); } + | TOKEN_FOR TOKEN_LEFT_BRACKET statement[init_stmt] TOKEN_SEMICOLON expr[exp] TOKEN_SEMICOLON statement_list[inc_stmt] TOKEN_RIGHT_BRACKET statement_for_condition[stmt] + { + sval_t while_stmt = node4(ENUM_while_statement, $exp, $stmt, node1(ENUM_statement_list, $inc_stmt), TOKPOS(@1)); + $$ = node1(ENUM_statement_list, append_node(linked_list_end($init_stmt), while_stmt)); + } + | TOKEN_FOR TOKEN_LEFT_BRACKET TOKEN_SEMICOLON expr[exp] TOKEN_SEMICOLON statement_list[inc_stmt] TOKEN_RIGHT_BRACKET statement_for_condition[stmt] + { + $$ = node4(ENUM_while_statement, $exp, $stmt, node1(ENUM_statement_list, $inc_stmt), TOKPOS(@1)); + } + | TOKEN_DO statement_for_condition[stmt] TOKEN_WHILE prim_expr[exp]{ $$ = node3(ENUM_do, $stmt, $exp, TOKPOS(@1)); } + ; expr: - expr TOKEN_LOGICAL_AND expr { $$ = node3( ENUM_logical_and, $1, $3, TOKPOS(@2) ); } - | expr TOKEN_LOGICAL_OR expr { $$ = node3( ENUM_logical_or, $1, $3, TOKPOS(@2) ); } - | expr TOKEN_BITWISE_AND expr { $$ = node4( ENUM_func2_expr, node1b( OP_BIN_BITWISE_AND ), $1, $3, TOKPOS(@2) ); } - | expr TOKEN_BITWISE_OR expr { $$ = node4( ENUM_func2_expr, node1b( OP_BIN_BITWISE_OR ), $1, $3, TOKPOS(@2) ); } - | expr TOKEN_BITWISE_EXCL_OR expr { $$ = node4( ENUM_func2_expr, node1b( OP_BIN_BITWISE_EXCL_OR ), $1, $3, TOKPOS(@2) ); } - | expr TOKEN_EQUALITY expr { $$ = node4( ENUM_func2_expr, node1b( OP_BIN_EQUALITY ), $1, $3, TOKPOS(@2) ); } - | expr TOKEN_INEQUALITY expr { $$ = node4( ENUM_func2_expr, node1b( OP_BIN_INEQUALITY ), $1, $3, TOKPOS(@2) ); } - | expr TOKEN_LESS_THAN expr { $$ = node4( ENUM_func2_expr, node1b( OP_BIN_LESS_THAN ), $1, $3, TOKPOS(@2) ); } - | expr TOKEN_GREATER_THAN expr { $$ = node4( ENUM_func2_expr, node1b( OP_BIN_GREATER_THAN ), $1, $3, TOKPOS(@2) ); } - | expr TOKEN_LESS_THAN_OR_EQUAL expr { $$ = node4( ENUM_func2_expr, node1b( OP_BIN_LESS_THAN_OR_EQUAL ), $1, $3, TOKPOS(@2) ); } - | expr TOKEN_GREATER_THAN_OR_EQUAL expr { $$ = node4( ENUM_func2_expr, node1b( OP_BIN_GREATER_THAN_OR_EQUAL ), $1, $3, TOKPOS(@2) ); } - | expr TOKEN_PLUS expr { $$ = node4( ENUM_func2_expr, node1b( OP_BIN_PLUS ), $1, $3, TOKPOS(@2) ); } - | expr TOKEN_MINUS expr { $$ = node4( ENUM_func2_expr, node1b( OP_BIN_MINUS ), $1, $3, TOKPOS(@2) ); } - | expr TOKEN_MULTIPLY expr { $$ = node4( ENUM_func2_expr, node1b( OP_BIN_MULTIPLY ), $1, $3, TOKPOS(@2) ); } - | expr TOKEN_DIVIDE expr { $$ = node4( ENUM_func2_expr, node1b( OP_BIN_DIVIDE ), $1, $3, TOKPOS(@2) ); } - | expr TOKEN_MODULUS expr { $$ = node4( ENUM_func2_expr, node1b( OP_BIN_PERCENTAGE ), $1, $3, TOKPOS(@2) ); } - | expr TOKEN_SHIFT_LEFT expr { $$ = node4( ENUM_func2_expr, node1b( OP_BIN_SHIFT_LEFT ), $1, $3, TOKPOS(@2) ); } - | expr TOKEN_SHIFT_RIGHT expr { $$ = node4( ENUM_func2_expr, node1b( OP_BIN_SHIFT_RIGHT ), $1, $3, TOKPOS(@2) ); } - | expr TOKEN_TERNARY expr TOKEN_COLON expr { $$ = node4( ENUM_if_else_statement, $1, $3, $5, TOKPOS(@2) ); } - | TOKEN_EOL expr[exp] { $$ = $exp; } - | nonident_prim_expr - | func_prim_expr - | TOKEN_IDENTIFIER { $$ = node2(ENUM_string, $1, TOKPOS(@1)); } - ; + expr TOKEN_LOGICAL_AND expr { $$ = node3( ENUM_logical_and, $1, $3, TOKPOS(@2) ); } + | expr TOKEN_LOGICAL_OR expr { $$ = node3( ENUM_logical_or, $1, $3, TOKPOS(@2) ); } + | expr TOKEN_BITWISE_AND expr { $$ = node4( ENUM_func2_expr, node1b( OP_BIN_BITWISE_AND ), $1, $3, TOKPOS(@2) ); } + | expr TOKEN_BITWISE_OR expr { $$ = node4( ENUM_func2_expr, node1b( OP_BIN_BITWISE_OR ), $1, $3, TOKPOS(@2) ); } + | expr TOKEN_BITWISE_EXCL_OR expr { $$ = node4( ENUM_func2_expr, node1b( OP_BIN_BITWISE_EXCL_OR ), $1, $3, TOKPOS(@2) ); } + | expr TOKEN_EQUALITY expr { $$ = node4( ENUM_func2_expr, node1b( OP_BIN_EQUALITY ), $1, $3, TOKPOS(@2) ); } + | expr TOKEN_INEQUALITY expr { $$ = node4( ENUM_func2_expr, node1b( OP_BIN_INEQUALITY ), $1, $3, TOKPOS(@2) ); } + | expr TOKEN_LESS_THAN expr { $$ = node4( ENUM_func2_expr, node1b( OP_BIN_LESS_THAN ), $1, $3, TOKPOS(@2) ); } + | expr TOKEN_GREATER_THAN expr { $$ = node4( ENUM_func2_expr, node1b( OP_BIN_GREATER_THAN ), $1, $3, TOKPOS(@2) ); } + | expr TOKEN_LESS_THAN_OR_EQUAL expr { $$ = node4( ENUM_func2_expr, node1b( OP_BIN_LESS_THAN_OR_EQUAL ), $1, $3, TOKPOS(@2) ); } + | expr TOKEN_GREATER_THAN_OR_EQUAL expr { $$ = node4( ENUM_func2_expr, node1b( OP_BIN_GREATER_THAN_OR_EQUAL ), $1, $3, TOKPOS(@2) ); } + | expr TOKEN_PLUS expr { $$ = node4( ENUM_func2_expr, node1b( OP_BIN_PLUS ), $1, $3, TOKPOS(@2) ); } + | expr TOKEN_MINUS expr { $$ = node4( ENUM_func2_expr, node1b( OP_BIN_MINUS ), $1, $3, TOKPOS(@2) ); } + | expr TOKEN_MULTIPLY expr { $$ = node4( ENUM_func2_expr, node1b( OP_BIN_MULTIPLY ), $1, $3, TOKPOS(@2) ); } + | expr TOKEN_DIVIDE expr { $$ = node4( ENUM_func2_expr, node1b( OP_BIN_DIVIDE ), $1, $3, TOKPOS(@2) ); } + | expr TOKEN_MODULUS expr { $$ = node4( ENUM_func2_expr, node1b( OP_BIN_PERCENTAGE ), $1, $3, TOKPOS(@2) ); } + | expr TOKEN_SHIFT_LEFT expr { $$ = node4( ENUM_func2_expr, node1b( OP_BIN_SHIFT_LEFT ), $1, $3, TOKPOS(@2) ); } + | expr TOKEN_SHIFT_RIGHT expr { $$ = node4( ENUM_func2_expr, node1b( OP_BIN_SHIFT_RIGHT ), $1, $3, TOKPOS(@2) ); } + | expr TOKEN_TERNARY expr TOKEN_COLON expr { $$ = node4( ENUM_if_else_statement, $1, $3, $5, TOKPOS(@2) ); } + | TOKEN_EOL expr[exp] { $$ = $exp; } + | nonident_prim_expr + | func_prim_expr + | TOKEN_IDENTIFIER { $$ = node2(ENUM_string, $1, TOKPOS(@1)); } + ; func_prim_expr: - TOKEN_IDENTIFIER event_parameter_list_need { $$ = node3(ENUM_cmd_event_expr, $1, $2, TOKPOS(@1)); } - | nonident_prim_expr_base TOKEN_IDENTIFIER event_parameter_list { $$ = node4(ENUM_method_event_expr, $1, $2, $3, TOKPOS(@2)); } - | TOKEN_NEG func_prim_expr { $$ = node3(ENUM_func1_expr, node1b(OP_UN_MINUS), $2, TOKPOS(@1)); } - | TOKEN_COMPLEMENT func_prim_expr { $$ = node3(ENUM_func1_expr, node1b(OP_UN_COMPLEMENT), $2, TOKPOS(@1)); } - | TOKEN_NOT func_prim_expr { $$ = node2(ENUM_bool_not, $2, TOKPOS(@1)); } - | TOKEN_IDENTIFIER TOKEN_DOUBLE_COLON const_array_list - { - $$ = node3(ENUM_const_array_expr, node2(ENUM_string, $1, TOKPOS(@1)), $3, TOKPOS(@2)); - } - | nonident_prim_expr TOKEN_DOUBLE_COLON const_array_list - { - $$ = node3(ENUM_const_array_expr, $1, $3, TOKPOS(@2)); - } - | TOKEN_MAKEARRAY makearray_statement_list[stmt] TOKEN_ENDARRAY - { - $$ = node2(ENUM_makearray, $stmt, TOKPOS(@1)); - } - ; + TOKEN_IDENTIFIER event_parameter_list_need { $$ = node3(ENUM_cmd_event_expr, $1, $2, TOKPOS(@1)); } + | nonident_prim_expr_base TOKEN_IDENTIFIER event_parameter_list { $$ = node4(ENUM_method_event_expr, $1, $2, $3, TOKPOS(@2)); } + | TOKEN_NEG func_prim_expr { $$ = node3(ENUM_func1_expr, node1b(OP_UN_MINUS), $2, TOKPOS(@1)); } + | TOKEN_COMPLEMENT func_prim_expr { $$ = node3(ENUM_func1_expr, node1b(OP_UN_COMPLEMENT), $2, TOKPOS(@1)); } + | TOKEN_NOT func_prim_expr { $$ = node2(ENUM_bool_not, $2, TOKPOS(@1)); } + | TOKEN_IDENTIFIER TOKEN_DOUBLE_COLON const_array_list + { + $$ = node3(ENUM_const_array_expr, node2(ENUM_string, $1, TOKPOS(@1)), $3, TOKPOS(@2)); + } + | nonident_prim_expr TOKEN_DOUBLE_COLON const_array_list + { + $$ = node3(ENUM_const_array_expr, $1, $3, TOKPOS(@2)); + } + | TOKEN_MAKEARRAY makearray_statement_list[stmt] TOKEN_ENDARRAY + { + $$ = node2(ENUM_makearray, $stmt, TOKPOS(@1)); + } + ; event_parameter_list - : { $$ = sval_u{}; $$.node = NULL; } - | event_parameter { $$ = $1; } - ; + : { $$ = sval_u{}; $$.node = NULL; } + | event_parameter { $$ = $1; } + ; event_parameter_list_need - : event_parameter { $$ = $1; } - ; + : event_parameter { $$ = $1; } + ; event_parameter - : prim_expr { $$ = linked_list_end($1); } - | event_parameter prim_expr { $$ = append_node($1, $2); } - ; + : prim_expr { $$ = linked_list_end($1); } + | event_parameter prim_expr { $$ = append_node($1, $2); } + ; const_array_list - : const_array { $$ = linked_list_end($1); } - | const_array_list TOKEN_DOUBLE_COLON const_array { $$ = append_node($1, $3); } - ; + : const_array { $$ = linked_list_end($1); } + | const_array_list TOKEN_DOUBLE_COLON const_array { $$ = append_node($1, $3); } + ; const_array - : nonident_prim_expr - | identifier_prim { $$ = node2(ENUM_string, $1, TOKPOS(@1)); } - ; + : nonident_prim_expr + | identifier_prim { $$ = node2(ENUM_string, $1, TOKPOS(@1)); } + ; prim_expr - : nonident_prim_expr - | identifier_prim { $$ = node2(ENUM_string, $1, TOKPOS(@1)); } - | const_array TOKEN_DOUBLE_COLON const_array_list { $$ = node3(ENUM_const_array_expr, $1, $3, TOKPOS(@2)); } - ; + : nonident_prim_expr + | identifier_prim { $$ = node2(ENUM_string, $1, TOKPOS(@1)); } + | const_array TOKEN_DOUBLE_COLON const_array_list { $$ = node3(ENUM_const_array_expr, $1, $3, TOKPOS(@2)); } + ; identifier_prim: - TOKEN_IDENTIFIER { $$ = $1; @$ = @1; } - ; + TOKEN_IDENTIFIER { $$ = $1; @$ = @1; } + ; identifier - : TOKEN_IDENTIFIER { $$ = $1; @$ = @1; } - | TOKEN_STRING { $$ = $1; @$ = @1; } - ; + : TOKEN_IDENTIFIER { $$ = $1; @$ = @1; } + | TOKEN_STRING { $$ = $1; @$ = @1; } + ; listener_identifier - : identifier { $$ = node_listener($1, TOKPOS(@1)); } - | TOKEN_LEFT_BRACKET expr TOKEN_RIGHT_BRACKET { $$ = $2; } - ; + : identifier { $$ = node_listener($1, TOKPOS(@1)); } + | TOKEN_LEFT_BRACKET expr TOKEN_RIGHT_BRACKET { $$ = $2; } + ; nonident_prim_expr - : nonident_prim_expr_base - | TOKEN_NEG nonident_prim_expr { $$ = node3(ENUM_func1_expr, node1b(OP_UN_MINUS), $2, TOKPOS(@1)); } - | TOKEN_COMPLEMENT nonident_prim_expr { $$ = node3(ENUM_func1_expr, node1b(OP_UN_COMPLEMENT), $2, TOKPOS(@1)); } - | TOKEN_NOT nonident_prim_expr { $$ = node2(ENUM_bool_not, $2, TOKPOS(@1)); } - ; + : nonident_prim_expr_base + | TOKEN_NEG nonident_prim_expr { $$ = node3(ENUM_func1_expr, node1b(OP_UN_MINUS), $2, TOKPOS(@1)); } + | TOKEN_COMPLEMENT nonident_prim_expr { $$ = node3(ENUM_func1_expr, node1b(OP_UN_COMPLEMENT), $2, TOKPOS(@1)); } + | TOKEN_NOT nonident_prim_expr { $$ = node2(ENUM_bool_not, $2, TOKPOS(@1)); } + ; nonident_prim_expr_base - : TOKEN_DOLLAR listener_identifier { $$ = node3(ENUM_func1_expr, node1b(OP_UN_TARGETNAME), $2, TOKPOS(@1)); } - | nonident_prim_expr TOKEN_PERIOD identifier { $$ = node3(ENUM_field, $1, $3, TOKPOS(@3)); } - | nonident_prim_expr TOKEN_PERIOD TOKEN_SIZE { $$ = node3(ENUM_func1_expr, node1b(OP_UN_SIZE), $1, TOKPOS(@3)); } - | nonident_prim_expr TOKEN_LEFT_SQUARE_BRACKET expr TOKEN_RIGHT_SQUARE_BRACKET { $$ = node3(ENUM_array_expr, $1, $3, TOKPOS(@2)); } - | TOKEN_STRING { $$ = node2(ENUM_string, $1, TOKPOS(@1)); } - | TOKEN_INTEGER { $$ = node2(ENUM_integer, $1, TOKPOS(@1)); } - | TOKEN_FLOAT { $$ = node2(ENUM_float, $1, TOKPOS(@1)); } - | TOKEN_LEFT_BRACKET expr[exp1] expr[exp2] expr[exp3] TOKEN_RIGHT_BRACKET { $$ = node4(ENUM_vector, $exp1, $exp2, $exp3, TOKPOS(@1)); } - | TOKEN_LISTENER { $$ = node2(ENUM_listener, $1, TOKPOS(@1)); } - | TOKEN_LEFT_BRACKET expr TOKEN_RIGHT_BRACKET { $$ = $2; } - | TOKEN_LEFT_BRACKET expr TOKEN_EOL TOKEN_RIGHT_BRACKET { $$ = $2; } - | TOKEN_NULL { $$ = node1(ENUM_NULL, TOKPOS(@1)); } - | TOKEN_NIL { $$ = node1(ENUM_NIL, TOKPOS(@1)); } - ; + : TOKEN_DOLLAR listener_identifier { $$ = node3(ENUM_func1_expr, node1b(OP_UN_TARGETNAME), $2, TOKPOS(@1)); } + | nonident_prim_expr TOKEN_PERIOD identifier { $$ = node3(ENUM_field, $1, $3, TOKPOS(@3)); } + | nonident_prim_expr TOKEN_PERIOD TOKEN_SIZE { $$ = node3(ENUM_func1_expr, node1b(OP_UN_SIZE), $1, TOKPOS(@3)); } + | nonident_prim_expr TOKEN_LEFT_SQUARE_BRACKET expr TOKEN_RIGHT_SQUARE_BRACKET { $$ = node3(ENUM_array_expr, $1, $3, TOKPOS(@2)); } + | TOKEN_STRING { $$ = node2(ENUM_string, $1, TOKPOS(@1)); } + | TOKEN_INTEGER { $$ = node2(ENUM_integer, $1, TOKPOS(@1)); } + | TOKEN_FLOAT { $$ = node2(ENUM_float, $1, TOKPOS(@1)); } + | TOKEN_LEFT_BRACKET expr[exp1] expr[exp2] expr[exp3] TOKEN_RIGHT_BRACKET { $$ = node4(ENUM_vector, $exp1, $exp2, $exp3, TOKPOS(@1)); } + | TOKEN_LISTENER { $$ = node2(ENUM_listener, $1, TOKPOS(@1)); } + | TOKEN_LEFT_BRACKET expr TOKEN_RIGHT_BRACKET { $$ = $2; } + | TOKEN_LEFT_BRACKET expr TOKEN_EOL TOKEN_RIGHT_BRACKET { $$ = $2; } + | TOKEN_NULL { $$ = node1(ENUM_NULL, TOKPOS(@1)); } + | TOKEN_NIL { $$ = node1(ENUM_NIL, TOKPOS(@1)); } + ; makearray_statement_list: - { $$ = node0(ENUM_NOP); } - | makearray_statement_list[list] makearray_statement[ma_stmt] TOKEN_EOL { $$ = append_node($list, node2(ENUM_makearray, $ma_stmt, TOKPOS(@ma_stmt))); } - | makearray_statement[ma_stmt] TOKEN_EOL { $$ = linked_list_end(node2(ENUM_makearray, $ma_stmt, TOKPOS(@ma_stmt))); } - | TOKEN_EOL makearray_statement_list { $$ = $2; @$ = @2; } - ; + { $$ = node0(ENUM_NOP); } + | makearray_statement_list[list] makearray_statement[ma_stmt] TOKEN_EOL { $$ = append_node($list, node2(ENUM_makearray, $ma_stmt, TOKPOS(@ma_stmt))); } + | makearray_statement[ma_stmt] TOKEN_EOL { $$ = linked_list_end(node2(ENUM_makearray, $ma_stmt, TOKPOS(@ma_stmt))); } + | TOKEN_EOL makearray_statement_list { $$ = $2; @$ = @2; } + ; makearray_statement: - prim_expr { $$ = linked_list_end( $1 ); } - | makearray_statement prim_expr { $$ = append_node( $1, $2 ); } - ; + prim_expr { $$ = linked_list_end( $1 ); } + | makearray_statement prim_expr { $$ = append_node( $1, $2 ); } + ; line_opt - : {} - | TOKEN_EOL - ; + : {} + | TOKEN_EOL + ; %% diff --git a/code/parser/lex.yy.cpp b/code/parser/lex.yy.cpp index a7175203..225052d9 100644 --- a/code/parser/lex.yy.cpp +++ b/code/parser/lex.yy.cpp @@ -1,3 +1,28 @@ +/* +* =========================================================================== +* Copyright (C) 2025 the OpenMoHAA team +* +* This file is part of OpenMoHAA source code. +* +* OpenMoHAA source code is free software; you can redistribute it +* and/or modify it under the terms of the GNU General Public License as +* published by the Free Software Foundation; either version 2 of the License, +* or (at your option) any later version. +* +* OpenMoHAA source code is distributed in the hope that it will be +* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with OpenMoHAA source code; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +* =========================================================================== +* +* +* lex.yy.cpp: original lex generated file (unimplemented) +*/ + #include "scriptcompiler.h" #include diff --git a/code/parser/lex_source.txt b/code/parser/lex_source.txt index 6ae674fc..d97038b0 100644 --- a/code/parser/lex_source.txt +++ b/code/parser/lex_source.txt @@ -1,7 +1,7 @@ %{ /* * =========================================================================== -* Copyright (C) 2015 the OpenMoHAA team +* Copyright (C) 2025 the OpenMoHAA team * * This file is part of OpenMoHAA source code. * @@ -144,33 +144,29 @@ static bool UseField(void) return prev_yylex == TOKEN_PERIOD || prev_yylex == TOKEN_DOLLAR; } -#define YY_INPUT(buf,result,max_size) \ -{ \ - char c; \ - int n; \ - \ - c = '*'; \ - for(n = 0; n < max_size; n++) \ - { \ - c = *in_ptr++; \ - if (!c || c == '\n') { \ - break; \ - } \ - \ - buf[n] = c; \ - } \ - \ - if (c == '\n') \ - { \ - buf[n++] = c; \ - } \ - else if (!c) \ - { \ - in_ptr--; \ - } \ - \ - result = n; \ -} +#define YY_INPUT(buf, result, max_size) \ + { \ + char c; \ + int n; \ + \ + c = '*'; \ + for (n = 0; n < max_size; n++) { \ + c = *in_ptr++; \ + if (!c || c == '\n') { \ + break; \ + } \ + \ + buf[n] = c; \ + } \ + \ + if (c == '\n') { \ + buf[n++] = c; \ + } else if (!c) { \ + in_ptr--; \ + } \ + \ + result = n; \ + } %} @@ -187,195 +183,193 @@ static bool UseField(void) %x VARIABLES %x IDENTIFIER -string ([^\\\"\r\n]|\\.)* -identifier [^\{\}\(\)\[\]\r\n\,:; \t] -nonexpr [0-9a-zA-Z_\"'?@#`\.\x80-\xff] -nonnumeric [a-zA-Z_\"'?@#`\x80-\xff] -alphanum [a-zA-Z0-9_]+ -varname [a-zA-Z0-9_\"$\\]+ +string ([^\\\"\r\n]|\\.)* +identifier [^\{\}\(\)\[\]\r\n\,:; \t] +nonexpr [0-9a-zA-Z_\"'?@#`\.\x80-\xff] +nonnumeric [a-zA-Z_\"'?@#`\x80-\xff] +alphanum [a-zA-Z0-9_]+ +varname [a-zA-Z0-9_\"$\\]+ %% -"/*" { BEGIN( C_COMMENT ); } -"*/" { BEGIN( INITIAL ); } -\n { ; } -. { ; } -"*/" { Compiler.CompileError( parsedata.pos - yyleng, "'*/' found outside of comment" ); } +"/*" { BEGIN(C_COMMENT); } +"*/" { BEGIN(INITIAL); } +\n { ; } +. { ; } +"*/" { Compiler.CompileError( parsedata.pos - yyleng, "'*/' found outside of comment" ); } -\\[\r\n]+ { ; } -"//"[^\r\n]* { if( prev_yylex != TOKEN_EOL ) YYLEX( TOKEN_EOL ); } +\\[\r\n]+ { ; } +"//"[^\r\n]* { if(prev_yylex != TOKEN_EOL) YYLEX(TOKEN_EOL); } -"size" { BEGIN(INITIAL); YYLEX(TOKEN_SIZE); } -[ \t]*\./([0-9]*[^0-9[:space:]]) { YYLEX(TOKEN_PERIOD); } -\"{string}\" { BEGIN(INITIAL); TextEscapeValue(yytext + 1, strlen( yytext ) - 2 ); YYLEX(TOKEN_STRING); } -{varname} { - TextEscapeValue(yytext, strlen(yytext)); - YYLEX(TOKEN_IDENTIFIER); - } -[ \t\r\n] { - BEGIN(INITIAL); - unput(yytext[yyleng - 1]); - yyreducepos(1); - } -. { - BEGIN(INITIAL); - unput(yytext[yyleng - 1]); - yyreducepos(1); - } +"size" { BEGIN(INITIAL); YYLEX(TOKEN_SIZE); } +[ \t]*\./([0-9]*[^0-9[:space:]]) { YYLEX(TOKEN_PERIOD); } +\"{string}\" { BEGIN(INITIAL); TextEscapeValue(yytext + 1, strlen( yytext ) - 2 ); YYLEX(TOKEN_STRING); } +{varname} { + TextEscapeValue(yytext, strlen(yytext)); + YYLEX(TOKEN_IDENTIFIER); + } +[ \t\r\n] { + BEGIN(INITIAL); + unput(yytext[yyleng - 1]); + yyreducepos(1); + } +. { + BEGIN(INITIAL); + unput(yytext[yyleng - 1]); + yyreducepos(1); + } - +\"{string}\"{nonexpr} { + BEGIN(IDENTIFIER); + yymore(); + } -\"{string}\"{nonexpr} { - BEGIN(IDENTIFIER); - yymore(); - } +\"{string}\" { TextEscapeValue(yytext + 1, yyleng - 2); YYLEX(TOKEN_STRING); } -\"{string}\" { TextEscapeValue( yytext + 1, yyleng - 2 ); YYLEX( TOKEN_STRING ); } +"?" { YYLEX(TOKEN_TERNARY); } +"if" { YYLEX(TOKEN_IF); } +"else" { YYLEX(TOKEN_ELSE); } +"while" { YYLEX(TOKEN_WHILE); } +"for" { YYLEX(TOKEN_FOR); } +"do" { YYLEX(TOKEN_DO); } -"?" { YYLEX( TOKEN_TERNARY ); } -"if" { YYLEX( TOKEN_IF ); } -"else" { YYLEX( TOKEN_ELSE ); } -"while" { YYLEX( TOKEN_WHILE ); } -"for" { YYLEX( TOKEN_FOR ); } -"do" { YYLEX( TOKEN_DO ); } +"game" { BEGIN(VARIABLES); yylval.s.val = node1_(method_game); YYLEX(TOKEN_LISTENER); } +"group" { BEGIN(VARIABLES); yylval.s.val = node1_(method_group); YYLEX(TOKEN_LISTENER); } +"level" { BEGIN(VARIABLES); yylval.s.val = node1_(method_level); YYLEX(TOKEN_LISTENER); } +"local" { BEGIN(VARIABLES); yylval.s.val = node1_(method_local); YYLEX(TOKEN_LISTENER); } +"parm" { BEGIN(VARIABLES); yylval.s.val = node1_(method_parm); YYLEX(TOKEN_LISTENER); } +"owner" { BEGIN(VARIABLES); yylval.s.val = node1_(method_owner); YYLEX(TOKEN_LISTENER); } +"self" { BEGIN(VARIABLES); yylval.s.val = node1_(method_self); YYLEX(TOKEN_LISTENER); } -"game" { BEGIN( VARIABLES ); yylval.s.val = node1_( method_game ); YYLEX( TOKEN_LISTENER ); } -"group" { BEGIN( VARIABLES ); yylval.s.val = node1_( method_group ); YYLEX( TOKEN_LISTENER ); } -"level" { BEGIN( VARIABLES ); yylval.s.val = node1_( method_level ); YYLEX( TOKEN_LISTENER ); } -"local" { BEGIN( VARIABLES ); yylval.s.val = node1_( method_local ); YYLEX( TOKEN_LISTENER ); } -"parm" { BEGIN( VARIABLES ); yylval.s.val = node1_( method_parm ); YYLEX( TOKEN_LISTENER ); } -"owner" { BEGIN( VARIABLES ); yylval.s.val = node1_( method_owner ); YYLEX( TOKEN_LISTENER ); } -"self" { BEGIN( VARIABLES ); yylval.s.val = node1_( method_self ); YYLEX( TOKEN_LISTENER ); } +"{" { parsedata.braces_count++; YYLEX(TOKEN_LEFT_BRACES); } +"}" { parsedata.braces_count--; YYLEX(TOKEN_RIGHT_BRACES); } +"(" { YYLEX(TOKEN_LEFT_BRACKET); } +")" { BEGIN(VARIABLES); YYLEX(TOKEN_RIGHT_BRACKET); } +"[" { YYLEX(TOKEN_LEFT_SQUARE_BRACKET); } +"]" { BEGIN(VARIABLES); YYLEX(TOKEN_RIGHT_SQUARE_BRACKET); } -"{" { parsedata.braces_count++; YYLEX( TOKEN_LEFT_BRACES ); } -"}" { parsedata.braces_count--; YYLEX( TOKEN_RIGHT_BRACES ); } -"(" { YYLEX(TOKEN_LEFT_BRACKET); } -")" { BEGIN(VARIABLES); YYLEX(TOKEN_RIGHT_BRACKET); } -"[" { YYLEX(TOKEN_LEFT_SQUARE_BRACKET); } -"]" { BEGIN(VARIABLES); YYLEX(TOKEN_RIGHT_SQUARE_BRACKET); } +"=" { YYLEX(TOKEN_ASSIGNMENT); } +":" { YYLEX(TOKEN_COLON); } +"::" { YYLEX(TOKEN_DOUBLE_COLON); } +";" { YYLEX(TOKEN_SEMICOLON); } -"=" { YYLEX( TOKEN_ASSIGNMENT ); } -":" { YYLEX( TOKEN_COLON ); } -"::" { YYLEX( TOKEN_DOUBLE_COLON ); } -";" { YYLEX( TOKEN_SEMICOLON ); } +"==" { YYLEX(TOKEN_EQUALITY); } +"ifequal" { YYLEX(TOKEN_EQUALITY); } +"ifstrequal" { YYLEX(TOKEN_EQUALITY); } +"||" { YYLEX(TOKEN_LOGICAL_OR); } +"&&" { YYLEX(TOKEN_LOGICAL_AND); } -"==" { YYLEX( TOKEN_EQUALITY ); } -"ifequal" { YYLEX( TOKEN_EQUALITY ); } -"ifstrequal" { YYLEX( TOKEN_EQUALITY ); } -"||" { YYLEX( TOKEN_LOGICAL_OR ); } -"&&" { YYLEX( TOKEN_LOGICAL_AND ); } +"|" { YYLEX(TOKEN_BITWISE_OR); } +"^" { YYLEX(TOKEN_BITWISE_EXCL_OR); } +"&" { YYLEX(TOKEN_BITWISE_AND); } +"!=" { YYLEX(TOKEN_INEQUALITY); } +"ifnotequal" { YYLEX(TOKEN_INEQUALITY); } +"ifstrnotequal" { YYLEX(TOKEN_INEQUALITY); } +"<" { YYLEX(TOKEN_LESS_THAN); } +"ifless" { YYLEX(TOKEN_LESS_THAN); } +">" { YYLEX(TOKEN_GREATER_THAN); } +"ifgreater" { YYLEX(TOKEN_GREATER_THAN); } +"<=" { YYLEX(TOKEN_LESS_THAN_OR_EQUAL); } +"iflessequal" { YYLEX(TOKEN_LESS_THAN_OR_EQUAL); } +">=" { YYLEX(TOKEN_GREATER_THAN_OR_EQUAL); } +"ifgreaterequal" { YYLEX(TOKEN_GREATER_THAN_OR_EQUAL); } +[ \t]"-" { YYLEX(TOKEN_NEG); } -"|" { YYLEX( TOKEN_BITWISE_OR ); } -"^" { YYLEX( TOKEN_BITWISE_EXCL_OR ); } -"&" { YYLEX( TOKEN_BITWISE_AND ); } -"!=" { YYLEX( TOKEN_INEQUALITY ); } -"ifnotequal" { YYLEX( TOKEN_INEQUALITY ); } -"ifstrnotequal" { YYLEX( TOKEN_INEQUALITY ); } -"<" { YYLEX( TOKEN_LESS_THAN ); } -"ifless" { YYLEX( TOKEN_LESS_THAN ); } -">" { YYLEX( TOKEN_GREATER_THAN ); } -"ifgreater" { YYLEX( TOKEN_GREATER_THAN ); } -"<=" { YYLEX( TOKEN_LESS_THAN_OR_EQUAL ); } -"iflessequal" { YYLEX( TOKEN_LESS_THAN_OR_EQUAL ); } -">=" { YYLEX( TOKEN_GREATER_THAN_OR_EQUAL ); } -"ifgreaterequal" { YYLEX( TOKEN_GREATER_THAN_OR_EQUAL ); } -[ \t]"-" { YYLEX( TOKEN_NEG ); } +"+" { YYLEX(TOKEN_PLUS); } +"+=" { YYLEX(TOKEN_PLUS_EQUALS); } +"++"|[ \t]"++" { YYLEX(TOKEN_INCREMENT); } +"-"|"-"[ \t]|[ \t]"-"[ \t] { YYLEX(TOKEN_MINUS); } +"-=" { YYLEX(TOKEN_MINUS_EQUALS); } +[ \t]"-=" { YYLEX(TOKEN_MINUS_EQUALS); } +"--"|[ \t]"--" { YYLEX(TOKEN_DECREMENT); } +"*" { YYLEX(TOKEN_MULTIPLY); } +"*=" { YYLEX(TOKEN_MULTIPLY_EQUALS); } +"/" { YYLEX(TOKEN_DIVIDE); } +"/=" { YYLEX(TOKEN_DIVIDE_EQUALS); } +"%" { YYLEX(TOKEN_MODULUS); } +"%=" { YYLEX(TOKEN_MODULUS_EQUALS); } +"<<" { YYLEX(TOKEN_SHIFT_LEFT); } +"<<=" { YYLEX(TOKEN_SHIFT_LEFT_EQUALS); } +">>" { YYLEX(TOKEN_SHIFT_RIGHT); } +">>=" { YYLEX(TOKEN_SHIFT_RIGHT_EQUALS); } +"&=" { YYLEX(TOKEN_AND_EQUALS); } +"^=" { YYLEX(TOKEN_EXCL_OR_EQUALS); } +"|=" { YYLEX(TOKEN_OR_EQUALS); } +[$]+ { BEGIN( VARIABLES ); YYLEX(TOKEN_DOLLAR); } +"!" { YYLEX(TOKEN_NOT); } +"~" { YYLEX(TOKEN_COMPLEMENT); } -"+" { YYLEX( TOKEN_PLUS ); } -"+=" { YYLEX( TOKEN_PLUS_EQUALS ); } -"++"|[ \t]"++" { YYLEX( TOKEN_INCREMENT ); } -"-"|"-"[ \t]|[ \t]"-"[ \t] { YYLEX( TOKEN_MINUS ); } -"-=" { YYLEX( TOKEN_MINUS_EQUALS ); } -[ \t]"-=" { YYLEX( TOKEN_MINUS_EQUALS ); } -"--"|[ \t]"--" { YYLEX( TOKEN_DECREMENT ); } -"*" { YYLEX( TOKEN_MULTIPLY ); } -"*=" { YYLEX( TOKEN_MULTIPLY_EQUALS ); } -"/" { YYLEX( TOKEN_DIVIDE ); } -"/=" { YYLEX( TOKEN_DIVIDE_EQUALS ); } -"%" { YYLEX( TOKEN_MODULUS ); } -"%=" { YYLEX( TOKEN_MODULUS_EQUALS ); } -"<<" { YYLEX( TOKEN_SHIFT_LEFT ); } -"<<=" { YYLEX( TOKEN_SHIFT_LEFT_EQUALS ); } -">>" { YYLEX( TOKEN_SHIFT_RIGHT ); } -">>=" { YYLEX( TOKEN_SHIFT_RIGHT_EQUALS ); } -"&=" { YYLEX( TOKEN_AND_EQUALS ); } -"^=" { YYLEX( TOKEN_EXCL_OR_EQUALS ); } -"|=" { YYLEX( TOKEN_OR_EQUALS ); } -[$]+ { BEGIN( VARIABLES ); YYLEX( TOKEN_DOLLAR ); } -"!" { YYLEX( TOKEN_NOT ); } -"~" { YYLEX( TOKEN_COMPLEMENT ); } +"." { YYLEX(TOKEN_PERIOD); } -"." { YYLEX( TOKEN_PERIOD ); } +"," { YYLEX(TOKEN_COMMA); } -"," { YYLEX( TOKEN_COMMA ); } +"NULL" { YYLEX(TOKEN_NULL); } +"NIL" { YYLEX(TOKEN_NIL); } -"NULL" { YYLEX( TOKEN_NULL ); } -"NIL" { YYLEX( TOKEN_NIL ); } +"try" { YYLEX(TOKEN_TRY); } +"catch" { YYLEX(TOKEN_CATCH); } +"switch" { YYLEX(TOKEN_SWITCH); } -"try" { YYLEX( TOKEN_TRY ); } -"catch" { YYLEX( TOKEN_CATCH ); } -"switch" { YYLEX( TOKEN_SWITCH ); } +"case" { YYLEX(TOKEN_CASE); } +"break" { YYLEX(TOKEN_BREAK); } +"continue" { YYLEX(TOKEN_CONTINUE); } -"case" { YYLEX( TOKEN_CASE ); } -"break" { YYLEX( TOKEN_BREAK ); } -"continue" { YYLEX( TOKEN_CONTINUE ); } +"makearray"|"makeArray" { YYLEX(TOKEN_MAKEARRAY); } +"endarray"|"endArray" { YYLEX(TOKEN_ENDARRAY); } -"makearray"|"makeArray" { YYLEX( TOKEN_MAKEARRAY ); } -"endarray"|"endArray" { YYLEX( TOKEN_ENDARRAY ); } +[\r\n]+ { if (prev_yylex != TOKEN_EOL) YYLEX(TOKEN_EOL); } +[ \t] { ; } -[\r\n]+ { if (prev_yylex != TOKEN_EOL) YYLEX(TOKEN_EOL); } -[ \t] { ; } +[0-9]+ { + char* p = nullptr; + yylval.s.val.intValue = std::strtol(yytext, &p, 10); + YYLEX(TOKEN_INTEGER); + } -[0-9]+ { - char* p = nullptr; - yylval.s.val.intValue = std::strtol(yytext, &p, 10); - YYLEX(TOKEN_INTEGER); - } +[0-9\.]+{nonnumeric} { + BEGIN(IDENTIFIER); + yymore(); + } -[0-9\.]+{nonnumeric} { - BEGIN(IDENTIFIER); - yymore(); - } +[0-9\.]+|[0-9\.]+("e+"|"e-")+[0-9\.] { + char* p = nullptr; + yylval.s.val.floatValue = std::strtof(yytext, &p); + YYLEX(TOKEN_FLOAT); + } -[0-9\.]+|[0-9\.]+("e+"|"e-")+[0-9\.] { - char* p = nullptr; - yylval.s.val.floatValue = std::strtof(yytext, &p); - YYLEX(TOKEN_FLOAT); - } +{identifier}* { + BEGIN(INITIAL); + TextEscapeValue(yytext, yyleng); + YYLEX(TOKEN_IDENTIFIER); + } +[ \t\r\n] { + BEGIN(INITIAL); + unput(yytext[yyleng - 1]); + yyreducepos(1); + TextEscapeValue(yytext, yyleng - 1); + YYLEXOFF(TOKEN_IDENTIFIER, 1); + } +. { + BEGIN(INITIAL); + unput(yytext[yyleng - 1]); + yyreducepos(1); + TextEscapeValue(yytext, yyleng - 1); + YYLEXOFF(TOKEN_IDENTIFIER, 1); + } -{identifier}* { - BEGIN(INITIAL); - TextEscapeValue(yytext, yyleng); - YYLEX(TOKEN_IDENTIFIER); - } -[ \t\r\n] { - BEGIN(INITIAL); - unput(yytext[yyleng - 1]); - yyreducepos(1); - TextEscapeValue(yytext, yyleng - 1); - YYLEXOFF(TOKEN_IDENTIFIER, 1); - } -. { - BEGIN(INITIAL); - unput(yytext[yyleng - 1]); - yyreducepos(1); - TextEscapeValue(yytext, yyleng - 1); - YYLEXOFF(TOKEN_IDENTIFIER, 1); - } +{identifier} { + BEGIN(IDENTIFIER); + yymore(); + } -{identifier} { - BEGIN(IDENTIFIER); - yymore(); - } +[a-zA-Z0-9_]+ { + BEGIN(IDENTIFIER); + yymore(); + } -[a-zA-Z0-9_]+ { - BEGIN(IDENTIFIER); - yymore(); - } +