2325: expr: 2326: | LET pattern EQUAL expr IN expr 2327: { 2328: let sr = rsrange (slift $1) (src_of_expr $6) in 2329: `AST_letin (sr,($2,$4,$6)) 2330: } 2331: | rvalue { $1 } 2332: 2333: rvalue: 2334: | lambda { $1 } 2335: 2336: /* cannot use fun_args, since ambiguity on the third case (NAME) */ 2337: lambda_fun_arg: 2338: | LPAR parameter_comma_list WHEN expr RPAR { rstoken $1 $3,($2,Some $4) } 2339: | LPAR parameter_comma_list RPAR { rstoken $1 $3,($2,None) } 2340: 2341: lambda_fun_args: 2342: | lambda_fun_arg lambda_fun_args { $1 :: $2 } 2343: | lambda_fun_arg { [$1] } 2344: 2345: lambda: 2346: | dollar_apply { $1 } 2347: 2348: | adjectives FUNCTION lambda_fun_args opt_type_expr EQUAL compound 2349: { 2350: let sr = rsrange (slift $2) (fst $6) in 2351: let args = List.map snd $3 in 2352: let ret,traint = $4 in 2353: let body = snd $6 in 2354: `AST_lambda ( sr,(args, ret, body)) 2355: } 2356: 2357: | adjectives FUNCTION lambda_fun_args opt_type_expr EQRIGHTARROW expr 2358: { 2359: let sr = rsrange (slift $2) (src_of_expr $6) in 2360: let args = List.map snd $3 in 2361: let body = [`AST_fun_return (sr,$6)] in 2362: let ret,traint = $4 in 2363: `AST_lambda (sr, (args, ret, body)) 2364: } 2365: 2366: | PROCEDURE lambda_fun_args compound 2367: { 2368: let sr = rsrange (slift $1) (fst $3) in 2369: let args = List.map snd $2 in 2370: `AST_lambda ( sr, (args, `AST_void sr, snd $3)) 2371: } 2372: 2373: | PROCEDURE compound 2374: { 2375: let sr = rsrange (slift $1) (fst $2) in 2376: `AST_lambda ( sr, ([[],None], `AST_void sr, snd $2)) 2377: } 2378: 2379: dollar_apply: 2380: | tuple DOLLAR dollar_apply 2381: { 2382: let sr = rsexpr $1 $3 in 2383: `AST_apply (sr, ($1,$3)) 2384: } 2385: | tuple { $1 } 2386: 2387: tuple: 2388: | or_condition tuple_suffix 2389: { 2390: let lst = $1 :: $2 in 2391: `AST_tuple ( rslist lst, lst) 2392: } 2393: | or_condition { $1 } 2394: 2395: tuple_suffix: 2396: | COMMA or_condition tuple_suffix { $2 :: $3 } 2397: | COMMA or_condition { [$2] } 2398: 2399: /*orop: 2400: | OR {$1} 2401: or_condition: 2402: | or_condition orop and_condition { apl2 $2 "lor" [$1; $3] } 2403: | and_condition { $1 } 2404: */ 2405: 2406: /* oring formation is 'psuedo-associative' */ 2407: or_condition: 2408: | and_condition OR or_list 2409: { 2410: let sr = rsrange 2411: (src_of_expr $1) 2412: (src_of_expr (list_last $3)) 2413: in 2414: `AST_orlist (sr,$1 :: $3) 2415: } 2416: | and_condition { $1 } 2417: 2418: or_list: 2419: | and_condition OR or_list { $1 :: $3 } 2420: | and_condition { [$1] } 2421: 2422: /* oring formation is 'psuedo-associative' */ 2423: and_condition: 2424: | not_condition AND and_list 2425: { 2426: let sr = rsrange 2427: (src_of_expr $1) 2428: (src_of_expr (list_last $3)) 2429: in 2430: `AST_andlist (sr,$1 :: $3) 2431: } 2432: | not_condition { $1 } 2433: 2434: and_list: 2435: | not_condition AND and_list { $1 :: $3 } 2436: | not_condition { [$1] } 2437: 2438: /* 2439: andop: 2440: | AND {$1} 2441: and_condition: 2442: | and_condition andop not_condition { apl2 $2 "land" [$1; $3] } 2443: | not_condition { $1 } 2444: */ 2445: 2446: notop: 2447: | NOT {$1,"lnot"} 2448: not_condition: 2449: | notop not_condition { apl (fst $1) (snd $1) $2 } 2450: | comparison { $1 } 2451: 2452: chain_cmp_op: 2453: | ANDEQEQUAL { "eq",$1} 2454: | ANDNOTEQUAL { "ne",$1} 2455: | ANDLESS { "lt",$1} 2456: | ANDGREATER { "gt",$1} 2457: | ANDLESSEQUAL { "le",$1} 2458: | ANDGREATEREQUAL { "ge",$1} 2459: 2460: cmp_item: 2461: | chain_cmp_op sum { $1,$2 } 2462: 2463: cmp_item_list: 2464: | cmp_item cmp_item_list { $1 :: $2 } 2465: | cmp_item { [$1] } 2466: 2467: cmp_op: 2468: | EQEQUAL { "eq",$1 } 2469: | NOTEQUAL { "ne",$1 } 2470: | LESS { "lt",$1 } 2471: | GREATER { "gt",$1 } 2472: | LESSEQUAL { "le",$1 } 2473: | GREATEREQUAL { "ge",$1 } 2474: | ISIN { "_isin",$1 } 2475: /* hack */ 2476: 2477: comparison: 2478: | sum cmp_op sum cmp_item_list 2479: { 2480: let dummy_sr:range_srcref = ("",0,0,0,0) in 2481: let unit_tuple:expr_t = `AST_tuple (dummy_sr,[]) in 2482: let sr:range_srcref = rsrange (src_of_expr $1) (src_of_expr (snd (list_last $4))) in 2483: let si i = string_of_int i in 2484: let nm s = `AST_name (dummy_sr,s,[]) in 2485: let rec p n lst = 2486: match lst with 2487: | [] -> [] 2488: | ((op,opsrc),ex) :: t -> 2489: `AST_val_decl(slift opsrc,"_t"^si (n+1), [],None, Some ex) 2490: :: 2491: `AST_val_decl 2492: ( 2493: slift opsrc, 2494: "_r"^si (n+1), 2495: [], 2496: None, 2497: Some 2498: ( 2499: apl2 opsrc "land" 2500: [ 2501: nm ("_r"^si n); 2502: apl2 opsrc op 2503: [ 2504: nm ("_t"^si n); 2505: nm ("_t"^si (n+1)) 2506: ] 2507: ] 2508: ) 2509: ) 2510: :: 2511: p (n+1) t 2512: in 2513: let stmts = 2514: let n = List.length $4 in 2515: `AST_val_decl (src_of_expr $3,"_t0",[],None,Some $3) :: 2516: `AST_val_decl 2517: ( 2518: rsrange (src_of_expr $1) (src_of_expr $3), 2519: "_r0",[], 2520: None, 2521: Some (apl2 (snd $2) (fst $2) [$1; nm "_t0"]) 2522: ) 2523: :: 2524: p 0 $4 2525: @ 2526: [`AST_fun_return (sr,`AST_name(sr,"_r"^si n,[]))] 2527: in 2528: `AST_apply 2529: ( 2530: sr, 2531: ( 2532: `AST_lambda (sr,([[],None],flx_bool, stmts)), 2533: unit_tuple 2534: ) 2535: ) 2536: } 2537: | sum cmp_op sum { apl2 (snd $2) (fst $2) [$1; $3] } 2538: | as_expr { $1 } 2539: 2540: as_expr: 2541: | as_expr AS NAME 2542: { 2543: let sr = rsrange (src_of_expr $1) (slift (fst $3)) in 2544: `AST_as (sr,($1,snd $3)) 2545: } 2546: | setunion { $1 } 2547: 2548: setunion: 2549: | user10 VBARVBAR setunion_list 2550: { 2551: let sr = rsrange 2552: (src_of_expr $1) 2553: (src_of_expr (list_last $3)) 2554: in 2555: `AST_setunion (sr,$1 :: $3) 2556: } 2557: | user10 { $1 } 2558: 2559: setunion_list: 2560: | user10 VBARVBAR setunion_list { $1 :: $3 } 2561: | user10 { [$1] } 2562: 2563: user10: 2564: | user10 USER10 setintersection 2565: { 2566: let sr,op,fn = $2 in 2567: apl2 sr fn [$1;$3] 2568: } 2569: | setintersection { $1 } 2570: 2571: setintersection: 2572: | arrow AMPERAMPER setintersection_list 2573: { 2574: let sr = rsrange 2575: (src_of_expr $1) 2576: (src_of_expr (list_last $3)) 2577: in 2578: `AST_setintersection (sr,$1 :: $3) 2579: } 2580: | arrow { $1 } 2581: 2582: setintersection_list: 2583: | arrow AMPERAMPER setintersection_list { $1 :: $3 } 2584: | arrow { [$1] } 2585: 2586: 2587: arrow: 2588: | case_literal RIGHTARROW arrow 2589: { 2590: let sr = rsexpr $1 $3 in 2591: `AST_arrow (sr,($1,$3)) 2592: } 2593: | case_literal LONGRIGHTARROW arrow 2594: { 2595: let sr = rsexpr $1 $3 in 2596: `AST_longarrow (sr,($1,$3)) 2597: } 2598: | case_literal { $1 } 2599: 2600: case_literal: 2601: | CASE INTEGER 2602: { 2603: let sr,t,v = $2 in 2604: `AST_case_tag (rstoken $1 sr, Big_int.int_of_big_int v) 2605: } 2606: | CASE INTEGER OF sum 2607: { 2608: let _,_,v = $2 in 2609: `AST_typed_case 2610: ( 2611: rsrange (slift $1) (src_of_expr $4), 2612: Big_int.int_of_big_int v, 2613: typecode_of_expr $4 2614: ) 2615: } 2616: | CASE NAME OF sum 2617: { 2618: let sr = rsrange (slift $1) (src_of_expr $4) in 2619: let s = snd $2 in 2620: let e = $4 in 2621: `AST_variant (sr,(s,e)) 2622: } 2623: 2624: | bor { $1 } 2625: 2626: bor: 2627: | bor SLOSHVBAR bxor { apl2 $2 "bor" [$1;$3] } 2628: | bxor { $1 } 2629: 2630: bxor: 2631: | bxor SLOSHCIRCUMFLEX band { apl2 $2 "bxor" [$1;$3] } 2632: | band { $1 } 2633: 2634: band: 2635: | band SLOSHAMPER shift { apl2 $2 "band" [$1;$3] } 2636: | shift { $1 } 2637: 2638: shift: 2639: | shift LEFTSHIFT sum { apl2 $2 "shl" [$1;$3] } 2640: | shift RIGHTSHIFT sum { apl2 $2 "shr" [$1;$3] } 2641: | sum { $1 } 2642: 2643: /* sum formation is 'psuedo-associative' */ 2644: sum: 2645: | subtraction PLUS sum_list 2646: { 2647: let sr = rsrange 2648: (src_of_expr $1) 2649: (src_of_expr (list_last $3)) 2650: in 2651: `AST_sum (sr,$1 :: $3) 2652: } 2653: | subtraction { $1 } 2654: 2655: sum_list: 2656: | subtraction PLUS sum_list { $1 :: $3 } 2657: | subtraction { [$1] } 2658: 2659: subtraction: 2660: | subtraction MINUS product { apl2 $2 "sub" [$1; $3] } 2661: | product { $1 } 2662: 2663: /* product formation is 'psuedo-associative' */ 2664: product: 2665: | term STAR product_list 2666: { 2667: let sr = rsrange 2668: (src_of_expr $1) 2669: (src_of_expr (list_last $3)) 2670: in 2671: `AST_product (sr,$1 :: $3) 2672: } 2673: | term { $1 } 2674: product_list: 2675: | term STAR product_list { $1 :: $3 } 2676: | term { [$1] } 2677: 2678: 2679: /* division is left associative: note higher precedence 2680: the product, so that 2681: 2682: a * b/c * d -> a * (b/c) * d 2683: */ 2684: term: 2685: | term SLASH power { apl2 $2 "div" [$1; $3] } 2686: | term PERCENT power { apl2 $2 "mod" [$1; $3] } 2687: | prefixed { $1 } 2688: 2689: /* note weird recursion here: we need to support 2690: -x ** -x = -(x**(-x)) 2691: */ 2692: prefixed: 2693: | LVAL power 2694: { 2695: `AST_lvalue 2696: ( 2697: rsrange (slift $1) (src_of_expr $2), 2698: $2 2699: ) 2700: } 2701: | HASH power { apl $1 "len" $2 } 2702: | EXCLAMATION power { apl $1 "excl" $2 } 2703: | PLUS power { apl $1 "pos" $2 } 2704: | MINUS power { apl $1 "neg" $2 } 2705: | TILDE power { apl $1 "compl" $2 } 2706: | power { $1 } 2707: 2708: /* exponentiation is right associative */ 2709: power: 2710: | superscript STARSTAR prefixed { apl2 $2 "pow" [$1; $3] } 2711: | superscript { $1 } 2712: 2713: superscript: 2714: | superscript CIRCUMFLEX refr 2715: { 2716: let sr = rsrange (src_of_expr $1) (src_of_expr $3) in 2717: `AST_superscript (sr, ($1, $3)) 2718: } 2719: 2720: | refr { $1 } 2721: refr: 2722: | UNION LBRACE type_sum_items2 RBRACE 2723: { 2724: let sr = rstoken $1 $4 in 2725: let ls = map (fun (s,_,t)->s,t) $3 in 2726: `AST_variant_type (sr,ls) 2727: } 2728: 2729: | STRUCT compound { 2730: let sr = rsrange (slift $1) (fst $2) in 2731: let es = snd $2 in 2732: let flag = ref `Unk in 2733: (* this crud distinguishes "a=e;" from "a:t;" *) 2734: let f (stmt:statement_t) = match stmt with 2735: | `AST_assign (_,sname,(`Name (_,lhs),None), rhs) 2736: | `AST_assign (_,sname,(`Expr (_,`AST_name (_,lhs,[])),None), rhs) 2737: when sname = "_set" -> 2738: if !flag = `Unk then flag := `Ex 2739: else if !flag = `Ty then 2740: Flx_exceptions.clierr sr 2741: "anonymous struct type components require coercions!" 2742: ; 2743: lhs,rhs 2744: | `AST_call (_,`AST_coercion(_,(`AST_name(_,lhs,[]),rhs)),`AST_tuple (_,[])) -> 2745: if !flag = `Unk then flag := `Ty 2746: else if !flag = `Ex then 2747: Flx_exceptions.clierr sr 2748: "anonymous struct components require assignments!" 2749: ; 2750: lhs,`AST_expr (sr,"dummy",rhs) 2751: 2752: | _ -> Flx_exceptions.clierr sr 2753: "anonymous struct components require assignments!" 2754: in 2755: 2756: let es: (string * expr_t) list = map f es in 2757: if !flag = `Unk then 2758: if length es = 0 then `AST_tuple (sr,[]) 2759: else 2760: Flx_exceptions.clierr sr 2761: "anonymous struct: unrecognizable components!" 2762: else if !flag = `Ex then 2763: (`AST_record (sr,es):> expr_t) 2764: else if !flag = `Ty then 2765: let es : (string * typecode_t) list = map (fun (lhs,x) -> 2766: match x with 2767: | `AST_expr (_,_,rhs) -> lhs, rhs 2768: | _ -> assert false 2769: ) es 2770: in 2771: (`AST_record_type (sr,es) :> expr_t) 2772: else assert false 2773: } 2774: 2775: | AMPER refr 2776: { 2777: `AST_ref 2778: ( 2779: rsrange (slift $1) (src_of_expr $2), 2780: $2 2781: ) 2782: } 2783: | STAR refr { apl $1 "deref" $2 } 2784: | DEREF refr 2785: { 2786: `AST_deref 2787: ( 2788: rsrange (slift $1) (src_of_expr $2), 2789: $2 2790: ) 2791: } 2792: | application { $1 } 2793: 2794: /* applications is left associative */ 2795: application: 2796: | application coercion 2797: { 2798: `AST_apply (rsexpr $1 $2, ($1, $2)) 2799: } 2800: /* 2801: | MAP coercion coercion 2802: { 2803: `AST_map (rsrange (slift $1) (src_of_expr $3), $2, $3) 2804: } 2805: */ 2806: | CASENO coercion { 2807: let sr = rsrange (slift $1) (src_of_expr $2) in 2808: `AST_case_index (sr,$2) 2809: } 2810: 2811: | MACRO CTOR NAME coercion 2812: { 2813: let sr = rsrange (slift $1) (src_of_expr $4) in 2814: `AST_macro_ctor (sr,(snd $3,$4)) 2815: } 2816: 2817: | coercion { $1 } 2818: 2819: 2820: coercion: 2821: | coercion COLON factor 2822: { 2823: `AST_coercion (slift $2, ($1, typecode_of_expr $3)) 2824: } 2825: | suffixed_name { ($1:>expr_t) } 2826: | factor { $1 } 2827: 2828: 2829: factor: 2830: | dollar_name { ($1:>expr_t) } 2831: | factor DOT LSQB expr RSQB { apl2 $3 "subscript" [$1; $4] } 2832: | factor DOT LSQB expr TO expr RSQB { apl2 $3 "substring" [$1; $4; $6] } 2833: | factor DOT LSQB expr TO RSQB { apl2 $3 "copyfrom" [$1; $4] } 2834: | factor DOT LSQB TO expr RSQB { apl2 $3 "copyto" [$1; $5] } 2835: | factor DOT simple_name_parts 2836: { 2837: let rsr,name,ts = $3 in 2838: let sr = rsrange (src_of_expr $1) rsr in 2839: `AST_dot (sr, ($1, name,ts)) 2840: } 2841: | factor DOTRIGHTARROW simple_name_parts 2842: { 2843: let rsr,name,ts = $3 in 2844: let sr = rsrange (src_of_expr $1) rsr in 2845: let x = apl $2 "deref" $1 in 2846: `AST_dot (sr, (x, name,ts)) 2847: } 2848: | factor DOT LPAR INTEGER RPAR 2849: { 2850: match $4 with 2851: | (sr,t,v) -> 2852: let n = 2853: try Big_int.int_of_big_int v 2854: with _ -> 2855: failwith 2856: ( 2857: "[parser] Tuple index " ^ 2858: Big_int.string_of_big_int v ^ 2859: " too big in " ^ 2860: short_string_of_src (slift sr) 2861: ) 2862: in 2863: let sr = rsrange (src_of_expr $1) (slift $5) in 2864: `AST_get_n (sr, (n,$1)) 2865: } 2866: 2867: dollar_name: 2868: | NOEXPAND qualified_name 2869: { 2870: let e = ($2:>expr_t) in 2871: let sr = src_of_expr e in 2872: let sr = rsrange (slift $1) sr in 2873: `AST_noexpand (sr,e) 2874: } 2875: | THE qualified_name 2876: { 2877: let sr = src_of_expr $2 in 2878: let sr = rsrange (slift $1) sr in 2879: let qn = qualified_name_of_expr $2 in 2880: (`AST_the (sr,qn)) 2881: } 2882: | qualified_name{ $1 } 2883: | atom { $1 } 2884: 2885: qualified_name: 2886: | qualified_name COLONCOLON simple_name_parts 2887: { 2888: match $3 with sr,name,ts -> 2889: let sr = rsrange (src_of_expr $1) sr in 2890: `AST_lookup (sr,($1, name, ts)) 2891: } 2892: 2893: | simple_name_parts 2894: { 2895: match $1 with sr,name,ts -> 2896: (`AST_name (sr,name,ts):>expr_t) 2897: } 2898: 2899: elif: 2900: | ELIF expr THEN expr { $2,$4 } 2901: 2902: elifs: 2903: | elifs elif { $2 :: $1 } 2904: | elif { [$1] } 2905: 2906: else_part: 2907: | elifs ELSE expr 2908: { 2909: List.fold_left (* actually a right fold cause list is reversed *) 2910: (fun result (cond,thn) -> 2911: let sr = rsrange (src_of_expr cond) (src_of_expr result) in 2912: `AST_cond 2913: ( 2914: sr, 2915: ( 2916: cond, 2917: thn, 2918: result 2919: ) 2920: ) 2921: ) 2922: $3 $1 2923: } 2924: | ELSE expr { $2 } 2925: 2926: cond: 2927: | IF expr THEN expr else_part ENDIF 2928: { 2929: `AST_cond (rstoken $1 $6,($2,$4,$5)) 2930: } 2931: 2932: expr_code_prefix: 2933: | CODE LSQB expr RSQB 2934: { 2935: $1, 2936: typecode_of_expr $3 2937: } 2938: 2939: 2940: 2941: atom: 2942: | CALLBACK LSQB qualified_name RSQB 2943: { 2944: let sr = rstoken $1 $4 in 2945: let qn = qualified_name_of_expr $3 in 2946: `AST_callback (sr,qn) 2947: } 2948: 2949: | DOTDOTDOT { `AST_ellipsis (slift $1) } 2950: 2951: | type_match_expr { $1 } 2952: | expr_code_prefix NAME 2953: { 2954: let sr = rstoken (fst $1) (fst $2) in 2955: let s = snd $2 in 2956: let t = snd $1 in 2957: `AST_expr (sr,s,t) 2958: } 2959: 2960: | expr_code_prefix STRING 2961: { 2962: let sr = rstoken (fst $1) (fst $2) in 2963: let s = snd $2 in 2964: let t = snd $1 in 2965: `AST_expr (sr,s,t) 2966: } 2967: 2968: | LSQBAR expr RSQBAR 2969: { 2970: let sr = rstoken $1 $3 in 2971: match $2 with 2972: | `AST_tuple (_,ls) -> `AST_arrayof (sr,ls) 2973: | x -> `AST_arrayof (sr,[x]) 2974: } 2975: 2976: | LBRACE expr RBRACE 2977: { 2978: let sr = rstoken $1 $3 in 2979: `AST_lambda 2980: ( 2981: sr, 2982: ( 2983: [[],None], 2984: `TYP_none, 2985: [`AST_fun_return (sr,$2)] 2986: ) 2987: ) 2988: } 2989: | glr_parse { $1 } 2990: | match_expr { $1 } 2991: | regmatch_expr { $1 } 2992: | compound 2993: { 2994: let sr, stmts = $1 in 2995: `AST_lambda 2996: ( 2997: sr, 2998: ([[],None], `TYP_none, stmts) 2999: ) 3000: 3001: } 3002: | LPAR expr RPAR { $2 } 3003: | LPAR RPAR { `AST_tuple (rstoken $1 $2,[]) } 3004: | literal { $1 } 3005: | cond { $1 } 3006: | FSTRING 3007: { 3008: let sr,s = $1 in 3009: let sr = slift sr in 3010: `AST_vsprintf (sr,s) 3011: } 3012: 3013: | USERLB expr USERRB 3014: { 3015: let sr1,fnmap,lsym =$1 and sr2,rsym = $3 in 3016: let sr = rstoken sr1 sr2 in 3017: try 3018: let fn = List.assoc rsym fnmap in 3019: apl2 (fst $3) fn [$2] 3020: with Not_found -> 3021: Flx_exceptions.clierr sr "Mismatched brackets" 3022: } 3023: 3024: literal: 3025: | integer_literal { $1 } 3026: | string_literal { $1 } 3027: | float_literal { $1 } 3028: 3029: integer_literal: 3030: | INTEGER 3031: { let sr,t,v = $1 in 3032: `AST_literal (slift sr, `AST_int (t,v)) 3033: } 3034: 3035: float_literal: 3036: | FLOAT 3037: { 3038: let sr,t,v = $1 in 3039: `AST_literal (slift sr, `AST_float (t,v)) 3040: } 3041: 3042: string_literal: 3043: | STRING 3044: { 3045: let sr,s = $1 in 3046: `AST_literal (slift sr, `AST_string s) 3047: } 3048: 3049: | WSTRING 3050: { 3051: let sr,s = $1 in 3052: `AST_literal (slift sr, `AST_wstring s) 3053: } 3054: 3055: | USTRING 3056: { 3057: let sr,s = $1 in 3058: `AST_literal (slift sr, `AST_ustring s) 3059: } 3060: 3061: | CSTRING 3062: { 3063: let sr,s = $1 in 3064: `AST_literal (slift sr, `AST_cstring s) 3065: } 3066: 3067: simple_name_parts: 3068: | NAME LSQB expr RSQB 3069: { 3070: rsrange (slift (fst $1)) (slift $4), 3071: snd $1, 3072: match typecode_of_expr $3 with 3073: | `TYP_type_tuple ls -> ls 3074: | x -> [x] 3075: } 3076: 3077: | NAME 3078: { 3079: slift (fst $1), 3080: snd $1, 3081: [] 3082: } 3083: 3084: suffixed_name: 3085: | qualified_name OF factor 3086: { 3087: `AST_suffix 3088: ( 3089: rsrange (src_of_expr $1) (src_of_expr $3), 3090: (qualified_name_of_expr $1, typecode_of_expr $3) 3091: ) 3092: } 3093: 3094: %% 3095: (* trailer *) 3096: