cc4.om (14749B)
1 enum { 2 LEFT_BRACE, 3 RIGHT_BRACE, 4 LEFT_SQUARE, 5 RIGHT_SQUARE, 6 LEFT_PAREN, 7 RIGHT_PAREN, 8 DOT, 9 ASSIGN, 10 SEMI, 11 COLON, 12 QMARK, 13 STAR, 14 AMP, 15 COMMA, 16 BANG, 17 PLUS, 18 MINUS, 19 NOT, 20 SLASH, 21 MOD, 22 PIPE, 23 XOR, 24 AND_THEN, 25 OR_ELSE, 26 LE, 27 GE, 28 LT, 29 GT, 30 EQ, 31 NE, 32 LEFT_SHIFT, 33 RIGHT_SHIFT, 34 RETURN, 35 BREAK, 36 SIZEOF, 37 IF, 38 ELSE, 39 LOOP, 40 CONTINUE, 41 GOTO, 42 VAR, 43 ENUM, 44 STRUCT, 45 UNION, 46 BYTE, 47 INT, 48 VOID, 49 FUNC, 50 AS, 51 NIL, 52 LEX, 53 LALR, 54 IDENT, 55 NUMBER, 56 STRING, 57 CHARSET, 58 } 59 60 lexer { 61 "{" { return LEFT_BRACE; } 62 "}" { return RIGHT_BRACE; } 63 64 "[" { return LEFT_SQUARE; } 65 "]" { return RIGHT_SQUARE; } 66 67 "(" { return LEFT_PAREN; } 68 ")" { return RIGHT_PAREN; } 69 70 "." { return DOT; } 71 "=" { return ASSIGN; } 72 ";" { return SEMI; } 73 ":" { return COLON; } 74 "?" { return QMARK; } 75 "*" { return STAR; } 76 "&" { return AMP; } 77 "," { return COMMA; } 78 "!" { return BANG; } 79 "+" { return PLUS; } 80 "-" { return MINUS; } 81 "~" { return NOT; } 82 "/" { return SLASH; } 83 "%" { return MOD; } 84 "|" { return PIPE; } 85 "^" { return XOR; } 86 87 "&&" { return AND_THEN; } 88 "||" { return OR_ELSE; } 89 90 "<=" { return LE; } 91 ">=" { return GE; } 92 "<" { return LT; } 93 ">" { return GT; } 94 "==" { return EQ; } 95 "!=" { return NE; } 96 97 "<<" { return LEFT_SHIFT; } 98 ">>" { return RIGHT_SHIFT; } 99 100 "return" { return RETURN; } 101 "break" { return BREAK; } 102 "sizeof" { return SIZEOF; } 103 "if" { return IF; } 104 "else" { return ELSE; } 105 "loop" { return LOOP; } 106 "continue" { return CONTINUE; } 107 "goto" { return GOTO; } 108 "var" { return VAR; } 109 "enum" { return ENUM; } 110 "struct" { return STRUCT; } 111 "union" { return UNION; } 112 "byte" { return BYTE; } 113 "int" { return INT; } 114 "void" { return VOID; } 115 "func" { return FUNC; } 116 "as" { return AS; } 117 "nil" { return NIL; } 118 "lexer" { return LEX; } 119 "lalr" { return LALR; } 120 121 ["a-zA-Z_"]["a-zA-Z0-9_"]* { 122 var n: *node; 123 n = mknode(ctx.c.p, N_IDENT, nil, nil); 124 n.s = mkstr(ctx.a, &ctx.buf[ctx.start], ctx.end - ctx.start); 125 ctx.val.n = n; 126 return IDENT; 127 } 128 129 "0b" ["01"] (["01_"]* ["01"])? { 130 var n: *node; 131 var ok: int; 132 n = mknode(ctx.c.p, N_NUM, nil, nil); 133 n.n = bin2int(&ctx.buf[ctx.start + 2], ctx.end - ctx.start - 2, &ok); 134 if !ok { 135 die("invalid bin"); 136 } 137 ctx.val.n = n; 138 return NUMBER; 139 } 140 141 "0x" ["0-9a-fA-F"] (["0-9a-fA-F_"]* ["0-9a-fA-F"])? { 142 var n: *node; 143 var ok: int; 144 n = mknode(ctx.c.p, N_NUM, nil, nil); 145 n.n = hex2int(&ctx.buf[ctx.start + 2], ctx.end - ctx.start - 2, &ok); 146 if !ok { 147 die("invalid hex"); 148 } 149 ctx.val.n = n; 150 return NUMBER; 151 } 152 153 ["0-9"] (["0-9_"]* ["0-9"])? { 154 var n: *node; 155 var x: int; 156 var ok: int; 157 n = mknode(ctx.c.p, N_NUM, nil, nil); 158 n.n = dec2int(&ctx.buf[ctx.start], ctx.end - ctx.start, &ok); 159 if !ok { 160 die("invalid dec"); 161 } 162 ctx.val.n = n; 163 return NUMBER; 164 } 165 166 "'" ("\\" . | ["^\\\x27"])* "'" { 167 var n: *node; 168 var i: int; 169 var x: int; 170 var ok: int; 171 n = mknode(ctx.c.p, N_NUM, nil, nil); 172 i = ctx.start + 1; 173 n.n = unescape(ctx.buf, &i, ctx.end - 1, &ok); 174 if !ok || i != ctx.end - 1 { 175 die("invalid char"); 176 } 177 ctx.val.n = n; 178 return NUMBER; 179 } 180 181 "\"" ("\\" . | ["^\\\x22"])* "\"" { 182 var n: *node; 183 var i: int; 184 var j: int; 185 var ok: int; 186 n = mknode(ctx.c.p, N_STR, nil, nil); 187 n.s = alloc(ctx.a, ctx.end - ctx.start); 188 i = ctx.start + 1; 189 j = 0; 190 loop { 191 if i == ctx.end - 1 { 192 break; 193 } 194 n.s[j] = unescape(ctx.buf, &i, ctx.end - 1, &ok) as byte; 195 if !ok { 196 die("invalid string"); 197 } 198 j = j + 1; 199 } 200 n.s[j] = 0 as byte; 201 ctx.val.n = n; 202 return STRING; 203 } 204 205 "[\"" (["^\"\\"] | "\\".)* "\"]" { 206 var n: *node; 207 n = mknode(ctx.c.p, N_CHARSET, nil, nil); 208 n.s = parse_charset(ctx.a, &ctx.buf[ctx.start + 2], ctx.end - ctx.start - 4); 209 ctx.val.n = n; 210 return CHARSET; 211 } 212 213 [" \r\n\t"] { } 214 "//" ["^\n"]* "\n" { } 215 } 216 217 lalr { 218 grammar 219 = decl_list { ctx.val.n = ctx.sem[0].n; } 220 ; 221 222 decl_list 223 = decl_list decl { ctx.val.n = mknode(ctx.c.p, N_PROGRAM, ctx.sem[1].n, ctx.sem[0].n); } 224 | { ctx.val.n = nil; } 225 ; 226 227 decl 228 = enum_decl { ctx.val.n = ctx.sem[0].n; } 229 | struct_decl { ctx.val.n = ctx.sem[0].n; } 230 | union_decl { ctx.val.n = ctx.sem[0].n; } 231 | func_def { ctx.val.n = ctx.sem[0].n; } 232 | lexer_grammar { ctx.val.n = ctx.sem[0].n; } 233 | lalr_grammar { ctx.val.n = ctx.sem[0].n; } 234 ; 235 236 enum_item 237 = IDENT { ctx.val.n = mknode(ctx.c.p, N_ENUMITEM, ctx.sem[0].n, nil); } 238 | IDENT ASSIGN expr { ctx.val.n = mknode(ctx.c.p, N_ENUMITEM, ctx.sem[0].n, ctx.sem[2].n); } 239 ; 240 241 enum_item_list 242 = enum_item COMMA enum_item_list { ctx.val.n = mknode(ctx.c.p, N_ENUMLIST, ctx.sem[0].n, ctx.sem[2].n); } 243 | enum_item COMMA { ctx.val.n = mknode(ctx.c.p, N_ENUMLIST, ctx.sem[0].n, nil); } 244 | enum_item { ctx.val.n = mknode(ctx.c.p, N_ENUMLIST, ctx.sem[0].n, nil); }; 245 246 enum_decl 247 = ENUM LEFT_BRACE enum_item_list RIGHT_BRACE { ctx.val.n = mknode(ctx.c.p, N_ENUM, ctx.sem[2].n, nil); } 248 ; 249 250 member_decl 251 = IDENT COLON type_decl SEMI { ctx.val.n = mknode(ctx.c.p, N_MEMBERDECL, ctx.sem[0].n, ctx.sem[2].n); } 252 ; 253 254 member_decl_list 255 = member_decl member_decl_list { ctx.val.n = mknode(ctx.c.p, N_MEMBERLIST, ctx.sem[0].n, ctx.sem[1].n); } 256 | { ctx.val.n = nil; } 257 ; 258 259 struct_decl 260 = STRUCT IDENT LEFT_BRACE member_decl_list RIGHT_BRACE { ctx.val.n = mknode(ctx.c.p, N_STRUCT, ctx.sem[1].n, ctx.sem[3].n); } 261 ; 262 263 union_decl 264 = UNION IDENT LEFT_BRACE member_decl_list RIGHT_BRACE { ctx.val.n = mknode(ctx.c.p, N_UNION, ctx.sem[1].n, ctx.sem[3].n); } 265 ; 266 267 type_decl 268 = IDENT { ctx.val.n = ctx.sem[0].n; } 269 | BYTE { ctx.val.n = mkident(ctx.c.p, "byte"); } 270 | INT { ctx.val.n = mkident(ctx.c.p, "int"); } 271 | VOID { ctx.val.n = mkident(ctx.c.p, "void"); } 272 | FUNC func_type { ctx.val.n = ctx.sem[1].n; } 273 | STAR type_decl { ctx.val.n = mknode(ctx.c.p, N_PTRTYPE, ctx.sem[1].n, nil); } 274 | LEFT_PAREN type_decl RIGHT_PAREN { ctx.val.n = ctx.sem[1].n; } 275 ; 276 277 arg_decl 278 = IDENT COLON type_decl { ctx.val.n = mknode(ctx.c.p, N_ARGDECL, ctx.sem[0].n, ctx.sem[2].n); } 279 ; 280 281 arg_decl_list 282 = arg_decl COMMA arg_decl_list { ctx.val.n = mknode(ctx.c.p, N_ARGLIST, ctx.sem[0].n, ctx.sem[2].n); } 283 | arg_decl { ctx.val.n = mknode(ctx.c.p, N_ARGLIST, ctx.sem[0].n, nil); } 284 | { ctx.val.n = nil; } 285 ; 286 287 func_return_type 288 = COLON type_decl { ctx.val.n = ctx.sem[1].n; } 289 | { ctx.val.n = nil; } 290 ; 291 292 func_type 293 = LEFT_PAREN arg_decl_list RIGHT_PAREN func_return_type { ctx.val.n = mknode(ctx.c.p, N_FUNCTYPE, ctx.sem[1].n, ctx.sem[3].n); } 294 ; 295 296 func_decl 297 = FUNC IDENT func_type { ctx.val.n = mknode(ctx.c.p, N_FUNCDECL, ctx.sem[1].n, ctx.sem[2].n); } 298 ; 299 300 func_def 301 = func_decl SEMI { ctx.val.n = ctx.sem[0].n; } 302 | func_decl compound_stmt { ctx.val.n = mknode(ctx.c.p, N_FUNC, ctx.sem[0].n, ctx.sem[1].n); } 303 ; 304 305 stmt 306 = if_stmt { ctx.val.n = ctx.sem[0].n; } 307 | loop_stmt { ctx.val.n = ctx.sem[0].n; } 308 | break_stmt { ctx.val.n = ctx.sem[0].n; } 309 | continue_stmt { ctx.val.n = ctx.sem[0].n; } 310 | return_stmt { ctx.val.n = ctx.sem[0].n; } 311 | var_stmt { ctx.val.n = ctx.sem[0].n; } 312 | label_stmt { ctx.val.n = ctx.sem[0].n; } 313 | goto_stmt { ctx.val.n = ctx.sem[0].n; } 314 | assign_stmt { ctx.val.n = ctx.sem[0].n; } 315 | expr_stmt { ctx.val.n = ctx.sem[0].n; } 316 | empty_stmt { ctx.val.n = ctx.sem[0].n; } 317 | compound_stmt { ctx.val.n = ctx.sem[0].n; } 318 ; 319 320 if_stmt 321 = IF expr compound_stmt { ctx.val.n = mknode(ctx.c.p, N_CONDLIST, mknode(ctx.c.p, N_COND, ctx.sem[1].n, ctx.sem[2].n), nil); } 322 | IF expr compound_stmt ELSE if_stmt { ctx.val.n = mknode(ctx.c.p, N_CONDLIST, mknode(ctx.c.p, N_COND, ctx.sem[1].n, ctx.sem[2].n), ctx.sem[4].n); } 323 | IF expr compound_stmt ELSE compound_stmt { 324 var n: *node; 325 n = mknode(ctx.c.p, N_CONDLIST, mknode(ctx.c.p, N_COND, nil, ctx.sem[4].n), n); 326 n = mknode(ctx.c.p, N_CONDLIST, mknode(ctx.c.p, N_COND, ctx.sem[1].n, ctx.sem[2].n), n); 327 ctx.val.n = n; 328 } 329 ; 330 331 loop_stmt 332 = LOOP compound_stmt { ctx.val.n = mknode(ctx.c.p, N_LOOP, ctx.sem[1].n, nil); } 333 ; 334 335 break_stmt 336 = BREAK SEMI { ctx.val.n = mknode(ctx.c.p, N_BREAK, nil, nil); } 337 ; 338 339 continue_stmt 340 = CONTINUE SEMI { ctx.val.n = mknode(ctx.c.p, N_CONTINUE, nil, nil); } 341 ; 342 343 return_stmt 344 = RETURN expr SEMI { ctx.val.n = mknode(ctx.c.p, N_RETURN, ctx.sem[1].n, nil); } 345 | RETURN SEMI { ctx.val.n = mknode(ctx.c.p, N_RETURN, nil, nil); } 346 ; 347 348 var_stmt 349 = VAR IDENT COLON type_decl SEMI { ctx.val.n = mknode(ctx.c.p, N_VARDECL, ctx.sem[1].n, ctx.sem[3].n); } 350 ; 351 352 label_stmt 353 = IDENT COLON { ctx.val.n = mknode(ctx.c.p, N_LABEL, ctx.sem[0].n, nil); } 354 ; 355 356 goto_stmt 357 = GOTO IDENT SEMI { ctx.val.n = mknode(ctx.c.p, N_GOTO, ctx.sem[1].n, nil); } 358 ; 359 360 assign_stmt 361 = unary_expr ASSIGN expr SEMI { ctx.val.n = mknode(ctx.c.p, N_ASSIGN, ctx.sem[0].n, ctx.sem[2].n); } 362 ; 363 364 expr_stmt 365 = expr SEMI { ctx.val.n = ctx.sem[0].n; } 366 ; 367 368 empty_stmt 369 = SEMI { ctx.val.n = nil; } 370 ; 371 372 stmt_list 373 = stmt stmt_list { ctx.val.n = mknode(ctx.c.p, N_STMTLIST, ctx.sem[0].n, ctx.sem[1].n); } 374 | { ctx.val.n = nil; } 375 ; 376 377 compound_stmt 378 = LEFT_BRACE stmt_list RIGHT_BRACE { ctx.val.n = ctx.sem[1].n; } 379 ; 380 381 expr 382 = expr AND_THEN comp_expr { ctx.val.n = mknode(ctx.c.p, N_BAND, ctx.sem[0].n, ctx.sem[2].n); } 383 | expr OR_ELSE comp_expr { ctx.val.n = mknode(ctx.c.p, N_BOR, ctx.sem[0].n, ctx.sem[2].n); } 384 | comp_expr { ctx.val.n = ctx.sem[0].n; } 385 ; 386 387 comp_expr 388 = add_expr LE add_expr { ctx.val.n = mknode(ctx.c.p, N_LE, ctx.sem[0].n, ctx.sem[2].n); } 389 | add_expr GE add_expr { ctx.val.n = mknode(ctx.c.p, N_GE, ctx.sem[0].n, ctx.sem[2].n); } 390 | add_expr LT add_expr { ctx.val.n = mknode(ctx.c.p, N_LT, ctx.sem[0].n, ctx.sem[2].n); } 391 | add_expr GT add_expr { ctx.val.n = mknode(ctx.c.p, N_GT, ctx.sem[0].n, ctx.sem[2].n); } 392 | add_expr EQ add_expr { ctx.val.n = mknode(ctx.c.p, N_EQ, ctx.sem[0].n, ctx.sem[2].n); } 393 | add_expr NE add_expr { ctx.val.n = mknode(ctx.c.p, N_NE, ctx.sem[0].n, ctx.sem[2].n); } 394 | add_expr { ctx.val.n = ctx.sem[0].n; } 395 ; 396 397 add_expr 398 = add_expr PLUS mul_expr { ctx.val.n = mknode(ctx.c.p, N_ADD, ctx.sem[0].n, ctx.sem[2].n); } 399 | add_expr MINUS mul_expr { ctx.val.n = mknode(ctx.c.p, N_SUB, ctx.sem[0].n, ctx.sem[2].n); } 400 | add_expr PIPE mul_expr { ctx.val.n = mknode(ctx.c.p, N_OR, ctx.sem[0].n, ctx.sem[2].n); } 401 | add_expr XOR mul_expr { ctx.val.n = mknode(ctx.c.p, N_XOR, ctx.sem[0].n, ctx.sem[2].n); } 402 | mul_expr { ctx.val.n = ctx.sem[0].n; } 403 ; 404 405 mul_expr 406 = mul_expr STAR shift_expr { ctx.val.n = mknode(ctx.c.p, N_MUL, ctx.sem[0].n, ctx.sem[2].n); } 407 | mul_expr SLASH shift_expr { ctx.val.n = mknode(ctx.c.p, N_DIV, ctx.sem[0].n, ctx.sem[2].n); } 408 | mul_expr MOD shift_expr { ctx.val.n = mknode(ctx.c.p, N_MOD, ctx.sem[0].n, ctx.sem[2].n); } 409 | mul_expr AMP shift_expr { ctx.val.n = mknode(ctx.c.p, N_AND, ctx.sem[0].n, ctx.sem[2].n); } 410 | shift_expr { ctx.val.n = ctx.sem[0].n; } 411 ; 412 413 shift_expr 414 = shift_expr LEFT_SHIFT unary_expr { ctx.val.n = mknode(ctx.c.p, N_LSH, ctx.sem[0].n, ctx.sem[2].n); } 415 | shift_expr RIGHT_SHIFT unary_expr { ctx.val.n = mknode(ctx.c.p, N_RSH, ctx.sem[0].n, ctx.sem[2].n); } 416 | unary_expr { ctx.val.n = ctx.sem[0].n; } 417 ; 418 419 unary_expr 420 = AMP unary_expr { ctx.val.n = mknode(ctx.c.p, N_REF, ctx.sem[1].n, nil); } 421 | STAR unary_expr { ctx.val.n = mknode(ctx.c.p, N_DEREF, ctx.sem[1].n, nil); } 422 | PLUS unary_expr { ctx.val.n = mknode(ctx.c.p, N_POS, ctx.sem[1].n, nil); } 423 | MINUS unary_expr { ctx.val.n = mknode(ctx.c.p, N_NEG, ctx.sem[1].n, nil); } 424 | NOT unary_expr { ctx.val.n = mknode(ctx.c.p, N_NOT, ctx.sem[1].n, nil); } 425 | BANG unary_expr { ctx.val.n = mknode(ctx.c.p, N_BNOT, ctx.sem[1].n, nil); } 426 | post_expr { ctx.val.n = ctx.sem[0].n; } 427 ; 428 429 expr_list 430 = expr COMMA expr_list { ctx.val.n = mknode(ctx.c.p, N_EXPRLIST, ctx.sem[0].n, ctx.sem[2].n); } 431 | expr { ctx.val.n = mknode(ctx.c.p, N_EXPRLIST, ctx.sem[0].n, nil); } 432 | { ctx.val.n = nil; } 433 ; 434 435 post_expr 436 = post_expr LEFT_SQUARE expr RIGHT_SQUARE { ctx.val.n = mknode(ctx.c.p, N_INDEX, ctx.sem[0].n, ctx.sem[2].n); } 437 | post_expr LEFT_PAREN expr_list RIGHT_PAREN { ctx.val.n = mknode(ctx.c.p, N_CALL, ctx.sem[0].n, ctx.sem[2].n); } 438 | post_expr DOT IDENT { ctx.val.n = mknode(ctx.c.p, N_DOT, ctx.sem[0].n, ctx.sem[2].n); } 439 | post_expr AS type_decl { ctx.val.n = mknode(ctx.c.p, N_CAST, ctx.sem[0].n, ctx.sem[2].n);} 440 | primary { ctx.val.n = ctx.sem[0].n; } 441 ; 442 443 primary 444 = IDENT { ctx.val.n = ctx.sem[0].n; } 445 | NUMBER { ctx.val.n = ctx.sem[0].n; } 446 | STRING { ctx.val.n = ctx.sem[0].n; } 447 | SIZEOF LEFT_PAREN expr RIGHT_PAREN { ctx.val.n = mknode(ctx.c.p, N_SIZEOF, ctx.sem[2].n, nil); } 448 | NIL { ctx.val.n = mknode(ctx.c.p, N_NIL, nil, nil); } 449 | LEFT_PAREN expr RIGHT_PAREN { ctx.val.n = ctx.sem[1].n; } 450 ; 451 452 lexer_primary 453 = LEFT_PAREN lexer_pattern RIGHT_PAREN { ctx.val.n = ctx.sem[1].n; } 454 | DOT { ctx.val.n = mknode(ctx.c.p, N_LEXDOT, nil, nil); } 455 | STRING { ctx.val.n = ctx.sem[0].n; } 456 | CHARSET { ctx.val.n = ctx.sem[0].n; } 457 ; 458 459 lexer_suffix 460 = lexer_suffix STAR { ctx.val.n = mknode(ctx.c.p, N_LEXSTAR, ctx.sem[0].n, nil); } 461 | lexer_suffix PLUS { ctx.val.n = mknode(ctx.c.p, N_LEXPLUS, ctx.sem[0].n, nil); } 462 | lexer_suffix QMARK { ctx.val.n = mknode(ctx.c.p, N_LEXQMARK, ctx.sem[0].n, nil); } 463 | lexer_primary { ctx.val.n = ctx.sem[0].n; } 464 ; 465 466 lexer_alternative 467 = lexer_suffix lexer_alternative { ctx.val.n = mknode(ctx.c.p, N_LEXCONCAT, ctx.sem[0].n, ctx.sem[1].n); } 468 | lexer_suffix { ctx.val.n = ctx.sem[0].n; } 469 ; 470 471 lexer_pattern 472 = lexer_alternative PIPE lexer_pattern { ctx.val.n = mknode(ctx.c.p, N_LEXALT, ctx.sem[0].n, ctx.sem[2].n); } 473 | lexer_alternative { ctx.val.n = ctx.sem[0].n; } 474 ; 475 476 lexer_rule 477 = lexer_pattern compound_stmt { ctx.val.n = mknode(ctx.c.p, N_LEXRULE, ctx.sem[0].n, ctx.sem[1].n); } 478 ; 479 480 lexer_rule_list 481 = lexer_rule lexer_rule_list { ctx.val.n = mknode(ctx.c.p, N_LEXLIST, ctx.sem[0].n, ctx.sem[1].n); } 482 | { ctx.val.n = nil; } 483 ; 484 485 lexer_grammar 486 = LEX LEFT_BRACE lexer_rule_list RIGHT_BRACE { ctx.val.n = mknode(ctx.c.p, N_LEXER, ctx.sem[2].n, nil); } 487 ; 488 489 lalr_primary 490 = IDENT { ctx.val.n = ctx.sem[0].n; } 491 | compound_stmt { ctx.val.n = ctx.sem[0].n; } 492 ; 493 494 lalr_alternative 495 = lalr_primary lalr_alternative { ctx.val.n = mknode(ctx.c.p, N_PRODITEM, ctx.sem[0].n, ctx.sem[1].n); } 496 | { ctx.val.n = nil; } 497 ; 498 499 lalr_pattern 500 = lalr_alternative PIPE lalr_pattern { ctx.val.n = mknode(ctx.c.p, N_PRODALT, ctx.sem[0].n, ctx.sem[2].n); } 501 | lalr_alternative { ctx.val.n = mknode(ctx.c.p, N_PRODALT, ctx.sem[0].n, nil); } 502 ; 503 504 lalr_rule 505 = IDENT ASSIGN lalr_pattern { ctx.val.n = mknode(ctx.c.p, N_PROD, ctx.sem[0].n, ctx.sem[2].n); } 506 ; 507 508 lalr_rule_list 509 = lalr_rule SEMI lalr_rule_list { ctx.val.n = mknode(ctx.c.p, N_PRODLIST, ctx.sem[0].n, ctx.sem[2].n); } 510 | lalr_rule SEMI { ctx.val.n = mknode(ctx.c.p, N_PRODLIST, ctx.sem[0].n, nil); } 511 ; 512 513 lalr_grammar 514 = LALR LEFT_BRACE lalr_rule_list RIGHT_BRACE { ctx.val.n = mknode(ctx.c.p, N_GRAMMAR, ctx.sem[2].n, nil); } 515 ; 516 }