diff options
author | Emanuele Torre <torreemanuele6@gmail.com> | 2023-07-25 20:50:45 +0200 |
---|---|---|
committer | Nico Williams <nico@cryptonector.com> | 2023-07-25 14:51:58 -0500 |
commit | ae95864b6b338f04ab25e389824a632087f1bd60 (patch) | |
tree | 162fb004d54cc896f80a6cc331faa166f64c28f9 /src | |
parent | a949745059ee61366a5d880c3b18d5d4db6524eb (diff) |
Make sure to free default `@text` format on error
It seems that bison doesn't call destructors for mid-rule action
components on error, since it does not know their type.
A mid-rule action was used to allocate the "text" string used as format
by string literals without a format, which would leak on error.
This patch replaces it with a new NoFormat component of type <literal>.
Now bison will call jv_free() on that string after a syntax error.
Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=60836
$ ./jq '"'
jq: error: syntax error, unexpected end of file, expecting QQSTRING_TEXT or QQSTRING_INTERP_START or QQSTRING_END (Unix shell quoting issues?) at <top-level>, line 1:
"
jq: 1 compile error
=================================================================
==1495450==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 21 byte(s) in 1 object(s) allocated from:
#0 0x7fc21aee1359 in __interceptor_malloc /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_malloc_linux.cpp:69
#1 0x557ccb6ff608 in jv_mem_alloc src/jv_alloc.c:141
SUMMARY: AddressSanitizer: 21 byte(s) leaked in 1 allocation(s).
Diffstat (limited to 'src')
-rw-r--r-- | src/parser.c | 802 | ||||
-rw-r--r-- | src/parser.y | 10 |
2 files changed, 413 insertions, 399 deletions
diff --git a/src/parser.c b/src/parser.c index e7c6a4ea..6f859666 100644 --- a/src/parser.c +++ b/src/parser.c @@ -366,9 +366,9 @@ enum yysymbol_kind_t YYSYMBOL_FuncDef = 79, /* FuncDef */ YYSYMBOL_Params = 80, /* Params */ YYSYMBOL_Param = 81, /* Param */ - YYSYMBOL_String = 82, /* String */ - YYSYMBOL_83_1 = 83, /* @1 */ - YYSYMBOL_84_2 = 84, /* @2 */ + YYSYMBOL_NoFormat = 82, /* NoFormat */ + YYSYMBOL_String = 83, /* String */ + YYSYMBOL_84_1 = 84, /* @1 */ YYSYMBOL_QQString = 85, /* QQString */ YYSYMBOL_ElseBody = 86, /* ElseBody */ YYSYMBOL_ExpD = 87, /* ExpD */ @@ -389,7 +389,7 @@ typedef enum yysymbol_kind_t yysymbol_kind_t; /* Second part of user prologue. */ -#line 125 "src/parser.y" +#line 126 "src/parser.y" #include "lexer.h" struct lexer_param { @@ -964,24 +964,24 @@ static const yytype_int8 yytranslate[] = /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_int16 yyrline[] = { - 0, 312, 312, 315, 320, 323, 338, 341, 346, 349, - 354, 358, 361, 365, 369, 373, 376, 381, 384, 387, - 392, 399, 403, 407, 411, 415, 419, 423, 427, 431, - 435, 439, 443, 447, 451, 455, 459, 463, 469, 475, - 479, 483, 487, 491, 495, 499, 503, 507, 512, 515, - 532, 541, 548, 556, 567, 572, 578, 581, 586, 590, - 597, 597, 601, 601, 608, 611, 614, 620, 623, 626, - 631, 634, 637, 643, 646, 649, 657, 661, 664, 667, - 670, 673, 676, 679, 682, 685, 689, 695, 698, 701, - 704, 707, 710, 713, 716, 719, 722, 725, 728, 731, - 734, 737, 740, 743, 746, 749, 752, 755, 777, 781, - 785, 788, 800, 805, 806, 807, 808, 811, 814, 819, - 824, 827, 832, 835, 840, 844, 847, 852, 855, 860, - 863, 868, 871, 874, 877, 880, 883, 891, 897, 900, - 903, 906, 909, 912, 915, 918, 921, 924, 927, 930, - 933, 936, 939, 942, 945, 948, 953, 956, 957, 958, - 961, 964, 967, 970, 974, 978, 982, 986, 990, 994, - 1002 + 0, 313, 313, 316, 321, 324, 339, 342, 347, 350, + 355, 359, 362, 366, 370, 374, 377, 382, 385, 388, + 393, 400, 404, 408, 412, 416, 420, 424, 428, 432, + 436, 440, 444, 448, 452, 456, 460, 464, 470, 476, + 480, 484, 488, 492, 496, 500, 504, 508, 513, 516, + 533, 542, 549, 557, 568, 573, 579, 582, 587, 591, + 598, 603, 607, 607, 614, 617, 620, 626, 629, 632, + 637, 640, 643, 649, 652, 655, 663, 667, 670, 673, + 676, 679, 682, 685, 688, 691, 695, 701, 704, 707, + 710, 713, 716, 719, 722, 725, 728, 731, 734, 737, + 740, 743, 746, 749, 752, 755, 758, 761, 783, 787, + 791, 794, 806, 811, 812, 813, 814, 817, 820, 825, + 830, 833, 838, 841, 846, 850, 853, 858, 861, 866, + 869, 874, 877, 880, 883, 886, 889, 897, 903, 906, + 909, 912, 915, 918, 921, 924, 927, 930, 933, 936, + 939, 942, 945, 948, 951, 954, 959, 962, 963, 964, + 967, 970, 973, 976, 980, 984, 988, 992, 996, 1000, + 1008 }; #endif @@ -1010,9 +1010,9 @@ static const char *const yytname[] = "'%'", "NONOPT", "'?'", "';'", "'('", "')'", "':'", "'.'", "'['", "']'", "'{'", "'}'", "'$'", "$accept", "TopLevel", "Module", "Imports", "FuncDefs", "Exp", "Import", "ImportWhat", "ImportFrom", "FuncDef", - "Params", "Param", "String", "@1", "@2", "QQString", "ElseBody", "ExpD", - "Term", "Args", "Arg", "RepPatterns", "Patterns", "Pattern", "ArrayPats", - "ObjPats", "ObjPat", "Keyword", "MkDict", "MkDictPair", YY_NULLPTR + "Params", "Param", "NoFormat", "String", "@1", "QQString", "ElseBody", + "ExpD", "Term", "Args", "Arg", "RepPatterns", "Patterns", "Pattern", + "ArrayPats", "ObjPats", "ObjPat", "Keyword", "MkDict", "MkDictPair", YY_NULLPTR }; static const char * @@ -1113,7 +1113,7 @@ static const yytype_uint8 yydefact[] = static const yytype_int16 yypgoto[] = { -159, -159, -159, 145, 74, -1, -159, -159, 172, -12, - -159, -43, 5, -159, -159, 78, -104, -138, -7, -159, + -159, -43, -159, 5, -159, 78, -104, -138, -7, -159, 16, -159, -69, -114, -159, -159, -51, -158, -111, -159 }; @@ -1121,7 +1121,7 @@ static const yytype_int16 yypgoto[] = static const yytype_uint8 yydefgoto[] = { 0, 2, 3, 32, 119, 111, 33, 34, 116, 26, - 199, 200, 27, 46, 128, 136, 254, 215, 28, 126, + 199, 200, 46, 27, 128, 136, 254, 215, 28, 126, 127, 182, 183, 184, 225, 231, 232, 81, 82, 83 }; @@ -1550,28 +1550,28 @@ static const yytype_int8 yystos[] = { 0, 16, 71, 72, 4, 5, 6, 7, 8, 9, 15, 19, 23, 24, 28, 30, 31, 32, 42, 54, - 61, 64, 65, 67, 69, 75, 79, 82, 88, 0, + 61, 64, 65, 67, 69, 75, 79, 83, 88, 0, 17, 18, 73, 76, 77, 61, 59, 42, 4, 75, - 88, 88, 75, 6, 1, 6, 83, 75, 1, 75, - 1, 4, 8, 82, 1, 66, 75, 1, 4, 6, + 88, 88, 75, 6, 1, 6, 82, 75, 1, 75, + 1, 4, 8, 83, 1, 66, 75, 1, 4, 6, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 61, - 82, 97, 98, 99, 69, 10, 11, 12, 13, 26, + 83, 97, 98, 99, 69, 10, 11, 12, 13, 26, 27, 33, 34, 35, 36, 37, 38, 39, 40, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 59, - 60, 75, 5, 14, 64, 65, 78, 82, 78, 74, + 60, 75, 5, 14, 64, 65, 78, 83, 78, 74, 75, 79, 73, 60, 75, 75, 89, 90, 84, 61, 63, 20, 14, 14, 29, 48, 85, 62, 62, 1, 59, 66, 66, 49, 63, 68, 63, 63, 75, 63, 63, 68, 49, 69, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 59, 6, - 65, 67, 91, 92, 93, 65, 82, 1, 63, 66, + 65, 67, 91, 92, 93, 65, 83, 1, 63, 66, 75, 14, 74, 60, 60, 62, 85, 4, 6, 80, 81, 75, 1, 75, 92, 92, 1, 75, 75, 43, 44, 46, 1, 98, 54, 87, 88, 87, 87, 62, 87, 87, 98, 6, 93, 94, 1, 4, 6, 61, - 82, 95, 96, 97, 41, 48, 66, 75, 59, 66, + 83, 95, 96, 97, 41, 48, 66, 75, 59, 66, 75, 59, 63, 66, 4, 6, 90, 46, 60, 62, 60, 21, 22, 25, 86, 61, 61, 75, 87, 48, 63, 49, 66, 63, 63, 63, 75, 63, 49, 68, @@ -1591,7 +1591,7 @@ static const yytype_int8 yyr1[] = 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 76, 76, 77, 77, 77, 78, 79, 79, 80, 80, 81, 81, - 83, 82, 84, 82, 85, 85, 85, 86, 86, 86, + 82, 83, 84, 83, 85, 85, 85, 86, 86, 86, 87, 87, 87, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, @@ -2288,100 +2288,106 @@ yydestruct (const char *yymsg, #line 2289 "src/parser.c" break; + case YYSYMBOL_NoFormat: /* NoFormat */ +#line 36 "src/parser.y" + { jv_free(((*yyvaluep).literal)); } +#line 2295 "src/parser.c" + break; + case YYSYMBOL_String: /* String */ #line 37 "src/parser.y" { block_free(((*yyvaluep).blk)); } -#line 2295 "src/parser.c" +#line 2301 "src/parser.c" break; case YYSYMBOL_QQString: /* QQString */ #line 37 "src/parser.y" { block_free(((*yyvaluep).blk)); } -#line 2301 "src/parser.c" +#line 2307 "src/parser.c" break; case YYSYMBOL_ElseBody: /* ElseBody */ #line 37 "src/parser.y" { block_free(((*yyvaluep).blk)); } -#line 2307 "src/parser.c" +#line 2313 "src/parser.c" break; case YYSYMBOL_ExpD: /* ExpD */ #line 37 "src/parser.y" { block_free(((*yyvaluep).blk)); } -#line 2313 "src/parser.c" +#line 2319 "src/parser.c" break; case YYSYMBOL_Term: /* Term */ #line 37 "src/parser.y" { block_free(((*yyvaluep).blk)); } -#line 2319 "src/parser.c" +#line 2325 "src/parser.c" break; case YYSYMBOL_Args: /* Args */ #line 37 "src/parser.y" { block_free(((*yyvaluep).blk)); } -#line 2325 "src/parser.c" +#line 2331 "src/parser.c" break; case YYSYMBOL_Arg: /* Arg */ #line 37 "src/parser.y" { block_free(((*yyvaluep).blk)); } -#line 2331 "src/parser.c" +#line 2337 "src/parser.c" break; case YYSYMBOL_RepPatterns: /* RepPatterns */ #line 37 "src/parser.y" { block_free(((*yyvaluep).blk)); } -#line 2337 "src/parser.c" +#line 2343 "src/parser.c" break; case YYSYMBOL_Patterns: /* Patterns */ #line 37 "src/parser.y" { block_free(((*yyvaluep).blk)); } -#line 2343 "src/parser.c" +#line 2349 "src/parser.c" break; case YYSYMBOL_Pattern: /* Pattern */ #line 37 "src/parser.y" { block_free(((*yyvaluep).blk)); } -#line 2349 "src/parser.c" +#line 2355 "src/parser.c" break; case YYSYMBOL_ArrayPats: /* ArrayPats */ #line 37 "src/parser.y" { block_free(((*yyvaluep).blk)); } -#line 2355 "src/parser.c" +#line 2361 "src/parser.c" break; case YYSYMBOL_ObjPats: /* ObjPats */ #line 37 "src/parser.y" { block_free(((*yyvaluep).blk)); } -#line 2361 "src/parser.c" +#line 2367 "src/parser.c" break; case YYSYMBOL_ObjPat: /* ObjPat */ #line 37 "src/parser.y" { block_free(((*yyvaluep).blk)); } -#line 2367 "src/parser.c" +#line 2373 "src/parser.c" break; case YYSYMBOL_Keyword: /* Keyword */ #line 36 "src/parser.y" { jv_free(((*yyvaluep).literal)); } -#line 2373 "src/parser.c" +#line 2379 "src/parser.c" break; case YYSYMBOL_MkDict: /* MkDict */ #line 37 "src/parser.y" { block_free(((*yyvaluep).blk)); } -#line 2379 "src/parser.c" +#line 2385 "src/parser.c" break; case YYSYMBOL_MkDictPair: /* MkDictPair */ #line 37 "src/parser.y" { block_free(((*yyvaluep).blk)); } -#line 2385 "src/parser.c" +#line 2391 "src/parser.c" break; default: @@ -2685,31 +2691,31 @@ yyreduce: switch (yyn) { case 2: /* TopLevel: Module Imports Exp */ -#line 312 "src/parser.y" +#line 313 "src/parser.y" { *answer = BLOCK((yyvsp[-2].blk), (yyvsp[-1].blk), gen_op_simple(TOP), (yyvsp[0].blk)); } -#line 2693 "src/parser.c" +#line 2699 "src/parser.c" break; case 3: /* TopLevel: Module Imports FuncDefs */ -#line 315 "src/parser.y" +#line 316 "src/parser.y" { *answer = BLOCK((yyvsp[-2].blk), (yyvsp[-1].blk), (yyvsp[0].blk)); } -#line 2701 "src/parser.c" +#line 2707 "src/parser.c" break; case 4: /* Module: %empty */ -#line 320 "src/parser.y" +#line 321 "src/parser.y" { (yyval.blk) = gen_noop(); } -#line 2709 "src/parser.c" +#line 2715 "src/parser.c" break; case 5: /* Module: "module" Exp ';' */ -#line 323 "src/parser.y" +#line 324 "src/parser.y" { if (!block_is_const((yyvsp[-1].blk))) { FAIL((yyloc), "Module metadata must be constant"); @@ -2723,364 +2729,364 @@ yyreduce: (yyval.blk) = gen_module((yyvsp[-1].blk)); } } -#line 2727 "src/parser.c" +#line 2733 "src/parser.c" break; case 6: /* Imports: %empty */ -#line 338 "src/parser.y" +#line 339 "src/parser.y" { (yyval.blk) = gen_noop(); } -#line 2735 "src/parser.c" +#line 2741 "src/parser.c" break; case 7: /* Imports: Import Imports */ -#line 341 "src/parser.y" +#line 342 "src/parser.y" { (yyval.blk) = BLOCK((yyvsp[-1].blk), (yyvsp[0].blk)); } -#line 2743 "src/parser.c" +#line 2749 "src/parser.c" break; case 8: /* FuncDefs: %empty */ -#line 346 "src/parser.y" +#line 347 "src/parser.y" { (yyval.blk) = gen_noop(); } -#line 2751 "src/parser.c" +#line 2757 "src/parser.c" break; case 9: /* FuncDefs: FuncDef FuncDefs */ -#line 349 "src/parser.y" +#line 350 "src/parser.y" { (yyval.blk) = block_join((yyvsp[-1].blk), (yyvsp[0].blk)); } -#line 2759 "src/parser.c" +#line 2765 "src/parser.c" break; case 10: /* Exp: FuncDef Exp */ -#line 354 "src/parser.y" +#line 355 "src/parser.y" { (yyval.blk) = block_bind_referenced((yyvsp[-1].blk), (yyvsp[0].blk), OP_IS_CALL_PSEUDO); } -#line 2767 "src/parser.c" +#line 2773 "src/parser.c" break; case 11: /* Exp: Term "as" Patterns '|' Exp */ -#line 358 "src/parser.y" +#line 359 "src/parser.y" { (yyval.blk) = gen_destructure((yyvsp[-4].blk), (yyvsp[-2].blk), (yyvsp[0].blk)); } -#line 2775 "src/parser.c" +#line 2781 "src/parser.c" break; case 12: /* Exp: "reduce" Term "as" Patterns '(' Exp ';' Exp ')' */ -#line 361 "src/parser.y" +#line 362 "src/parser.y" { (yyval.blk) = gen_reduce((yyvsp[-7].blk), (yyvsp[-5].blk), (yyvsp[-3].blk), (yyvsp[-1].blk)); } -#line 2783 "src/parser.c" +#line 2789 "src/parser.c" break; case 13: /* Exp: "foreach" Term "as" Patterns '(' Exp ';' Exp ';' Exp ')' */ -#line 365 "src/parser.y" +#line 366 "src/parser.y" { (yyval.blk) = gen_foreach((yyvsp[-9].blk), (yyvsp[-7].blk), (yyvsp[-5].blk), (yyvsp[-3].blk), (yyvsp[-1].blk)); } -#line 2791 "src/parser.c" +#line 2797 "src/parser.c" break; case 14: /* Exp: "foreach" Term "as" Patterns '(' Exp ';' Exp ')' */ -#line 369 "src/parser.y" +#line 370 "src/parser.y" { (yyval.blk) = gen_foreach((yyvsp[-7].blk), (yyvsp[-5].blk), (yyvsp[-3].blk), (yyvsp[-1].blk), gen_noop()); } -#line 2799 "src/parser.c" +#line 2805 "src/parser.c" break; case 15: /* Exp: "if" Exp "then" Exp ElseBody */ -#line 373 "src/parser.y" +#line 374 "src/parser.y" { (yyval.blk) = gen_cond((yyvsp[-3].blk), (yyvsp[-1].blk), (yyvsp[0].blk)); } -#line 2807 "src/parser.c" +#line 2813 "src/parser.c" break; case 16: /* Exp: "if" Exp "then" error */ -#line 376 "src/parser.y" +#line 377 "src/parser.y" { FAIL((yyloc), "Possibly unterminated 'if' statement"); (yyval.blk) = (yyvsp[-2].blk); } -#line 2816 "src/parser.c" +#line 2822 "src/parser.c" break; case 17: /* Exp: "try" Exp "catch" Exp */ -#line 381 "src/parser.y" +#line 382 "src/parser.y" { (yyval.blk) = gen_try((yyvsp[-2].blk), (yyvsp[0].blk)); } -#line 2824 "src/parser.c" +#line 2830 "src/parser.c" break; case 18: /* Exp: "try" Exp */ -#line 384 "src/parser.y" +#line 385 "src/parser.y" { (yyval.blk) = gen_try((yyvsp[0].blk), gen_op_simple(BACKTRACK)); } -#line 2832 "src/parser.c" +#line 2838 "src/parser.c" break; case 19: /* Exp: "try" Exp "catch" error */ -#line 387 "src/parser.y" +#line 388 "src/parser.y" { FAIL((yyloc), "Possibly unterminated 'try' statement"); (yyval.blk) = (yyvsp[-2].blk); } -#line 2841 "src/parser.c" +#line 2847 "src/parser.c" break; case 20: /* Exp: "label" BINDING '|' Exp */ -#line 392 "src/parser.y" +#line 393 "src/parser.y" { jv v = jv_string_fmt("*label-%s", jv_string_value((yyvsp[-2].literal))); (yyval.blk) = gen_location((yyloc), locations, gen_label(jv_string_value(v), (yyvsp[0].blk))); jv_free((yyvsp[-2].literal)); jv_free(v); } -#line 2852 "src/parser.c" +#line 2858 "src/parser.c" break; case 21: /* Exp: Exp '?' */ -#line 399 "src/parser.y" +#line 400 "src/parser.y" { (yyval.blk) = gen_try((yyvsp[-1].blk), gen_op_simple(BACKTRACK)); } -#line 2860 "src/parser.c" +#line 2866 "src/parser.c" break; case 22: /* Exp: Exp '=' Exp */ -#line 403 "src/parser.y" +#line 404 "src/parser.y" { (yyval.blk) = gen_call("_assign", BLOCK(gen_lambda((yyvsp[-2].blk)), gen_lambda((yyvsp[0].blk)))); } -#line 2868 "src/parser.c" +#line 2874 "src/parser.c" break; case 23: /* Exp: Exp "or" Exp */ -#line 407 "src/parser.y" +#line 408 "src/parser.y" { (yyval.blk) = gen_or((yyvsp[-2].blk), (yyvsp[0].blk)); } -#line 2876 "src/parser.c" +#line 2882 "src/parser.c" break; case 24: /* Exp: Exp "and" Exp */ -#line 411 "src/parser.y" +#line 412 "src/parser.y" { (yyval.blk) = gen_and((yyvsp[-2].blk), (yyvsp[0].blk)); } -#line 2884 "src/parser.c" +#line 2890 "src/parser.c" break; case 25: /* Exp: Exp "//" Exp */ -#line 415 "src/parser.y" +#line 416 "src/parser.y" { (yyval.blk) = gen_definedor((yyvsp[-2].blk), (yyvsp[0].blk)); } -#line 2892 "src/parser.c" +#line 2898 "src/parser.c" break; case 26: /* Exp: Exp "//=" Exp */ -#line 419 "src/parser.y" +#line 420 "src/parser.y" { (yyval.blk) = gen_definedor_assign((yyvsp[-2].blk), (yyvsp[0].blk)); } -#line 2900 "src/parser.c" +#line 2906 "src/parser.c" break; case 27: /* Exp: Exp "|=" Exp */ -#line 423 "src/parser.y" +#line 424 "src/parser.y" { (yyval.blk) = gen_call("_modify", BLOCK(gen_lambda((yyvsp[-2].blk)), gen_lambda((yyvsp[0].blk)))); } -#line 2908 "src/parser.c" +#line 2914 "src/parser.c" break; case 28: /* Exp: Exp '|' Exp */ -#line 427 "src/parser.y" +#line 428 "src/parser.y" { (yyval.blk) = block_join((yyvsp[-2].blk), (yyvsp[0].blk)); } -#line 2916 "src/parser.c" +#line 2922 "src/parser.c" break; case 29: /* Exp: Exp ',' Exp */ -#line 431 "src/parser.y" +#line 432 "src/parser.y" { (yyval.blk) = gen_both((yyvsp[-2].blk), (yyvsp[0].blk)); } -#line 2924 "src/parser.c" +#line 2930 "src/parser.c" break; case 30: /* Exp: Exp '+' Exp */ -#line 435 "src/parser.y" +#line 436 "src/parser.y" { (yyval.blk) = gen_binop((yyvsp[-2].blk), (yyvsp[0].blk), '+'); } -#line 2932 "src/parser.c" +#line 2938 "src/parser.c" break; case 31: /* Exp: Exp "+=" Exp */ -#line 439 "src/parser.y" +#line 440 "src/parser.y" { (yyval.blk) = gen_update((yyvsp[-2].blk), (yyvsp[0].blk), '+'); } -#line 2940 "src/parser.c" +#line 2946 "src/parser.c" break; case 32: /* Exp: '-' Exp */ -#line 443 "src/parser.y" +#line 444 "src/parser.y" { (yyval.blk) = BLOCK((yyvsp[0].blk), gen_call("_negate", gen_noop())); } -#line 2948 "src/parser.c" +#line 2954 "src/parser.c" break; case 33: /* Exp: Exp '-' Exp */ -#line 447 "src/parser.y" +#line 448 "src/parser.y" { (yyval.blk) = gen_binop((yyvsp[-2].blk), (yyvsp[0].blk), '-'); } -#line 2956 "src/parser.c" +#line 2962 "src/parser.c" break; case 34: /* Exp: Exp "-=" Exp */ -#line 451 "src/parser.y" +#line 452 "src/parser.y" { (yyval.blk) = gen_update((yyvsp[-2].blk), (yyvsp[0].blk), '-'); } -#line 2964 "src/parser.c" +#line 2970 "src/parser.c" break; case 35: /* Exp: Exp '*' Exp */ -#line 455 "src/parser.y" +#line 456 "src/parser.y" { (yyval.blk) = gen_binop((yyvsp[-2].blk), (yyvsp[0].blk), '*'); } -#line 2972 "src/parser.c" +#line 2978 "src/parser.c" break; case 36: /* Exp: Exp "*=" Exp */ -#line 459 "src/parser.y" +#line 460 "src/parser.y" { (yyval.blk) = gen_update((yyvsp[-2].blk), (yyvsp[0].blk), '*'); } -#line 2980 "src/parser.c" +#line 2986 "src/parser.c" break; case 37: /* Exp: Exp '/' Exp */ -#line 463 "src/parser.y" +#line 464 "src/parser.y" { (yyval.blk) = gen_binop((yyvsp[-2].blk), (yyvsp[0].blk), '/'); if (block_is_const_inf((yyval.blk))) FAIL((yyloc), "Division by zero?"); } -#line 2990 "src/parser.c" +#line 2996 "src/parser.c" break; case 38: /* Exp: Exp '%' Exp */ -#line 469 "src/parser.y" +#line 470 "src/parser.y" { (yyval.blk) = gen_binop((yyvsp[-2].blk), (yyvsp[0].blk), '%'); if (block_is_const_inf((yyval.blk))) FAIL((yyloc), "Remainder by zero?"); } -#line 3000 "src/parser.c" +#line 3006 "src/parser.c" break; case 39: /* Exp: Exp "/=" Exp */ -#line 475 "src/parser.y" +#line 476 "src/parser.y" { (yyval.blk) = gen_update((yyvsp[-2].blk), (yyvsp[0].blk), '/'); } -#line 3008 "src/parser.c" +#line 3014 "src/parser.c" break; case 40: /* Exp: Exp "%=" Exp */ -#line 479 "src/parser.y" +#line 480 "src/parser.y" { (yyval.blk) = gen_update((yyvsp[-2].blk), (yyvsp[0].blk), '%'); } -#line 3016 "src/parser.c" +#line 3022 "src/parser.c" break; case 41: /* Exp: Exp "==" Exp */ -#line 483 "src/parser.y" +#line 484 "src/parser.y" { (yyval.blk) = gen_binop((yyvsp[-2].blk), (yyvsp[0].blk), EQ); } -#line 3024 "src/parser.c" +#line 3030 "src/parser.c" break; case 42: /* Exp: Exp "!=" Exp */ -#line 487 "src/parser.y" +#line 488 "src/parser.y" { (yyval.blk) = gen_binop((yyvsp[-2].blk), (yyvsp[0].blk), NEQ); } -#line 3032 "src/parser.c" +#line 3038 "src/parser.c" break; case 43: /* Exp: Exp '<' Exp */ -#line 491 "src/parser.y" +#line 492 "src/parser.y" { (yyval.blk) = gen_binop((yyvsp[-2].blk), (yyvsp[0].blk), '<'); } -#line 3040 "src/parser.c" +#line 3046 "src/parser.c" break; case 44: /* Exp: Exp '>' Exp */ -#line 495 "src/parser.y" +#line 496 "src/parser.y" { (yyval.blk) = gen_binop((yyvsp[-2].blk), (yyvsp[0].blk), '>'); } -#line 3048 "src/parser.c" +#line 3054 "src/parser.c" break; case 45: /* Exp: Exp "<=" Exp */ -#line 499 "src/parser.y" +#line 500 "src/parser.y" { (yyval.blk) = gen_binop((yyvsp[-2].blk), (yyvsp[0].blk), LESSEQ); } -#line 3056 "src/parser.c" +#line 3062 "src/parser.c" break; case 46: /* Exp: Exp ">=" Exp */ -#line 503 "src/parser.y" +#line 504 "src/parser.y" { (yyval.blk) = gen_binop((yyvsp[-2].blk), (yyvsp[0].blk), GREATEREQ); } -#line 3064 "src/parser.c" +#line 3070 "src/parser.c" break; case 47: /* Exp: Term */ -#line 507 "src/parser.y" +#line 508 "src/parser.y" { (yyval.blk) = (yyvsp[0].blk); } -#line 3072 "src/parser.c" +#line 3078 "src/parser.c" break; case 48: /* Import: ImportWhat ';' */ -#line 512 "src/parser.y" +#line 513 "src/parser.y" { (yyval.blk) = (yyvsp[-1].blk); } -#line 3080 "src/parser.c" +#line 3086 "src/parser.c" break; case 49: /* Import: ImportWhat Exp ';' */ -#line 515 "src/parser.y" +#line 516 "src/parser.y" { if (!block_is_const((yyvsp[-1].blk))) { FAIL((yyloc), "Module metadata must be constant"); @@ -3096,11 +3102,11 @@ yyreduce: (yyval.blk) = gen_import_meta((yyvsp[-2].blk), (yyvsp[-1].blk)); } } -#line 3100 "src/parser.c" +#line 3106 "src/parser.c" break; case 50: /* ImportWhat: "import" ImportFrom "as" BINDING */ -#line 532 "src/parser.y" +#line 533 "src/parser.y" { jv v = block_const((yyvsp[-2].blk)); // XXX Make gen_import take only blocks and the int is_data so we @@ -3110,11 +3116,11 @@ yyreduce: jv_free((yyvsp[0].literal)); jv_free(v); } -#line 3114 "src/parser.c" +#line 3120 "src/parser.c" break; case 51: /* ImportWhat: "import" ImportFrom "as" IDENT */ -#line 541 "src/parser.y" +#line 542 "src/parser.y" { jv v = block_const((yyvsp[-2].blk)); (yyval.blk) = gen_import(jv_string_value(v), jv_string_value((yyvsp[0].literal)), 0); @@ -3122,22 +3128,22 @@ yyreduce: jv_free((yyvsp[0].literal)); jv_free(v); } -#line 3126 "src/parser.c" +#line 3132 "src/parser.c" break; case 52: /* ImportWhat: "include" ImportFrom */ -#line 548 "src/parser.y" +#line 549 "src/parser.y" { jv v = block_const((yyvsp[0].blk)); (yyval.blk) = gen_import(jv_string_value(v), NULL, 0); block_free((yyvsp[0].blk)); jv_free(v); } -#line 3137 "src/parser.c" +#line 3143 "src/parser.c" break; case 53: /* ImportFrom: String */ -#line 556 "src/parser.y" +#line 557 "src/parser.y" { if (!block_is_const((yyvsp[0].blk))) { FAIL((yyloc), "Import path must be constant"); @@ -3147,181 +3153,183 @@ yyreduce: (yyval.blk) = (yyvsp[0].blk); } } -#line 3151 "src/parser.c" +#line 3157 "src/parser.c" break; case 54: /* FuncDef: "def" IDENT ':' Exp ';' */ -#line 567 "src/parser.y" +#line 568 "src/parser.y" { (yyval.blk) = gen_function(jv_string_value((yyvsp[-3].literal)), gen_noop(), (yyvsp[-1].blk)); jv_free((yyvsp[-3].literal)); } -#line 3160 "src/parser.c" +#line 3166 "src/parser.c" break; case 55: /* FuncDef: "def" IDENT '(' Params ')' ':' Exp ';' */ -#line 572 "src/parser.y" +#line 573 "src/parser.y" { (yyval.blk) = gen_function(jv_string_value((yyvsp[-6].literal)), (yyvsp[-4].blk), (yyvsp[-1].blk)); jv_free((yyvsp[-6].literal)); } -#line 3169 "src/parser.c" +#line 3175 "src/parser.c" break; case 56: /* Params: Param */ -#line 578 "src/parser.y" +#line 579 "src/parser.y" { (yyval.blk) = (yyvsp[0].blk); } -#line 3177 "src/parser.c" +#line 3183 "src/parser.c" break; case 57: /* Params: Params ';' Param */ -#line 581 "src/parser.y" +#line 582 "src/parser.y" { (yyval.blk) = BLOCK((yyvsp[-2].blk), (yyvsp[0].blk)); } -#line 3185 "src/parser.c" +#line 3191 "src/parser.c" break; case 58: /* Param: BINDING */ -#line 586 "src/parser.y" +#line 587 "src/parser.y" { (yyval.blk) = gen_param_regular(jv_string_value((yyvsp[0].literal))); jv_free((yyvsp[0].literal)); } -#line 3194 "src/parser.c" +#line 3200 "src/parser.c" break; case 59: /* Param: IDENT */ -#line 590 "src/parser.y" +#line 591 "src/parser.y" { (yyval.blk) = gen_param(jv_string_value((yyvsp[0].literal))); jv_free((yyvsp[0].literal)); } -#line 3203 "src/parser.c" +#line 3209 "src/parser.c" break; - case 60: /* @1: %empty */ -#line 597 "src/parser.y" - { (yyval.literal) = jv_string("text"); } -#line 3209 "src/parser.c" + case 60: /* NoFormat: %empty */ +#line 598 "src/parser.y" + { + (yyval.literal) = jv_string("text"); +} +#line 3217 "src/parser.c" break; - case 61: /* String: QQSTRING_START @1 QQString QQSTRING_END */ -#line 597 "src/parser.y" - { + case 61: /* String: QQSTRING_START NoFormat QQString QQSTRING_END */ +#line 603 "src/parser.y" + { (yyval.blk) = (yyvsp[-1].blk); jv_free((yyvsp[-2].literal)); } -#line 3218 "src/parser.c" +#line 3226 "src/parser.c" break; - case 62: /* @2: %empty */ -#line 601 "src/parser.y" + case 62: /* @1: %empty */ +#line 607 "src/parser.y" { (yyval.literal) = (yyvsp[-1].literal); } -#line 3224 "src/parser.c" +#line 3232 "src/parser.c" break; - case 63: /* String: FORMAT QQSTRING_START @2 QQString QQSTRING_END */ -#line 601 "src/parser.y" + case 63: /* String: FORMAT QQSTRING_START @1 QQString QQSTRING_END */ +#line 607 "src/parser.y" { (yyval.blk) = (yyvsp[-1].blk); jv_free((yyvsp[-2].literal)); } -#line 3233 "src/parser.c" +#line 3241 "src/parser.c" break; case 64: /* QQString: %empty */ -#line 608 "src/parser.y" +#line 614 "src/parser.y" { (yyval.blk) = gen_const(jv_string("")); } -#line 3241 "src/parser.c" +#line 3249 "src/parser.c" break; case 65: /* QQString: QQString QQSTRING_TEXT */ -#line 611 "src/parser.y" +#line 617 "src/parser.y" { (yyval.blk) = gen_binop((yyvsp[-1].blk), gen_const((yyvsp[0].literal)), '+'); } -#line 3249 "src/parser.c" +#line 3257 "src/parser.c" break; case 66: /* QQString: QQString QQSTRING_INTERP_START Exp QQSTRING_INTERP_END */ -#line 614 "src/parser.y" +#line 620 "src/parser.y" { (yyval.blk) = gen_binop((yyvsp[-3].blk), gen_format((yyvsp[-1].blk), jv_copy((yyvsp[-4].literal))), '+'); } -#line 3257 "src/parser.c" +#line 3265 "src/parser.c" break; case 67: /* ElseBody: "elif" Exp "then" Exp ElseBody */ -#line 620 "src/parser.y" +#line 626 "src/parser.y" { (yyval.blk) = gen_cond((yyvsp[-3].blk), (yyvsp[-1].blk), (yyvsp[0].blk)); } -#line 3265 "src/parser.c" +#line 3273 "src/parser.c" break; case 68: /* ElseBody: "else" Exp "end" */ -#line 623 "src/parser.y" +#line 629 "src/parser.y" { (yyval.blk) = (yyvsp[-1].blk); } -#line 3273 "src/parser.c" +#line 3281 "src/parser.c" break; case 69: /* ElseBody: "end" */ -#line 626 "src/parser.y" +#line 632 "src/parser.y" { (yyval.blk) = gen_noop(); } -#line 3281 "src/parser.c" +#line 3289 "src/parser.c" break; case 70: /* ExpD: ExpD '|' ExpD */ -#line 631 "src/parser.y" +#line 637 "src/parser.y" { (yyval.blk) = block_join((yyvsp[-2].blk), (yyvsp[0].blk)); } -#line 3289 "src/parser.c" +#line 3297 "src/parser.c" break; case 71: /* ExpD: '-' ExpD */ -#line 634 "src/parser.y" +#line 640 "src/parser.y" { (yyval.blk) = BLOCK((yyvsp[0].blk), gen_call("_negate", gen_noop())); } -#line 3297 "src/parser.c" +#line 3305 "src/parser.c" break; case 72: /* ExpD: Term */ -#line 637 "src/parser.y" +#line 643 "src/parser.y" { (yyval.blk) = (yyvsp[0].blk); } -#line 3305 "src/parser.c" +#line 3313 "src/parser.c" break; case 73: /* Term: '.' */ -#line 643 "src/parser.y" +#line 649 "src/parser.y" { (yyval.blk) = gen_noop(); } -#line 3313 "src/parser.c" +#line 3321 "src/parser.c" break; case 74: /* Term: ".." */ -#line 646 "src/parser.y" +#line 652 "src/parser.y" { (yyval.blk) = gen_call("recurse", gen_noop()); } -#line 3321 "src/parser.c" +#line 3329 "src/parser.c" break; case 75: /* Term: "break" BINDING */ -#line 649 "src/parser.y" +#line 655 "src/parser.y" { jv v = jv_string_fmt("*label-%s", jv_string_value((yyvsp[0].literal))); // impossible symbol (yyval.blk) = gen_location((yyloc), locations, @@ -3330,263 +3338,263 @@ yyreduce: jv_free(v); jv_free((yyvsp[0].literal)); } -#line 3334 "src/parser.c" +#line 3342 "src/parser.c" break; case 76: /* Term: "break" error */ -#line 657 "src/parser.y" +#line 663 "src/parser.y" { FAIL((yyloc), "break requires a label to break to"); (yyval.blk) = gen_noop(); } -#line 3343 "src/parser.c" +#line 3351 "src/parser.c" break; case 77: /* Term: Term FIELD '?' */ -#line 661 "src/parser.y" +#line 667 "src/parser.y" { (yyval.blk) = gen_index_opt((yyvsp[-2].blk), gen_const((yyvsp[-1].literal))); } -#line 3351 "src/parser.c" +#line 3359 "src/parser.c" break; case 78: /* Term: FIELD '?' */ -#line 664 "src/parser.y" +#line 670 "src/parser.y" { (yyval.blk) = gen_index_opt(gen_noop(), gen_const((yyvsp[-1].literal))); } < |