4
|
1 %{
|
|
2 #include <cstdlib>
|
|
3 #include <cerrno>
|
|
4 #include <climits>
|
|
5 #include <string>
|
|
6 #include "compiler.h"
|
|
7 #include "script-parser.hh"
|
|
8
|
|
9 #ifdef _MSC_VER
|
|
10 #pragma warning(disable:4018)
|
|
11 #pragma warning(disable:4102)
|
|
12 #pragma warning(disable:4244)
|
|
13 #pragma warning(disable:4267)
|
|
14 #endif
|
|
15
|
|
16 #undef yywrap
|
|
17 #define yywrap() 1
|
|
18
|
|
19 #define yyterminate() return token::END_OF_FILE
|
|
20 %}
|
|
21
|
|
22 %option noyywrap nounput batch
|
|
23 %option never-interactive
|
|
24 %option noyy_scan_buffer
|
|
25 %option noyy_scan_bytes
|
|
26 %option noyy_scan_string
|
|
27 %option 8bit
|
|
28 %option nounistd
|
|
29
|
|
30 id [a-zA-Z_][a-zA-Z_0-9]*
|
|
31 int [1-9][0-9]*
|
|
32 blank [ \t]
|
|
33
|
|
34 %x C_COMMENT
|
|
35 %x CPP_COMMENT
|
|
36 %x STRING
|
|
37
|
|
38 %{
|
|
39 #define YY_USER_ACTION yylloc->columns(yyleng);
|
|
40 %}
|
|
41 %%
|
|
42 %{
|
|
43 typedef yy::script_parser::token token;
|
|
44
|
|
45 yylloc->step();
|
|
46
|
|
47 std::string string_buffer;
|
|
48 %}
|
|
49 <INITIAL>{
|
|
50 \n { yylloc->lines(); }
|
|
51 "^#" { yylloc->step(); BEGIN(CPP_COMMENT); }
|
|
52 "//" { yylloc->step(); BEGIN(CPP_COMMENT); }
|
|
53 "/*" { yylloc->step(); BEGIN(C_COMMENT); }
|
|
54
|
|
55 "if" return token::TK_IF;
|
|
56 "else" return token::TK_ELSE;
|
|
57 "for" return token::TK_FOR;
|
|
58 "while" return token::TK_WHILE;
|
|
59 "switch" return token::TK_SWITCH;
|
|
60 "case" return token::TK_CASE;
|
|
61 "default" return token::TK_DEFAULT;
|
|
62 "break" return token::TK_BREAK;
|
|
63
|
|
64 "string" return token::TK_STRING;
|
|
65 "int" return token::TK_INTEGER;
|
|
66 "void" return token::TK_VOID;
|
5
|
67 "__code" return token::TK_CODE;
|
4
|
68
|
|
69 "return" return token::TK_RETURN;
|
|
70
|
|
71 \\\n yylloc->lines();
|
|
72
|
|
73 [-+*/=%&|(){}<>\[\],:;&] return yy::script_parser::token_type(yytext[0]);
|
|
74
|
|
75 "&&" return token::TK_LOGAND;
|
|
76 "||" return token::TK_LOGOR;
|
|
77 "==" return token::TK_EQ;
|
|
78 "!=" return token::TK_NE;
|
|
79 ">=" return token::TK_GE;
|
|
80 "<=" return token::TK_LE;
|
|
81 "<<" return token::TK_LSHIFT;
|
|
82 ">>" return token::TK_RSHIFT;
|
|
83
|
|
84 "+=" return token::TK_ADD_ASSIGN;
|
|
85 "-=" return token::TK_SUB_ASSIGN;
|
|
86 "*=" return token::TK_MUL_ASSIGN;
|
|
87 "/=" return token::TK_DIV_ASSIGN;
|
|
88 "%=" return token::TK_MOD_ASSIGN;
|
|
89
|
|
90 {blank}+ yylloc->step();
|
|
91 \" {
|
|
92 yylloc->step();
|
|
93 string_buffer.clear();
|
|
94 BEGIN(STRING);
|
|
95 }
|
|
96 {int} {
|
|
97 errno = 0;
|
|
98 long n = strtol(yytext, NULL, 10);
|
|
99 if (n < LONG_MIN || n > LONG_MAX || errno == ERANGE)
|
5
|
100 driver.error(*yylloc, "整数が範囲外です。");
|
4
|
101 yylval->ival = n;
|
|
102 return token::TK_IVAL;
|
|
103 }
|
|
104 "0" {
|
|
105 yylval->ival = 0;
|
|
106 return token::TK_IVAL;
|
|
107 }
|
|
108 {id} {
|
|
109 yylval->sval = new std::string(yytext);
|
|
110 return token::TK_IDENTIFIER;
|
|
111 }
|
5
|
112 . driver.error(*yylloc, "この文字を識別子で使用することはできません。");
|
4
|
113 }
|
|
114 <STRING>{
|
|
115 \n {
|
|
116 yylloc->lines();
|
5
|
117 driver.error(*yylloc, "文字列がとじられていません");
|
4
|
118 string_buffer.clear();
|
|
119 BEGIN(INITIAL);
|
|
120 }
|
|
121 <<EOF>> {
|
5
|
122 driver.error(*yylloc, "文字列の途中でファイルが終了しました");
|
4
|
123 string_buffer.clear();
|
|
124 BEGIN(INITIAL);
|
|
125 }
|
|
126 ([\x81-\x9f\xe0-\xef][\x40-\x7e\x80-\xfc])+ {
|
|
127 string_buffer += yytext;
|
|
128 }
|
|
129 [^\\\n"]+ { string_buffer += yytext; }
|
|
130 \\\n yylloc->lines();
|
|
131 \\[^\n] {
|
|
132 switch (yytext[yyleng-1]) {
|
|
133 case 'n':
|
|
134 string_buffer += '\n';
|
|
135 break;
|
|
136
|
|
137 default:
|
|
138 string_buffer += yytext[yyleng-1];
|
|
139 break;
|
|
140 }
|
|
141 }
|
|
142 \" {
|
|
143 BEGIN(INITIAL);
|
|
144 yylval->sval = new std::string(string_buffer);
|
|
145 return token::TK_SVAL;
|
|
146 }
|
|
147 }
|
|
148 <CPP_COMMENT>{
|
|
149 [^\n]*
|
|
150 \n {
|
|
151 yylloc->lines();
|
|
152 yylloc->step();
|
|
153 BEGIN(INITIAL);
|
|
154 }
|
|
155 }
|
|
156 <C_COMMENT>{
|
|
157 [^*\n]*
|
|
158 [^*\n]*\n { yylloc->lines(); }
|
5
|
159 "*"+[^*/\n]* /* 余分な*を探す */
|
4
|
160 "*"+[^*/\n]*\n { yylloc->lines(); }
|
5
|
161 <<EOF>> driver.error(*yylloc, "コメントの途中でファイルが終了しました");
|
4
|
162 "*"+"/" BEGIN(INITIAL);
|
|
163 }
|
|
164 %%
|
|
165
|
|
166 void compiler::scan_begin()
|
|
167 {
|
|
168 if ((yyin = fopen(file.c_str(), "r")) == 0)
|
5
|
169 error(file + " がオープンできません。");
|
4
|
170 }
|
|
171
|
|
172 void compiler::scan_end()
|
|
173 {
|
|
174 fclose(yyin);
|
|
175 yylex_destroy();
|
|
176 }
|