File: bison_source.txt

package info (click to toggle)
openmohaa 0.82.1%2Bdfsg-1
  • links: PTS, VCS
  • area: contrib
  • in suites: forky, sid
  • size: 34,192 kB
  • sloc: cpp: 315,720; ansic: 275,789; sh: 312; xml: 246; asm: 141; makefile: 7
file content (341 lines) | stat: -rw-r--r-- 16,418 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
%{
/*
* ===========================================================================
* 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
* ===========================================================================
*
*
* yyParser.*: BISON Parser for MoHScript.
*/

#include "scriptcompiler.h"
#include "./yyParser.hpp"
#include "./yyLexer.h"

// the value was increased because some scripts have a lot of if/else statements
// which ends up with an high depth
#define YYINITDEPTH 500

int yyerror( const char *msg );

extern int prev_yylex;

extern yyparsedata parsedata;

int prev_yylex;
int out_pos;
int success_pos;

#define YYLLOC node_pos(success_pos - yyleng)
#define TOKPOS(pos) node_pos(pos.sourcePos)

%}

%define parse.error verbose
%locations
%define api.location.type { parse_pos_t }

%expect 123

%precedence TOKEN_EOF 0 "end of file"
%precedence TOKEN_EOL

%union {
    stype_t s;
}

%left TOKEN_COMMA

%precedence TOKEN_IF
%right THEN TOKEN_ELSE
%precedence TOKEN_WHILE TOKEN_FOR TOKEN_DO
%precedence <s.val> TOKEN_IDENTIFIER

%precedence TOKEN_LEFT_BRACES TOKEN_RIGHT_BRACES
%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

%left TOKEN_LOGICAL_OR
%left TOKEN_LOGICAL_AND

%left TOKEN_BITWISE_OR
%left TOKEN_BITWISE_EXCL_OR
%left TOKEN_BITWISE_AND

%left TOKEN_EQUALITY TOKEN_INEQUALITY
%left TOKEN_LESS_THAN TOKEN_LESS_THAN_OR_EQUAL TOKEN_GREATER_THAN TOKEN_GREATER_THAN_OR_EQUAL

%left TOKEN_SHIFT_LEFT TOKEN_SHIFT_RIGHT
%left TOKEN_PLUS TOKEN_MINUS
%left TOKEN_MULTIPLY TOKEN_DIVIDE TOKEN_MODULUS

%token TOKEN_NEG TOKEN_NOT TOKEN_COMPLEMENT

%precedence <s.val> TOKEN_STRING
%precedence <s.val> TOKEN_INTEGER
%precedence <s.val> TOKEN_FLOAT

%precedence <s.val> TOKEN_LISTENER
%precedence TOKEN_NIL TOKEN_NULL

%left TOKEN_DOUBLE_COLON
%left TOKEN_SEMICOLON
%right TOKEN_DOLLAR

%token TOKEN_INCREMENT TOKEN_DECREMENT TOKEN_PERIOD

%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

%type <s.val> event_parameter_list event_parameter_list_need event_parameter
%type <s.val> statement_list statement statement_declaration makearray_statement_list makearray_statement statement_for_condition
%type <s.val> compound_statement selection_statement iteration_statement
%type <s.val> expr
%type <s.val> func_prim_expr
%type <s.val> prim_expr
%type <s.val> listener_identifier
%type <s.val> nonident_prim_expr
%type <s.val> nonident_prim_expr_base
%type <s.val> const_array_list
%type <s.val> const_array
%type <s.val> identifier_prim
%type <s.val> identifier

%start program
 
%%

program
    : 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
    : 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) ); }
    ;
    
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; }
    ;

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; }
    ;

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)); }
    ;

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)); }
    ;

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)); }
    ;

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));
        }
    ;

event_parameter_list
    : { $$ = sval_u{}; $$.node = NULL; }
    | event_parameter { $$ = $1; }
    ;

event_parameter_list_need
    : event_parameter { $$ = $1; }
    ;

event_parameter
    : 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
    : 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)); }
    ;

identifier_prim:
    TOKEN_IDENTIFIER { $$ = $1; @$ = @1; }
    ;

identifier
    : TOKEN_IDENTIFIER { $$ = $1; @$ = @1; }
    | TOKEN_STRING { $$ = $1; @$ = @1; }
    ;

listener_identifier
    : 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_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; }
    ;

makearray_statement:
    prim_expr { $$ = linked_list_end( $1 ); }
    | makearray_statement prim_expr { $$ = append_node( $1, $2 ); }
    ;

line_opt
    : {}
    | TOKEN_EOL
    ;
 
%%