-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLexer.l
131 lines (97 loc) · 4.09 KB
/
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
129
130
131
%{
/*
* Lexer.l file
* To generate the lexical analyzer run: "flex Lexer.l"
*/
#include "Parser.h"
#include "astexpr.h"
#include <stdio.h>
#include <iostream>
#include <string>
#define SAVE_TOKEN (yylval->str = new std::string(yytext, yyleng));
#define TOKEN(t) (yylval.token = t)
#pragma clang diagnostic push
// Ignore about 20 "register storage class specifier is deprecated" warnings from flex code
#pragma clang diagnostic ignored "-Wdeprecated-register"
%}
%option outfile="Lexer.cpp" header-file="Lexer.h"
%option warn nodefault
%option reentrant noyywrap never-interactive nounistd
%option bison-bridge
IDNT_START [a-zA-Z_]
IDNT_CONT [a-zA-Z_0-9]
IDNT {IDNT_START}{IDNT_CONT}+
%x comment
%x str_single_quote
%x str_double_quote
%x str_dot
%%
std::string *string_buf;
"/*" BEGIN(comment);
<comment>{
[^*]* /* eat anything that's not a '*' */
"*"+[^*/]* /* eat up '*'s not followed by '/'s */
"*"+"/" BEGIN(INITIAL);
}
"<-" { printf("return LMAP;\n"); return LMAP; }
"->" { printf("return RMAP;\n"); return RMAP; }
"<<" { printf("return LREDUCE;\n"); return LREDUCE; }
">>" { printf("return RREDUCE;\n"); return RREDUCE; }
"<" { printf("return LAPPLY;\n"); return LAPPLY; }
">" { printf("return RAPPLY;\n"); return RAPPLY; }
"<=" { printf("return LASSIGN;\n"); return LASSIGN; }
"=>" { printf("return RASSIGN;\n"); return RASSIGN; }
"=" { printf("return ASSIGN;\n"); return ASSIGN; }
"(" { printf("return LPAREN;\n"); return LPAREN; }
")" { printf("return RPAREN;\n"); return RPAREN; }
"[" { printf("return LBRACKET;\n"); return LBRACKET; }
"]" { printf("return RBRACKET;\n"); return RBRACKET; }
"{" { printf("return LBRACE;\n"); return LBRACE; }
"}" { printf("return RBRACE;\n"); return RBRACE; }
"#" { printf("return DIRECTIVE;\n"); return DIRECTIVE; }
"==" { printf("return SAME;\n"); return SAME; }
[\r\n,] { printf("return BREAK;\n"); return BREAK; }
[ \t]* { printf("Skipping blanks: '%s'\n", yytext); }
[0-9]+ { printf("return NUMBER; // %s\n", yytext); SAVE_TOKEN; return NUMBER; }
"-"{IDNT} { printf("return PRIVATE_IDENT; // %s\n", yytext); SAVE_TOKEN; return PRIVATE_IDENT; }
"+"{IDNT} { printf("return PUBLIC_IDENT; // %s\n", yytext); SAVE_TOKEN; return PUBLIC_IDENT; }
"."{IDNT} { printf("return UNBOUND_IDENT; // %s\n", yytext); SAVE_TOKEN; return UNBOUND_IDENT; }
{IDNT} { printf("return IDENTIFIER; // %s\n", yytext); SAVE_TOKEN; return IDENTIFIER; }
\' { string_buf = new std::string(); BEGIN(str_single_quote); }
\" { string_buf = new std::string(); BEGIN(str_double_quote); }
\. { string_buf = new std::string(); BEGIN(str_dot); }
<str_single_quote,str_double_quote,str_dot>{
\\[0-7]{1,3} {
/* octal escape sequence */
unsigned int result;
sscanf( yytext + 1, "%o", &result );
if ( result > 0xff )
{
/* error, constant is out-of-bounds */
}
string_buf->append(1, result);
}
\\[0-9]+ {
/* generate error - bad escape sequence; something
* like '\48' or '\0777777'
*/
}
\\n { string_buf->append(1, '\n'); }
\\t { string_buf->append(1, '\t'); }
\\r { string_buf->append(1, '\r'); }
\\b { string_buf->append(1, '\b'); }
\\f { string_buf->append(1, '\f'); }
\\(.|\n) { string_buf->append(1, yytext[1]); }
}
<str_single_quote>[^\\\']+ { string_buf->append(yytext); }
<str_double_quote>[^\\\"]+ { string_buf->append(yytext); }
<str_dot>[a-zA-Z_0-9]+ { string_buf->append(yytext); }
<str_single_quote>\' { yylval->str = string_buf; BEGIN(INITIAL); return STRING; }
<str_double_quote>\" { yylval->str = string_buf; BEGIN(INITIAL); return STRING; }
<str_dot>[^\\a-zA-Z_0-9] { yylval->str = string_buf; BEGIN(INITIAL); return STRING; }
. { printf("Did not recognize: '%s'\n", yytext); }
%%
#pragma clang diagnostic pop
int yyerror(const char *msg) {
fprintf(stderr,"Error:%s\n",msg); return 0;
}