~martin-decky/helenos/rcu

« back to all changes in this revision

Viewing changes to uspace/app/sbi/src/lex.c

  • Committer: Martin Sucha
  • Date: 2011-03-22 19:55:06 UTC
  • mfrom: (888 mainline)
  • mto: (720.2.80 ext2-merge)
  • mto: This revision was merged to the branch mainline in revision 1004.
  • Revision ID: sucha14@st.fmph.uniba.sk-20110322195506-65nyzi3633naacrp
MergeĀ mainlineĀ changes

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * Copyright (c) 2010 Jiri Svoboda
 
2
 * Copyright (c) 2011 Jiri Svoboda
3
3
 * All rights reserved.
4
4
 *
5
5
 * Redistribution and use in source and binary forms, with or without
44
44
 
45
45
#define TAB_WIDTH 8
46
46
 
 
47
typedef enum {
 
48
        cs_chr,
 
49
        cs_str
 
50
} chr_str_t;
 
51
 
47
52
static void lex_touch(lex_t *lex);
48
53
static bool_t lex_read_try(lex_t *lex);
49
54
 
56
61
static void lex_char(lex_t *lex);
57
62
static void lex_number(lex_t *lex);
58
63
static void lex_string(lex_t *lex);
 
64
static void lex_char_string_core(lex_t *lex, chr_str_t cs);
59
65
static int digit_value(char c);
60
66
 
61
67
/* Note: This imposes an implementation limit on identifier length. */
116
122
        { lc_static,    "static" },
117
123
        { lc_string,    "string" },
118
124
        { lc_struct,    "struct" },
 
125
        { lc_switch,    "switch" },
119
126
        { lc_then,      "then" },
120
127
        { lc_this,      "this" },
121
128
        { lc_true,      "true" },
122
129
        { lc_var,       "var" },
123
130
        { lc_with,      "with" },
 
131
        { lc_when,      "when" },
124
132
        { lc_while,     "while" },
125
133
        { lc_yield,     "yield" },
126
134
 
534
542
 */
535
543
static void lex_char(lex_t *lex)
536
544
{
537
 
        char *bp;
538
 
        int idx;
539
545
        size_t len;
540
546
        int char_val;
541
547
 
542
 
        bp = lex->ibp + 1;
543
 
        idx = 0;
544
 
 
545
 
        while (bp[idx] != '\'') {
546
 
                if (idx >= SLBUF_SIZE) {
547
 
                        printf("Error: Character literal too long.\n");
548
 
                        exit(1);
549
 
                }
550
 
 
551
 
                if (bp[idx] == '\0') {
552
 
                        printf("Error: Unterminated character literal.\n");
553
 
                        exit(1);
554
 
                }
555
 
 
556
 
                strlit_buf[idx] = bp[idx];
557
 
                ++idx;
558
 
        }
559
 
 
560
 
        lex->ibp = bp + idx + 1;
561
 
 
562
 
        strlit_buf[idx] = '\0';
 
548
        lex_char_string_core(lex, cs_chr);
 
549
 
563
550
        len = os_str_length(strlit_buf);
564
551
        if (len != 1) {
565
552
                printf("Character literal should contain one character, "
619
606
 */
620
607
static void lex_string(lex_t *lex)
621
608
{
622
 
        char *bp;
623
 
        int idx;
624
 
 
625
 
        bp = lex->ibp + 1;
626
 
        idx = 0;
627
 
 
628
 
        while (bp[idx] != '"') {
629
 
                if (idx >= SLBUF_SIZE) {
630
 
                        printf("Error: String literal too long.\n");
631
 
                        exit(1);
632
 
                }
633
 
 
634
 
                if (bp[idx] == '\0') {
635
 
                        printf("Error: Unterminated string literal.\n");
636
 
                        exit(1);
637
 
                }
638
 
 
639
 
                strlit_buf[idx] = bp[idx];
640
 
                ++idx;
641
 
        }
642
 
 
643
 
        lex->ibp = bp + idx + 1;
644
 
 
645
 
        strlit_buf[idx] = '\0';
 
609
        lex_char_string_core(lex, cs_str);
646
610
 
647
611
        lex->current.lclass = lc_lit_string;
648
612
        lex->current.u.lit_string.value = os_str_dup(strlit_buf);
649
613
}
650
614
 
 
615
static void lex_char_string_core(lex_t *lex, chr_str_t cs)
 
616
{
 
617
        char *bp;
 
618
        int sidx, didx;
 
619
        char term;
 
620
        const char *descr, *cap_descr;
 
621
        char spchar;
 
622
 
 
623
        /* Make compiler happy */
 
624
        term = '\0';
 
625
        descr = NULL;
 
626
        cap_descr = NULL;
 
627
 
 
628
        switch (cs) {
 
629
        case cs_chr:
 
630
                term = '\'';
 
631
                descr = "character";
 
632
                cap_descr = "Character";
 
633
                break;
 
634
        case cs_str:
 
635
                term = '"';
 
636
                descr = "string";
 
637
                cap_descr = "String";
 
638
                break;
 
639
        }
 
640
 
 
641
        bp = lex->ibp + 1;
 
642
        sidx = didx = 0;
 
643
 
 
644
        while (bp[sidx] != term) {
 
645
                if (didx >= SLBUF_SIZE) {
 
646
                        printf("Error: %s literal too long.\n", cap_descr);
 
647
                        exit(1);
 
648
                }
 
649
 
 
650
                if (bp[sidx] == '\0') {
 
651
                        printf("Error: Unterminated %s literal.\n", descr);
 
652
                        exit(1);
 
653
                }
 
654
 
 
655
                if (bp[sidx] == '\\') {
 
656
                        switch (bp[sidx + 1]) {
 
657
                        case '\\':
 
658
                                spchar = '\\';
 
659
                                break;
 
660
                        case '\'':
 
661
                                spchar = '\'';
 
662
                                break;
 
663
                        case '"':
 
664
                                spchar = '"';
 
665
                                break;
 
666
                        case 'n':
 
667
                                spchar = '\n';
 
668
                                break;
 
669
                        case 't':
 
670
                                spchar = '\t';
 
671
                                break;
 
672
                        default:
 
673
                                printf("Error: Unknown character escape sequence.\n");
 
674
                                exit(1);
 
675
                        }
 
676
 
 
677
                        strlit_buf[didx] = spchar;
 
678
                        ++didx;
 
679
                        sidx += 2;
 
680
                } else {
 
681
                        strlit_buf[didx] = bp[sidx];
 
682
                        ++sidx; ++didx;
 
683
                }
 
684
        }
 
685
 
 
686
        lex->ibp = bp + sidx + 1;
 
687
 
 
688
        strlit_buf[didx] = '\0';
 
689
}
 
690
 
651
691
/** Lex a single-line comment.
652
692
 *
653
693
 * This does not produce any lem. The comment is just skipped.