Changeset 1ebc1a62 in mainline for uspace/app/sbi/src/parse.c


Ignore:
Timestamp:
2010-03-29T20:30:29Z (14 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
a95310e
Parents:
5da468e
Message:

Update SBI to rev. 157.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/sbi/src/parse.c

    r5da468e r1ebc1a62  
    8484        parse->cur_mod = parse->program->module;
    8585        parse->lex = lex;
     86
     87        parse->error = b_false;
     88        parse->error_bailout = b_false;
     89
    8690        lex_next(parse->lex);
    8791}
     
    9397        stree_modm_t *modm;
    9498
    95         while (lcur_lc(parse) != lc_eof) {
     99        while (lcur_lc(parse) != lc_eof && !parse_is_error(parse)) {
    96100                switch (lcur_lc(parse)) {
    97101                case lc_class:
     
    155159
    156160        /* Parse class, struct or interface members. */
    157         while (lcur_lc(parse) != lc_end) {
     161        while (lcur_lc(parse) != lc_end && !parse_is_error(parse)) {
    158162                csimbr = parse_csimbr(parse, csi);
    159163                list_append(&csi->members, csimbr);
     
    235239
    236240                /* Parse formal parameters. */
    237                 while (b_true) {
     241                while (!parse_is_error(parse)) {
    238242                        arg = parse_proc_arg(parse);
    239243
     
    264268
    265269        /* Parse attributes. */
    266         while (lcur_lc(parse) == lc_comma) {
     270        while (lcur_lc(parse) == lc_comma && !parse_is_error(parse)) {
    267271                lskip(parse);
    268272                attr = parse_symbol_attr(parse);
     
    281285                        symbol_print_fqn(symbol);
    282286                        printf("' has no body.\n");
    283                         exit(1);
     287                        parse_note_error(parse);
    284288                }
    285289                fun->proc->body = NULL;
     
    345349
    346350                /* Parse formal parameters. */
    347                 while (b_true) {
     351                while (!parse_is_error(parse)) {
    348352                        arg = parse_proc_arg(parse);
    349353                        if (stree_arg_has_attr(arg, aac_packed)) {
     
    370374        lmatch(parse, lc_is);
    371375
    372         while (lcur_lc(parse) != lc_end) {
     376        while (lcur_lc(parse) != lc_end && !parse_is_error(parse)) {
    373377                switch (lcur_lc(parse)) {
    374378                case lc_get:
     
    377381                        if (prop->getter != NULL) {
    378382                                printf("Error: Duplicate getter.\n");
    379                                 exit(1);
     383                                (void) parse_block(parse); /* XXX Free */
     384                                lmatch(parse, lc_end);
     385                                parse_note_error(parse);
     386                                break;
    380387                        }
    381388
     
    395402                        if (prop->setter != NULL) {
    396403                                printf("Error: Duplicate setter.\n");
    397                                 exit(1);
     404                                (void) parse_block(parse); /* XXX Free */
     405                                lmatch(parse, lc_end);
     406                                parse_note_error(parse);
    398407                        }
    399408
     
    424433                lem_print(lcur(parse));
    425434                printf("'.\n");
    426                 exit(1);
     435                parse_note_error(parse);
    427436        }
    428437
     
    447456
    448457        /* Parse attributes. */
    449         while (lcur_lc(parse) == lc_comma) {
     458        while (lcur_lc(parse) == lc_comma && !parse_is_error(parse)) {
    450459                lskip(parse);
    451460                attr = parse_arg_attr(parse);
     
    468477                lem_print(lcur(parse));
    469478                printf("'.\n");
    470                 exit(1);
     479                parse_note_error(parse);
    471480        }
    472481
     
    486495        list_init(&block->stats);
    487496
    488         while (terminates_block(lcur_lc(parse)) != b_true) {
     497        /* Avoid peeking if there is an error condition. */
     498        if (parse_is_error(parse))
     499                return block;
     500
     501        while (terminates_block(lcur_lc(parse)) != b_true &&
     502            !parse_is_error(parse)) {
     503
    489504                stat = parse_stat(parse);
    490505                list_append(&block->stats, stat);
     
    508523        stree_exps_t *exp_s;
    509524
     525#ifdef DEBUG_PARSE_TRACE
     526        printf("Parse statement.\n");
     527#endif
    510528        switch (lcur_lc(parse)) {
    511529        case lc_var:
     
    590608        stree_if_t *if_s;
    591609
     610#ifdef DEBUG_PARSE_TRACE
     611        printf("Parse 'if' statement.\n");
     612#endif
    592613        if_s = stree_if_new();
    593614
     
    613634        stree_while_t *while_s;
    614635
     636#ifdef DEBUG_PARSE_TRACE
     637        printf("Parse 'while' statement.\n");
     638#endif
    615639        while_s = stree_while_new();
    616640
     
    629653        stree_for_t *for_s;
    630654
     655#ifdef DEBUG_PARSE_TRACE
     656        printf("Parse 'for' statement.\n");
     657#endif
    631658        for_s = stree_for_new();
    632659
     
    649676        stree_raise_t *raise_s;
    650677
     678#ifdef DEBUG_PARSE_TRACE
     679        printf("Parse 'raise' statement.\n");
     680#endif
    651681        raise_s = stree_raise_new();
    652682        lmatch(parse, lc_raise);
     
    662692        stree_return_t *return_s;
    663693
     694#ifdef DEBUG_PARSE_TRACE
     695        printf("Parse 'return' statement.\n");
     696#endif
    664697        return_s = stree_return_new();
    665698
     
    677710        stree_except_t *except_c;
    678711
     712#ifdef DEBUG_PARSE_TRACE
     713        printf("Parse WEF statement.\n");
     714#endif
    679715        wef_s = stree_wef_new();
    680716        list_init(&wef_s->except_clauses);
     
    692728        wef_s->with_block = parse_block(parse);
    693729
    694         while (lcur_lc(parse) == lc_except) {
     730        while (lcur_lc(parse) == lc_except && !parse_is_error(parse)) {
    695731                except_c = parse_except(parse);
    696732                list_append(&wef_s->except_clauses, except_c);
     
    716752        stree_exps_t *exps;
    717753
     754#ifdef DEBUG_PARSE_TRACE
     755        printf("Parse expression statement.\n");
     756#endif
    718757        expr = parse_expr(parse);
    719758        lmatch(parse, lc_scolon);
     
    730769        stree_except_t *except_c;
    731770
     771#ifdef DEBUG_PARSE_TRACE
     772        printf("Parse 'except' statement.\n");
     773#endif
    732774        except_c = stree_except_new();
    733775
     
    748790        stree_ident_t *ident;
    749791
     792#ifdef DEBUG_PARSE_TRACE
     793        printf("Parse identifier.\n");
     794#endif
    750795        lcheck(parse, lc_ident);
    751796        ident = stree_ident_new();
     
    756801}
    757802
     803/** Signal a parse error, start bailing out from parser. */
     804void parse_raise_error(parse_t *parse)
     805{
     806        parse->error = b_true;
     807        parse->error_bailout = b_true;
     808}
     809
     810/** Note a parse error that has been immediately recovered. */
     811void parse_note_error(parse_t *parse)
     812{
     813        parse->error = b_true;
     814}
     815
     816/** Check if we are currently bailing out of parser due to a parse error. */
     817bool_t parse_is_error(parse_t *parse)
     818{
     819        return parse->error_bailout;
     820}
     821
     822/** Recover from parse error bailout.
     823 *
     824 * Still remember that there was an error, but stop bailing out.
     825 */
     826void parse_recover_error(parse_t *parse)
     827{
     828        assert(parse->error == b_true);
     829        assert(parse->error_bailout == b_true);
     830
     831        parse->error_bailout = b_false;
     832}
     833
    758834/** Return current lem. */
    759835lem_t *lcur(parse_t *parse)
    760836{
     837#ifdef DEBUG_LPARSE_TRACE
     838        printf("lcur()\n");
     839#endif
    761840        return lex_get_current(parse->lex);
    762841}
     
    767846        lem_t *lem;
    768847
     848        /*
     849         * This allows us to skip error checking in many places. If there is an
     850         * active error, lcur_lc() returns lc_invalid without reading input.
     851         *
     852         * Without this measure we would have to check for error all the time
     853         * or risk requiring extra input from the user (in interactive mode)
     854         * before actually bailing out from the parser.
     855         */
     856        if (parse_is_error(parse))
     857                return lc_invalid;
     858
    769859        lem = lcur(parse);
    770860        return lem->lclass;
     
    774864void lskip(parse_t *parse)
    775865{
     866#ifdef DEBUG_LPARSE_TRACE
     867        printf("lskip()\n");
     868#endif
    776869        lex_next(parse->lex);
    777870}
     
    780873void lcheck(parse_t *parse, lclass_t lc)
    781874{
     875#ifdef DEBUG_LPARSE_TRACE
     876        printf("lcheck(");
     877        lclass_print(lc);
     878        printf(")\n");
     879#endif
    782880        if (lcur(parse)->lclass != lc) {
    783881                lem_print_coords(lcur(parse));
     
    785883                printf("', got '"); lem_print(lcur(parse));
    786884                printf("'.\n");
    787                 exit(1);
     885                parse_raise_error(parse);
    788886        }
    789887}
     
    792890void lmatch(parse_t *parse, lclass_t lc)
    793891{
     892#ifdef DEBUG_LPARSE_TRACE
     893        printf("lmatch(");
     894        lclass_print(lc);
     895        printf(")\n");
     896#endif
     897        /*
     898         * This allows us to skip error checking in many places. If there is an
     899         * active error, lmatch() does nothing (similar to parse_block(), etc.
     900         *
     901         * Without this measure we would have to check for error all the time
     902         * or risk requiring extra input from the user (in interactive mode)
     903         * before actually bailing out from the parser.
     904         */
     905        if (parse_is_error(parse))
     906                return;
     907
    794908        lcheck(parse, lc);
    795909        lskip(parse);
     
    803917        lem_print(lcur(parse));
    804918        printf("'.\n");
    805         exit(1);
     919        parse_raise_error(parse);
    806920}
    807921
Note: See TracChangeset for help on using the changeset viewer.