source: mainline/uspace/app/sbi/src/p_expr.c@ ad1aedc

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since ad1aedc was 051bc69a, checked in by Jiri Svoboda <jiri@…>, 15 years ago

Update SBI to rev. 244.

  • Property mode set to 100644
File size: 17.5 KB
Line 
1/*
2 * Copyright (c) 2010 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @file Parse arithmetic expressions. */
30
31#include <assert.h>
32#include <stdlib.h>
33#include "bigint.h"
34#include "cspan.h"
35#include "debug.h"
36#include "lex.h"
37#include "list.h"
38#include "mytypes.h"
39#include "p_type.h"
40#include "parse.h"
41#include "stree.h"
42
43#include "p_expr.h"
44
45static stree_expr_t *parse_assign(parse_t *parse);
46static stree_expr_t *parse_disjunctive(parse_t *parse);
47static stree_expr_t *parse_conjunctive(parse_t *parse);
48static stree_expr_t *parse_comparative(parse_t *parse);
49static stree_expr_t *parse_additive(parse_t *parse);
50static stree_expr_t *parse_multip(parse_t *parse);
51static stree_expr_t *parse_prefix(parse_t *parse);
52static stree_expr_t *parse_prefix_new(parse_t *parse);
53static stree_expr_t *parse_postfix(parse_t *parse);
54static stree_expr_t *parse_pf_access(parse_t *parse, stree_expr_t *a);
55static stree_expr_t *parse_pf_call(parse_t *parse, stree_expr_t *a);
56static stree_expr_t *parse_pf_index(parse_t *parse, stree_expr_t *a);
57static stree_expr_t *parse_pf_as(parse_t *parse, stree_expr_t *a);
58static stree_expr_t *parse_paren(parse_t *parse);
59static stree_expr_t *parse_primitive(parse_t *parse);
60static stree_expr_t *parse_nameref(parse_t *parse);
61static stree_expr_t *parse_lit_bool(parse_t *parse);
62static stree_expr_t *parse_lit_char(parse_t *parse);
63static stree_expr_t *parse_lit_int(parse_t *parse);
64static stree_expr_t *parse_lit_ref(parse_t *parse);
65static stree_expr_t *parse_lit_string(parse_t *parse);
66static stree_expr_t *parse_self_ref(parse_t *parse);
67
68static stree_expr_t *parse_recovery_expr(parse_t *parse);
69
70/** Parse expression.
71 *
72 * Input is read from the input object associated with @a parse. If any
73 * error occurs, parse->error will @c b_true when this function
74 * returns. parse->error_bailout will be @c b_true if the error has not
75 * been recovered yet. Similar holds for other parsing functions in this
76 * module.
77 *
78 * @param parse Parser object.
79 */
80stree_expr_t *parse_expr(parse_t *parse)
81{
82#ifdef DEBUG_PARSE_TRACE
83 printf("Parse expression.\n");
84#endif
85 if (parse_is_error(parse))
86 return parse_recovery_expr(parse);
87
88 return parse_assign(parse);
89}
90
91/** Parse assignment expression.
92 *
93 * @param parse Parser object.
94 */
95static stree_expr_t *parse_assign(parse_t *parse)
96{
97 stree_expr_t *a, *b, *tmp;
98 stree_assign_t *assign;
99
100 a = parse_disjunctive(parse);
101
102 switch (lcur_lc(parse)) {
103 case lc_assign:
104 assign = stree_assign_new(ac_set);
105 break;
106 case lc_increase:
107 assign = stree_assign_new(ac_increase);
108 break;
109 default:
110 return a;
111 }
112
113 lskip(parse);
114 b = parse_disjunctive(parse);
115
116 assign->dest = a;
117 assign->src = b;
118
119 tmp = stree_expr_new(ec_assign);
120 tmp->u.assign = assign;
121 tmp->cspan = cspan_merge(a->cspan, b->cspan);
122
123 assign->expr = tmp;
124
125 return tmp;
126}
127
128/** Parse disjunctive expression.
129 *
130 * @param parse Parser object.
131 */
132static stree_expr_t *parse_disjunctive(parse_t *parse)
133{
134 stree_expr_t *a, *b, *tmp;
135 stree_binop_t *binop;
136 cspan_t *cs;
137
138 a = parse_conjunctive(parse);
139 cs = a->cspan;
140
141 while (lcur_lc(parse) == lc_or) {
142 if (parse_is_error(parse))
143 break;
144
145 lskip(parse);
146 b = parse_conjunctive(parse);
147
148 binop = stree_binop_new(bo_or);
149 binop->arg1 = a;
150 binop->arg2 = b;
151
152 tmp = stree_expr_new(ec_binop);
153 tmp->u.binop = binop;
154 tmp->cspan = cspan_merge(cs, b->cspan);
155 binop->expr = tmp;
156
157 a = tmp;
158 cs = tmp->cspan;
159 }
160
161 return a;
162}
163
164/** Parse conjunctive expression.
165 *
166 * @param parse Parser object.
167 */
168static stree_expr_t *parse_conjunctive(parse_t *parse)
169{
170 stree_expr_t *a, *b, *tmp;
171 stree_binop_t *binop;
172 cspan_t *cs;
173
174 a = parse_comparative(parse);
175 cs = a->cspan;
176
177 while (lcur_lc(parse) == lc_and) {
178 if (parse_is_error(parse))
179 break;
180
181 lskip(parse);
182 b = parse_comparative(parse);
183
184 binop = stree_binop_new(bo_and);
185 binop->arg1 = a;
186 binop->arg2 = b;
187
188 tmp = stree_expr_new(ec_binop);
189 tmp->u.binop = binop;
190 tmp->cspan = cspan_merge(cs, b->cspan);
191 binop->expr = tmp;
192
193 a = tmp;
194 cs = tmp->cspan;
195 }
196
197 return a;
198}
199
200/** Parse comparative expression.
201 *
202 * @param parse Parser object.
203 */
204static stree_expr_t *parse_comparative(parse_t *parse)
205{
206 stree_expr_t *a, *b, *tmp;
207 stree_binop_t *binop;
208 binop_class_t bc;
209 cspan_t *cs;
210
211 a = parse_additive(parse);
212 cs = a->cspan;
213
214 while (lcur_lc(parse) == lc_equal || lcur_lc(parse) == lc_notequal ||
215 lcur_lc(parse) == lc_lt || lcur_lc(parse) == lc_gt ||
216 lcur_lc(parse) == lc_lt_equal || lcur_lc(parse) == lc_gt_equal) {
217
218 if (parse_is_error(parse))
219 break;
220
221 switch (lcur_lc(parse)) {
222 case lc_equal: bc = bo_equal; break;
223 case lc_notequal: bc = bo_notequal; break;
224 case lc_lt: bc = bo_lt; break;
225 case lc_gt: bc = bo_gt; break;
226 case lc_lt_equal: bc = bo_lt_equal; break;
227 case lc_gt_equal: bc = bo_gt_equal; break;
228 default: assert(b_false);
229 }
230
231 lskip(parse);
232 b = parse_additive(parse);
233
234 binop = stree_binop_new(bc);
235 binop->arg1 = a;
236 binop->arg2 = b;
237
238 tmp = stree_expr_new(ec_binop);
239 tmp->u.binop = binop;
240 tmp->cspan = cspan_merge(cs, b->cspan);
241 binop->expr = tmp;
242
243 a = tmp;
244 cs = tmp->cspan;
245 }
246
247 return a;
248}
249
250/** Parse additive expression.
251 *
252 * @param parse Parser object.
253 */
254static stree_expr_t *parse_additive(parse_t *parse)
255{
256 stree_expr_t *a, *b, *tmp;
257 stree_binop_t *binop;
258 binop_class_t bc;
259 cspan_t *cs;
260
261 a = parse_multip(parse);
262 cs = a->cspan;
263
264 while (lcur_lc(parse) == lc_plus || lcur_lc(parse) == lc_minus) {
265 if (parse_is_error(parse))
266 break;
267
268 switch (lcur_lc(parse)) {
269 case lc_plus: bc = bo_plus; break;
270 case lc_minus: bc = bo_minus; break;
271 default: assert(b_false);
272 }
273
274 lskip(parse);
275 b = parse_multip(parse);
276
277 binop = stree_binop_new(bc);
278 binop->arg1 = a;
279 binop->arg2 = b;
280
281 tmp = stree_expr_new(ec_binop);
282 tmp->u.binop = binop;
283 tmp->cspan = cspan_merge(cs, b->cspan);
284 binop->expr = tmp;
285
286 a = tmp;
287 cs = tmp->cspan;
288 }
289
290 return a;
291}
292
293/** Parse multiplicative expression.
294 *
295 * @param parse Parser object.
296 */
297static stree_expr_t *parse_multip(parse_t *parse)
298{
299 stree_expr_t *a, *b, *tmp;
300 stree_binop_t *binop;
301 binop_class_t bc;
302 cspan_t *cs;
303
304 a = parse_prefix(parse);
305 cs = a->cspan;
306
307 while (lcur_lc(parse) == lc_mult) {
308 if (parse_is_error(parse))
309 break;
310
311 switch (lcur_lc(parse)) {
312 case lc_mult: bc = bo_mult; break;
313 default: assert(b_false);
314 }
315
316 lskip(parse);
317 b = parse_prefix(parse);
318
319 binop = stree_binop_new(bc);
320 binop->arg1 = a;
321 binop->arg2 = b;
322
323 tmp = stree_expr_new(ec_binop);
324 tmp->u.binop = binop;
325 tmp->cspan = cspan_merge(cs, b->cspan);
326 binop->expr = tmp;
327
328 a = tmp;
329 cs = tmp->cspan;
330 }
331
332 return a;
333}
334
335/** Parse prefix expression.
336 *
337 * @param parse Parser object.
338 */
339static stree_expr_t *parse_prefix(parse_t *parse)
340{
341 stree_expr_t *a;
342 stree_expr_t *tmp;
343 stree_unop_t *unop;
344 unop_class_t uc;
345 cspan_t *cs0;
346
347 switch (lcur_lc(parse)) {
348 case lc_plus:
349 case lc_minus:
350 case lc_not:
351 if (parse_is_error(parse))
352 return parse_recovery_expr(parse);
353
354 switch (lcur_lc(parse)) {
355 case lc_plus: uc = uo_plus; break;
356 case lc_minus: uc = uo_minus; break;
357 case lc_not: uc = uo_not; break;
358 default: assert(b_false);
359 }
360
361 cs0 = lcur_span(parse);
362 lskip(parse);
363 a = parse_postfix(parse);
364
365 unop = stree_unop_new(uc);
366 unop->arg = a;
367
368 tmp = stree_expr_new(ec_unop);
369 tmp->u.unop = unop;
370 tmp->cspan = cspan_merge(cs0, a->cspan);
371 unop->expr = tmp;
372 a = tmp;
373 break;
374 case lc_new:
375 a = parse_prefix_new(parse);
376 break;
377 default:
378 a = parse_postfix(parse);
379 break;
380 }
381
382 return a;
383}
384
385/** Parse @c new operator.
386 *
387 * @param parse Parser object.
388 */
389static stree_expr_t *parse_prefix_new(parse_t *parse)
390{
391 stree_texpr_t *texpr;
392 stree_new_t *new_op;
393 stree_expr_t *expr;
394 stree_expr_t *arg;
395 cspan_t *cs0, *cs1;
396
397 cs0 = lcur_span(parse);
398 lmatch(parse, lc_new);
399 texpr = parse_texpr(parse);
400
401 /* XXX Take span from texpr */
402 cs1 = lprev_span(parse);
403
404 new_op = stree_new_new();
405 new_op->texpr = texpr;
406 expr = stree_expr_new(ec_new);
407 expr->u.new_op = new_op;
408
409 list_init(&new_op->ctor_args);
410
411 /* Parenthesized arguments should be present except for arrays. */
412 if (texpr->tc != tc_tindex) {
413 lmatch(parse, lc_lparen);
414
415 /* Parse constructor arguments */
416
417 if (lcur_lc(parse) != lc_rparen) {
418 while (!parse_is_error(parse)) {
419 arg = parse_expr(parse);
420 list_append(&new_op->ctor_args, arg);
421
422 if (lcur_lc(parse) == lc_rparen)
423 break;
424 lmatch(parse, lc_comma);
425 }
426 }
427
428 lmatch(parse, lc_rparen);
429 cs1 = cspan_merge(cs0, lprev_span(parse));
430 }
431
432 expr->cspan = cspan_merge(cs0, cs1);
433 new_op->expr = expr;
434
435 return expr;
436}
437
438/** Parse postfix expression.
439 *
440 * @param parse Parser object.
441 */
442static stree_expr_t *parse_postfix(parse_t *parse)
443{
444 stree_expr_t *a;
445 stree_expr_t *tmp;
446
447 a = parse_paren(parse);
448
449 while (lcur_lc(parse) == lc_period || lcur_lc(parse) == lc_lparen ||
450 lcur_lc(parse) == lc_lsbr || lcur_lc(parse) == lc_as) {
451
452 if (parse_is_error(parse))
453 break;
454
455 switch (lcur_lc(parse)) {
456 case lc_period:
457 tmp = parse_pf_access(parse, a);
458 break;
459 case lc_lparen:
460 tmp = parse_pf_call(parse, a);
461 break;
462 case lc_lsbr:
463 tmp = parse_pf_index(parse, a);
464 break;
465 case lc_as:
466 tmp = parse_pf_as(parse, a);
467 break;
468 default:
469 assert(b_false);
470 }
471
472 a = tmp;
473 }
474
475 return a;
476}
477
478/** Parse member access expression
479 *
480 * @param parse Parser object.
481 */
482static stree_expr_t *parse_pf_access(parse_t *parse, stree_expr_t *a)
483{
484 stree_ident_t *ident;
485 stree_expr_t *expr;
486 stree_access_t *access;
487 cspan_t *cs1;
488
489 lmatch(parse, lc_period);
490 ident = parse_ident(parse);
491
492 /* XXX Take span from ident */
493 cs1 = lprev_span(parse);
494
495 access = stree_access_new();
496 access->arg = a;
497 access->member_name = ident;
498
499 expr = stree_expr_new(ec_access);
500 expr->u.access = access;
501 expr->cspan = cspan_merge(a->cspan, cs1);
502
503 access->expr = expr;
504
505 return expr;
506}
507
508/** Parse function call expression.
509 *
510 * @param parse Parser object.
511 */
512static stree_expr_t *parse_pf_call(parse_t *parse, stree_expr_t *a)
513{
514 stree_expr_t *expr;
515 stree_call_t *call;
516 stree_expr_t *arg;
517 cspan_t *cs1;
518
519 lmatch(parse, lc_lparen);
520
521 call = stree_call_new();
522 call->fun = a;
523 list_init(&call->args);
524
525 /* Parse function arguments */
526
527 if (lcur_lc(parse) != lc_rparen) {
528 while (!parse_is_error(parse)) {
529 arg = parse_expr(parse);
530 list_append(&call->args, arg);
531
532 if (lcur_lc(parse) == lc_rparen)
533 break;
534 lmatch(parse, lc_comma);
535 }
536 }
537
538 lmatch(parse, lc_rparen);
539 cs1 = lprev_span(parse);
540
541 expr = stree_expr_new(ec_call);
542 expr->u.call = call;
543 expr->cspan = cspan_merge(a->cspan, cs1);
544 call->expr = expr;
545
546 return expr;
547}
548
549/** Parse index expression.
550 *
551 * @param parse Parser object.
552 */
553static stree_expr_t *parse_pf_index(parse_t *parse, stree_expr_t *a)
554{
555 stree_expr_t *expr;
556 stree_index_t *index;
557 stree_expr_t *arg;
558 cspan_t *cs1;
559
560 lmatch(parse, lc_lsbr);
561
562 index = stree_index_new();
563 index->base = a;
564 list_init(&index->args);
565
566 /* Parse indices */
567
568 if (lcur_lc(parse) != lc_rsbr) {
569 while (!parse_is_error(parse)) {
570 arg = parse_expr(parse);
571 list_append(&index->args, arg);
572
573 if (lcur_lc(parse) == lc_rsbr)
574 break;
575 lmatch(parse, lc_comma);
576 }
577 }
578
579 lmatch(parse, lc_rsbr);
580 cs1 = lprev_span(parse);
581
582 expr = stree_expr_new(ec_index);
583 expr->u.index = index;
584 expr->cspan = cspan_merge(a->cspan, cs1);
585 index->expr = expr;
586
587 return expr;
588}
589
590/** Parse @c as operator.
591 *
592 * @param parse Parser object.
593 */
594static stree_expr_t *parse_pf_as(parse_t *parse, stree_expr_t *a)
595{
596 stree_expr_t *expr;
597 stree_texpr_t *texpr;
598 stree_as_t *as_op;
599 cspan_t *cs1;
600
601 lmatch(parse, lc_as);
602 texpr = parse_texpr(parse);
603
604 /* XXX Take span from texpr */
605 cs1 = lprev_span(parse);
606
607 as_op = stree_as_new();
608 as_op->arg = a;
609 as_op->dtype = texpr;
610
611 expr = stree_expr_new(ec_as);
612 expr->u.as_op = as_op;
613 expr->cspan = cspan_merge(a->cspan, cs1);
614
615 as_op->expr = expr;
616
617 return expr;
618}
619
620/** Parse possibly partenthesized expression.
621 *
622 * @param parse Parser object.
623 */
624static stree_expr_t *parse_paren(parse_t *parse)
625{
626 stree_expr_t *expr;
627 cspan_t *cs0, *cs1;
628
629 if (lcur_lc(parse) == lc_lparen) {
630 cs0 = lcur_span(parse);
631 lskip(parse);
632 expr = parse_expr(parse);
633 lmatch(parse, lc_rparen);
634 cs1 = lprev_span(parse);
635
636 expr->cspan = cspan_merge(cs0, cs1);
637 } else {
638 expr = parse_primitive(parse);
639 }
640
641 return expr;
642}
643
644/** Parse primitive expression.
645 *
646 * @param parse Parser object.
647 */
648static stree_expr_t *parse_primitive(parse_t *parse)
649{
650 stree_expr_t *expr;
651
652 switch (lcur_lc(parse)) {
653 case lc_ident:
654 expr = parse_nameref(parse);
655 break;
656 case lc_false:
657 case lc_true:
658 expr = parse_lit_bool(parse);
659 break;
660 case lc_lit_char:
661 expr = parse_lit_char(parse);
662 break;
663 case lc_lit_int:
664 expr = parse_lit_int(parse);
665 break;
666 case lc_nil:
667 expr = parse_lit_ref(parse);
668 break;
669 case lc_lit_string:
670 expr = parse_lit_string(parse);
671 break;
672 case lc_self:
673 expr = parse_self_ref(parse);
674 break;
675 default:
676 lunexpected_error(parse);
677 expr = parse_recovery_expr(parse);
678 }
679
680 return expr;
681}
682
683/** Parse name reference.
684 *
685 * @param parse Parser object.
686 */
687static stree_expr_t *parse_nameref(parse_t *parse)
688{
689 stree_nameref_t *nameref;
690 stree_expr_t *expr;
691
692 nameref = stree_nameref_new();
693 nameref->name = parse_ident(parse);
694 expr = stree_expr_new(ec_nameref);
695 expr->u.nameref = nameref;
696 expr->cspan = lprev_span(parse);
697 nameref->expr = expr;
698
699 return expr;
700}
701
702/** Parse boolean literal.
703 *
704 * @param parse Parser object.
705 */
706static stree_expr_t *parse_lit_bool(parse_t *parse)
707{
708 stree_literal_t *literal;
709 stree_expr_t *expr;
710 bool_t value;
711
712 switch (lcur_lc(parse)) {
713 case lc_false: value = b_false; break;
714 case lc_true: value = b_true; break;
715 default: assert(b_false);
716 }
717
718 lskip(parse);
719
720 literal = stree_literal_new(ltc_bool);
721 literal->u.lit_bool.value = value;
722
723 expr = stree_expr_new(ec_literal);
724 expr->u.literal = literal;
725 expr->cspan = lprev_span(parse);
726 literal->expr = expr;
727
728 return expr;
729}
730
731/** Parse character literal.
732 *
733 * @param parse Parser object.
734 */
735static stree_expr_t *parse_lit_char(parse_t *parse)
736{
737 stree_literal_t *literal;
738 stree_expr_t *expr;
739
740 lcheck(parse, lc_lit_char);
741
742 literal = stree_literal_new(ltc_char);
743 bigint_clone(&lcur(parse)->u.lit_char.value,
744 &literal->u.lit_char.value);
745
746 lskip(parse);
747
748 expr = stree_expr_new(ec_literal);
749 expr->u.literal = literal;
750 expr->cspan = lprev_span(parse);
751 literal->expr = expr;
752
753 return expr;
754}
755
756/** Parse integer literal.
757 *
758 * @param parse Parser object.
759 */
760static stree_expr_t *parse_lit_int(parse_t *parse)
761{
762 stree_literal_t *literal;
763 stree_expr_t *expr;
764
765 lcheck(parse, lc_lit_int);
766
767 literal = stree_literal_new(ltc_int);
768 bigint_clone(&lcur(parse)->u.lit_int.value,
769 &literal->u.lit_int.value);
770
771 lskip(parse);
772
773 expr = stree_expr_new(ec_literal);
774 expr->u.literal = literal;
775 expr->cspan = lprev_span(parse);
776 literal->expr = expr;
777
778 return expr;
779}
780
781/** Parse reference literal (@c nil).
782 *
783 * @param parse Parser object.
784 */
785static stree_expr_t *parse_lit_ref(parse_t *parse)
786{
787 stree_literal_t *literal;
788 stree_expr_t *expr;
789
790 lmatch(parse, lc_nil);
791
792 literal = stree_literal_new(ltc_ref);
793
794 expr = stree_expr_new(ec_literal);
795 expr->u.literal = literal;
796 expr->cspan = lprev_span(parse);
797 literal->expr = expr;
798
799 return expr;
800}
801
802/** Parse string literal.
803 *
804 * @param parse Parser object.
805 */
806static stree_expr_t *parse_lit_string(parse_t *parse)
807{
808 stree_literal_t *literal;
809 stree_expr_t *expr;
810
811 lcheck(parse, lc_lit_string);
812
813 literal = stree_literal_new(ltc_string);
814 literal->u.lit_string.value = lcur(parse)->u.lit_string.value;
815
816 lskip(parse);
817
818 expr = stree_expr_new(ec_literal);
819 expr->u.literal = literal;
820 expr->cspan = lprev_span(parse);
821 literal->expr = expr;
822
823 return expr;
824}
825
826/** Parse @c self keyword.
827 *
828 * @param parse Parser object.
829 */
830static stree_expr_t *parse_self_ref(parse_t *parse)
831{
832 stree_self_ref_t *self_ref;
833 stree_expr_t *expr;
834
835 lmatch(parse, lc_self);
836
837 self_ref = stree_self_ref_new();
838
839 expr = stree_expr_new(ec_self_ref);
840 expr->u.self_ref = self_ref;
841 expr->cspan = lprev_span(parse);
842 self_ref->expr = expr;
843
844 return expr;
845}
846
847/** Construct a special recovery expression.
848 *
849 * @param parse Parser object.
850 */
851static stree_expr_t *parse_recovery_expr(parse_t *parse)
852{
853 stree_literal_t *literal;
854 stree_expr_t *expr;
855
856 (void) parse;
857
858 literal = stree_literal_new(ltc_ref);
859
860 expr = stree_expr_new(ec_literal);
861 expr->u.literal = literal;
862 literal->expr = expr;
863
864 return expr;
865}
Note: See TracBrowser for help on using the repository browser.