-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathminic_lexer.l
128 lines (110 loc) · 3.31 KB
/
minic_lexer.l
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
127
128
/* C Language Compiler Lexer Created by Vincent Lin (https://github.com/vincnttt/) on 2021.06.11 */
%{
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include "y.tab.h"
extern int err_count;
void comment();
%}
%option yylineno
L [a-zA-Z]
D [0-9]
%%
/* Preprocessor */
"#include <stdio.h>" { /* Ignore Preprocessor */ }
"#include <stdlib.h>" { /* Ignore Preprocessor */ }
/* Data types */
"void" { return VOID; }
"int" { return INT; }
"short" { return SHORT; }
"long" { return LONG; }
"long long" { return LLONG; }
"char" { return CHAR; }
"float" { return FLOAT; }
"double" { return DOUBLE; }
"signed" { return SIGNED; }
"unsigned" { return UNSIGNED; }
/* Statements*/
"if" { return IF; }
"else" { return ELSE; }
"for" { return FOR; }
"while" { return WHILE; }
"switch" { return SWITCH; }
"case" { return CASE; }
"default" { return DEFAULT; }
"break" { return BREAK; }
"continue" { return CONTINUE; }
"return" { return RETURN; }
/* Functions */
"printf" { return PRINTF; }
"scanf" { return SCANF; }
/* Constants */
'({L}|{D})' { return CHAR_CONST; }
[+\-]?{D}+[lLuU]? { return DEC_CONST; }
[+\-]?{D}*\.{D}+ { return FLOAT_CONST; }
(_|{L})({L}|{D}|_){0,31} { return IDENTIFIER; }
\"[^\"\n]*\" {
return STRING;
}
/* Operators */
"+" { return '+'; }
"-" { return '-'; }
"*" { return '*'; }
"/" { return '/'; }
"%" { return '%'; }
"^" { return '^'; }
"=" { return '='; }
"<" { return '<'; }
">" { return '>'; }
"++" { return INCR; }
"--" { return DECR; }
"+=" { return ADD_ASSIGN; }
"-=" { return SUB_ASSIGN; }
"*=" { return MUL_ASSIGN; }
"/=" { return DIV_ASSIGN; }
"%=" { return MOD_ASSIGN; }
"^=" { return XOR_ASSIGN; }
"&&" { return LOGIC_AND; }
"||" { return LOGIC_OR; }
"==" { return EQ; }
"<=" { return LS_EQ; }
">=" { return GR_EQ; }
"!=" { return NOT_EQ; }
/* Symbols */
"{" { return '{'; }
"}" { return '}'; }
"(" { return '('; }
")" { return ')'; }
"[" { return '['; }
"]" { return ']'; }
"," { return ','; }
";" { return ';'; }
/* Unexpected and Illegal characters */
\"[^\"\n]*$ {
printf("[ERROR]: unterminated string %s, in line %d\n", yytext, yylineno); ++err_count;
}
{D}+({L}|_)+ { printf("[ERROR]: illegal identifier name '%s', in line %d\n", yytext, yylineno); ++err_count; }
\n { /* Ignore newline */ }
/* Whitespaces and Comments */
"//"[^\n]* { /* Discard comments. */ }
[ \t\r\f\v]+ { /* Ignore whitespace */ }
"/*" { comment(); }
\n { yylineno++; }
. { return yytext[0]; }
%%
#define INPUT_EOF 0
void comment(void) {
/* Consume characters up to the closing comment marker. */
char c, prev = 0;
while ((c = input()) != INPUT_EOF) {
if (c == '/' && prev == '*')
return;
prev = c;
}
printf("[ERROR]: unexpected comment in line %d\n", yylineno);
++err_count;
}
int yywrap() {
return 1;
}