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

Last change on this file was 1433ecda, checked in by Jiri Svoboda <jiri@…>, 7 years ago

Fix cstyle: make ccheck-fix and commit only files where all the changes are good.

  • 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:
223 bc = bo_equal;
224 break;
225 case lc_notequal:
226 bc = bo_notequal;
227 break;
228 case lc_lt:
229 bc = bo_lt;
230 break;
231 case lc_gt:
232 bc = bo_gt;
233 break;
234 case lc_lt_equal:
235 bc = bo_lt_equal;
236 break;
237 case lc_gt_equal:
238 bc = bo_gt_equal;
239 break;
240 default:
241 assert(b_false);
242 }
243
244 lskip(parse);
245 b = parse_additive(parse);
246
247 binop = stree_binop_new(bc);
248 binop->arg1 = a;
249 binop->arg2 = b;
250
251 tmp = stree_expr_new(ec_binop);
252 tmp->u.binop = binop;
253 tmp->cspan = cspan_merge(cs, b->cspan);
254 binop->expr = tmp;
255
256 a = tmp;
257 cs = tmp->cspan;
258 }
259
260 return a;
261}
262
263/** Parse additive expression.
264 *
265 * @param parse Parser object.
266 */
267static stree_expr_t *parse_additive(parse_t *parse)
268{
269 stree_expr_t *a, *b, *tmp;
270 stree_binop_t *binop;
271 binop_class_t bc;
272 cspan_t *cs;
273
274 a = parse_multip(parse);
275 cs = a->cspan;
276
277 while (lcur_lc(parse) == lc_plus || lcur_lc(parse) == lc_minus) {
278 if (parse_is_error(parse))
279 break;
280
281 switch (lcur_lc(parse)) {
282 case lc_plus:
283 bc = bo_plus;
284 break;
285 case lc_minus:
286 bc = bo_minus;
287 break;
288 default:
289 assert(b_false);
290 }
291
292 lskip(parse);
293 b = parse_multip(parse);
294
295 binop = stree_binop_new(bc);
296 binop->arg1 = a;
297 binop->arg2 = b;
298
299 tmp = stree_expr_new(ec_binop);
300 tmp->u.binop = binop;
301 tmp->cspan = cspan_merge(cs, b->cspan);
302 binop->expr = tmp;
303
304 a = tmp;
305 cs = tmp->cspan;
306 }
307
308 return a;
309}
310
311/** Parse multiplicative expression.
312 *
313 * @param parse Parser object.
314 */
315static stree_expr_t *parse_multip(parse_t *parse)
316{
317 stree_expr_t *a, *b, *tmp;
318 stree_binop_t *binop;
319 binop_class_t bc;
320 cspan_t *cs;
321
322 a = parse_prefix(parse);
323 cs = a->cspan;
324
325 while (lcur_lc(parse) == lc_mult) {
326 if (parse_is_error(parse))
327 break;
328
329 switch (lcur_lc(parse)) {
330 case lc_mult:
331 bc = bo_mult;
332 break;
333 default:
334 assert(b_false);
335 }
336
337 lskip(parse);
338 b = parse_prefix(parse);
339
340 binop = stree_binop_new(bc);
341 binop->arg1 = a;
342 binop->arg2 = b;
343
344 tmp = stree_expr_new(ec_binop);
345 tmp->u.binop = binop;
346 tmp->cspan = cspan_merge(cs, b->cspan);
347 binop->expr = tmp;
348
349 a = tmp;
350 cs = tmp->cspan;
351 }
352
353 return a;
354}
355
356/** Parse prefix expression.
357 *
358 * @param parse Parser object.
359 */
360static stree_expr_t *parse_prefix(parse_t *parse)
361{
362 stree_expr_t *a;
363 stree_expr_t *tmp;
364 stree_unop_t *unop;
365 unop_class_t uc;
366 cspan_t *cs0;
367
368 switch (lcur_lc(parse)) {
369 case lc_plus:
370 case lc_minus:
371 case lc_not:
372 if (parse_is_error(parse))
373 return parse_recovery_expr(parse);
374
375 switch (lcur_lc(parse)) {
376 case lc_plus:
377 uc = uo_plus;
378 break;
379 case lc_minus:
380 uc = uo_minus;
381 break;
382 case lc_not:
383 uc = uo_not;
384 break;
385 default:
386 assert(b_false);
387 }
388
389 cs0 = lcur_span(parse);
390 lskip(parse);
391 a = parse_postfix(parse);
392
393 unop = stree_unop_new(uc);
394 unop->arg = a;
395
396 tmp = stree_expr_new(ec_unop);
397 tmp->u.unop = unop;
398 tmp->cspan = cspan_merge(cs0, a->cspan);
399 unop->expr = tmp;
400 a = tmp;
401 break;
402 case lc_new:
403 a = parse_prefix_new(parse);
404 break;
405 default:
406 a = parse_postfix(parse);
407 break;
408 }
409
410 return a;
411}
412
413/** Parse @c new operator.
414 *
415 * @param parse Parser object.
416 */
417static stree_expr_t *parse_prefix_new(parse_t *parse)
418{
419 stree_texpr_t *texpr;
420 stree_new_t *new_op;
421 stree_expr_t *expr;
422 stree_expr_t *arg;
423 cspan_t *cs0, *cs1;
424
425 cs0 = lcur_span(parse);
426 lmatch(parse, lc_new);
427 texpr = parse_texpr(parse);
428
429 /* XXX Take span from texpr */
430 cs1 = lprev_span(parse);
431
432 new_op = stree_new_new();
433 new_op->texpr = texpr;
434 expr = stree_expr_new(ec_new);
435 expr->u.new_op = new_op;
436
437 list_init(&new_op->ctor_args);
438
439 /* Parenthesized arguments should be present except for arrays. */
440 if (texpr->tc != tc_tindex) {
441 lmatch(parse, lc_lparen);
442
443 /* Parse constructor arguments */
444
445 if (lcur_lc(parse) != lc_rparen) {
446 while (!parse_is_error(parse)) {
447 arg = parse_expr(parse);
448 list_append(&new_op->ctor_args, arg);
449
450 if (lcur_lc(parse) == lc_rparen)
451 break;
452 lmatch(parse, lc_comma);
453 }
454 }
455
456 lmatch(parse, lc_rparen);
457 cs1 = cspan_merge(cs0, lprev_span(parse));
458 }
459
460 expr->cspan = cspan_merge(cs0, cs1);
461 new_op->expr = expr;
462
463 return expr;
464}
465
466/** Parse postfix expression.
467 *
468 * @param parse Parser object.
469 */
470static stree_expr_t *parse_postfix(parse_t *parse)
471{
472 stree_expr_t *a;
473 stree_expr_t *tmp;
474
475 a = parse_paren(parse);
476
477 while (lcur_lc(parse) == lc_period || lcur_lc(parse) == lc_lparen ||
478 lcur_lc(parse) == lc_lsbr || lcur_lc(parse) == lc_as) {
479
480 if (parse_is_error(parse))
481 break;
482
483 switch (lcur_lc(parse)) {
484 case lc_period:
485 tmp = parse_pf_access(parse, a);
486 break;
487 case lc_lparen:
488 tmp = parse_pf_call(parse, a);
489 break;
490 case lc_lsbr:
491 tmp = parse_pf_index(parse, a);
492 break;
493 case lc_as:
494 tmp = parse_pf_as(parse, a);
495 break;
496 default:
497 assert(b_false);
498 }
499
500 a = tmp;
501 }
502
503 return a;
504}
505
506/** Parse member access expression
507 *
508 * @param parse Parser object.
509 */
510static stree_expr_t *parse_pf_access(parse_t *parse, stree_expr_t *a)
511{
512 stree_ident_t *ident;
513 stree_expr_t *expr;
514 stree_access_t *access;
515 cspan_t *cs1;
516
517 lmatch(parse, lc_period);
518 ident = parse_ident(parse);
519
520 /* XXX Take span from ident */
521 cs1 = lprev_span(parse);
522
523 access = stree_access_new();
524 access->arg = a;
525 access->member_name = ident;
526
527 expr = stree_expr_new(ec_access);
528 expr->u.access = access;
529 expr->cspan = cspan_merge(a->cspan, cs1);
530
531 access->expr = expr;
532
533 return expr;
534}
535
536/** Parse function call expression.
537 *
538 * @param parse Parser object.
539 */
540static stree_expr_t *parse_pf_call(parse_t *parse, stree_expr_t *a)
541{
542 stree_expr_t *expr;
543 stree_call_t *call;
544 stree_expr_t *arg;
545 cspan_t *cs1;
546
547 lmatch(parse, lc_lparen);
548
549 call = stree_call_new();
550 call->fun = a;
551 list_init(&call->args);
552
553 /* Parse function arguments */
554
555 if (lcur_lc(parse) != lc_rparen) {
556 while (!parse_is_error(parse)) {
557 arg = parse_expr(parse);
558 list_append(&call->args, arg);
559
560 if (lcur_lc(parse) == lc_rparen)
561 break;
562 lmatch(parse, lc_comma);
563 }
564 }
565
566 lmatch(parse, lc_rparen);
567 cs1 = lprev_span(parse);
568
569 expr = stree_expr_new(ec_call);
570 expr->u.call = call;
571 expr->cspan = cspan_merge(a->cspan, cs1);
572 call->expr = expr;
573
574 return expr;
575}
576
577/** Parse index expression.
578 *
579 * @param parse Parser object.
580 */
581static stree_expr_t *parse_pf_index(parse_t *parse, stree_expr_t *a)
582{
583 stree_expr_t *expr;
584 stree_index_t *index;
585 stree_expr_t *arg;
586 cspan_t *cs1;
587
588 lmatch(parse, lc_lsbr);
589
590 index = stree_index_new();
591 index->base = a;
592 list_init(&index->args);
593
594 /* Parse indices */
595
596 if (lcur_lc(parse) != lc_rsbr) {
597 while (!parse_is_error(parse)) {
598 arg = parse_expr(parse);
599 list_append(&index->args, arg);
600
601 if (lcur_lc(parse) == lc_rsbr)
602 break;
603 lmatch(parse, lc_comma);
604 }
605 }
606
607 lmatch(parse, lc_rsbr);
608 cs1 = lprev_span(parse);
609
610 expr = stree_expr_new(ec_index);
611 expr->u.index = index;
612 expr->cspan = cspan_merge(a->cspan, cs1);
613 index->expr = expr;
614
615 return expr;
616}
617
618/** Parse @c as operator.
619 *
620 * @param parse Parser object.
621 */
622static stree_expr_t *parse_pf_as(parse_t *parse, stree_expr_t *a)
623{
624 stree_expr_t *expr;
625 stree_texpr_t *texpr;
626 stree_as_t *as_op;
627 cspan_t *cs1;
628
629 lmatch(parse, lc_as);
630 texpr = parse_texpr(parse);
631
632 /* XXX Take span from texpr */
633 cs1 = lprev_span(parse);
634
635 as_op = stree_as_new();
636 as_op->arg = a;
637 as_op->dtype = texpr;
638
639 expr = stree_expr_new(ec_as);
640 expr->u.as_op = as_op;
641 expr->cspan = cspan_merge(a->cspan, cs1);
642
643 as_op->expr = expr;
644
645 return expr;
646}
647
648/** Parse possibly partenthesized expression.
649 *
650 * @param parse Parser object.
651 */
652static stree_expr_t *parse_paren(parse_t *parse)
653{
654 stree_expr_t *expr;
655 cspan_t *cs0, *cs1;
656
657 if (lcur_lc(parse) == lc_lparen) {
658 cs0 = lcur_span(parse);
659 lskip(parse);
660 expr = parse_expr(parse);
661 lmatch(parse, lc_rparen);
662 cs1 = lprev_span(parse);
663
664 expr->cspan = cspan_merge(cs0, cs1);
665 } else {
666 expr = parse_primitive(parse);
667 }
668
669 return expr;
670}
671
672/** Parse primitive expression.
673 *
674 * @param parse Parser object.
675 */
676static stree_expr_t *parse_primitive(parse_t *parse)
677{
678 stree_expr_t *expr;
679
680 switch (lcur_lc(parse)) {
681 case lc_ident:
682 expr = parse_nameref(parse);
683 break;
684 case lc_false:
685 case lc_true:
686 expr = parse_lit_bool(parse);
687 break;
688 case lc_lit_char:
689 expr = parse_lit_char(parse);
690 break;
691 case lc_lit_int:
692 expr = parse_lit_int(parse);
693 break;
694 case lc_nil:
695 expr = parse_lit_ref(parse);
696 break;
697 case lc_lit_string:
698 expr = parse_lit_string(parse);
699 break;
700 case lc_self:
701 expr = parse_self_ref(parse);
702 break;
703 default:
704 lunexpected_error(parse);
705 expr = parse_recovery_expr(parse);
706 }
707
708 return expr;
709}
710
711/** Parse name reference.
712 *
713 * @param parse Parser object.
714 */
715static stree_expr_t *parse_nameref(parse_t *parse)
716{
717 stree_nameref_t *nameref;
718 stree_expr_t *expr;
719
720 nameref = stree_nameref_new();
721 nameref->name = parse_ident(parse);
722 expr = stree_expr_new(ec_nameref);
723 expr->u.nameref = nameref;
724 expr->cspan = lprev_span(parse);
725 nameref->expr = expr;
726
727 return expr;
728}
729
730/** Parse boolean literal.
731 *
732 * @param parse Parser object.
733 */
734static stree_expr_t *parse_lit_bool(parse_t *parse)
735{
736 stree_literal_t *literal;
737 stree_expr_t *expr;
738 bool_t value;
739
740 switch (lcur_lc(parse)) {
741 case lc_false:
742 value = b_false;
743 break;
744 case lc_true:
745 value = b_true;
746 break;
747 default:
748 assert(b_false);
749 }
750
751 lskip(parse);
752
753 literal = stree_literal_new(ltc_bool);
754 literal->u.lit_bool.value = value;
755
756 expr = stree_expr_new(ec_literal);
757 expr->u.literal = literal;
758 expr->cspan = lprev_span(parse);
759 literal->expr = expr;
760
761 return expr;
762}
763
764/** Parse character literal.
765 *
766 * @param parse Parser object.
767 */
768static stree_expr_t *parse_lit_char(parse_t *parse)
769{
770 stree_literal_t *literal;
771 stree_expr_t *expr;
772
773 lcheck(parse, lc_lit_char);
774
775 literal = stree_literal_new(ltc_char);
776 bigint_clone(&lcur(parse)->u.lit_char.value,
777 &literal->u.lit_char.value);
778
779 lskip(parse);
780
781 expr = stree_expr_new(ec_literal);
782 expr->u.literal = literal;
783 expr->cspan = lprev_span(parse);
784 literal->expr = expr;
785
786 return expr;
787}
788
789/** Parse integer literal.
790 *
791 * @param parse Parser object.
792 */
793static stree_expr_t *parse_lit_int(parse_t *parse)
794{
795 stree_literal_t *literal;
796 stree_expr_t *expr;
797
798 lcheck(parse, lc_lit_int);
799
800 literal = stree_literal_new(ltc_int);
801 bigint_clone(&lcur(parse)->u.lit_int.value,
802 &literal->u.lit_int.value);
803
804 lskip(parse);
805
806 expr = stree_expr_new(ec_literal);
807 expr->u.literal = literal;
808 expr->cspan = lprev_span(parse);
809 literal->expr = expr;
810
811 return expr;
812}
813
814/** Parse reference literal (@c nil).
815 *
816 * @param parse Parser object.
817 */
818static stree_expr_t *parse_lit_ref(parse_t *parse)
819{
820 stree_literal_t *literal;
821 stree_expr_t *expr;
822
823 lmatch(parse, lc_nil);
824
825 literal = stree_literal_new(ltc_ref);
826
827 expr = stree_expr_new(ec_literal);
828 expr->u.literal = literal;
829 expr->cspan = lprev_span(parse);
830 literal->expr = expr;
831
832 return expr;
833}
834
835/** Parse string literal.
836 *
837 * @param parse Parser object.
838 */
839static stree_expr_t *parse_lit_string(parse_t *parse)
840{
841 stree_literal_t *literal;
842 stree_expr_t *expr;
843
844 lcheck(parse, lc_lit_string);
845
846 literal = stree_literal_new(ltc_string);
847 literal->u.lit_string.value = lcur(parse)->u.lit_string.value;
848
849 lskip(parse);
850
851 expr = stree_expr_new(ec_literal);
852 expr->u.literal = literal;
853 expr->cspan = lprev_span(parse);
854 literal->expr = expr;
855
856 return expr;
857}
858
859/** Parse @c self keyword.
860 *
861 * @param parse Parser object.
862 */
863static stree_expr_t *parse_self_ref(parse_t *parse)
864{
865 stree_self_ref_t *self_ref;
866 stree_expr_t *expr;
867
868 lmatch(parse, lc_self);
869
870 self_ref = stree_self_ref_new();
871
872 expr = stree_expr_new(ec_self_ref);
873 expr->u.self_ref = self_ref;
874 expr->cspan = lprev_span(parse);
875 self_ref->expr = expr;
876
877 return expr;
878}
879
880/** Construct a special recovery expression.
881 *
882 * @param parse Parser object.
883 */
884static stree_expr_t *parse_recovery_expr(parse_t *parse)
885{
886 stree_literal_t *literal;
887 stree_expr_t *expr;
888
889 (void) parse;
890
891 literal = stree_literal_new(ltc_ref);
892
893 expr = stree_expr_new(ec_literal);
894 expr->u.literal = literal;
895 literal->expr = expr;
896
897 return expr;
898}
Note: See TracBrowser for help on using the repository browser.