aboutsummaryrefslogtreecommitdiff
path: root/cibic.l
blob: 84b3239bcaf7ea25f624caa35e2a60df3e4a450e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
%{
#include "cibic.tab.h"
int yycolumn = 1;
#define YY_USER_ACTION \
    yylloc.first_line = yylloc.last_line = yylineno; \
    yylloc.first_column = yycolumn; yylloc.last_column = yycolumn + yyleng - 1; \
    yycolumn += yyleng;

%}

letter [a-zA-Z_$]
digit [0-9]
string ((\\.|[^\n\"\\])*)
char ([^'\\]|\\.|\\[0-7]+|\\[xX][0-9a-fA-F]+)

%s IN_BLOCK_COMMENT IN_INLINE_COMMENT IN_DIRECTIVE
%option yylineno
%%


<INITIAL>{
"/*"    BEGIN(IN_BLOCK_COMMENT);
}
<IN_BLOCK_COMMENT>{
"*/"    BEGIN(INITIAL);
[^*\n]+   // eat comment in chunks
"*"       // eat the lone star
\n      { yycolumn = 1; }
}

<INITIAL>{
"//"    BEGIN(IN_INLINE_COMMENT);
}
<IN_INLINE_COMMENT>{
\n      { yycolumn = 1; BEGIN(INITIAL); }
[^\n]+ 
}

<INITIAL>{
"#"    BEGIN(IN_DIRECTIVE);
}
<IN_DIRECTIVE>{
\n      { yycolumn = 1; BEGIN(INITIAL); }
[^\n]+ 
}

"void"                                      { return KW_VOID; }
"char"                                      { return KW_CHAR; }
"int"                                       { return KW_INT; }
"struct"                                    { return KW_STRUCT; }
"union"                                     { return KW_UNION; }
"if"                                        { return KW_IF; }
"else"                                      { return KW_ELSE; }
"while"                                     { return KW_WHILE; }
"for"                                       { return KW_FOR; }
"continue"                                  { return KW_CONT; }
"break"                                     { return KW_BREAK; }
"return"                                    { return KW_RET; }
"sizeof"                                    { return KW_SIZEOF; }

{letter}({letter}|{digit})*                 { 
    yylval.strval = strdup(yytext); 
    return IDENTIFIER; 
}

({digit}+)|(0[xX][0-9a-fA-F]+)              { 
    if (*yytext == '0')
    {
        if (*(yytext + 1) == 'x' || *(yytext + 1) == 'X')
            sscanf(yytext, "%x", &yylval.intval);
        else    // FIXME: error report if it is not a valid octal
            sscanf(yytext, "%o", &yylval.intval);
    }
    else yylval.intval = atoi(yytext);
    return INT_CONST; 
}

'{char}' { 
    yylval.strval = strdup(yytext);
    return CHAR_CONST; 
}

'{char} {
    yyerror("missing terminating ' character\n");
    exit(1);
}

\"{string}\" {
    yylval.strval = strndup(yytext + 1, strlen(yytext) - 2);
    return STR_CONST; 
}

\"{string} {
    yyerror("missing terminating \" character\n");
    exit(1);
}

"||"                                        { return OPT_OR; }
"&&"                                        { return OPT_AND; }
"=="                                        { return OPT_EQ; }
"!="                                        { return OPT_NE; }
"<="                                        { return OPT_LE; }
">="                                        { return OPT_GE; }
"<<"                                        { return OPT_SHL; }
">>"                                        { return OPT_SHR; }
"++"                                        { return OPT_INC; }
"--"                                        { return OPT_DEC; }
"->"                                        { return OPT_PTR; }

"*="                                        { return ASS_MUL; }
"/="                                        { return ASS_DIV; }
"%="                                        { return ASS_MOD; }
"+="                                        { return ASS_ADD; }
"-="                                        { return ASS_SUB; }
"<<="                                       { return ASS_SHL; }
">>="                                       { return ASS_SHR; }
"&="                                        { return ASS_AND; }
"^="                                        { return ASS_XOR; }
"|="                                        { return ASS_OR; }

[();,={}\[\]*|\^&<>+\-*//%~!.]              { return *yytext; }

[ \t\r]                                   /* skip whitespaces */
\n                                          { yycolumn = 1; }
.                                           { return UNKNOWN; }
%%