0
|
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;
|
|
67
|
|
68 "return" return token::TK_RETURN;
|
|
69
|
|
70 \\\n yylloc->lines();
|
|
71
|
|
72 [-+*/=%&|(){}<>\[\],:;&] return yy::script_parser::token_type(yytext[0]);
|
|
73
|
|
74 "&&" return token::TK_LOGAND;
|
|
75 "||" return token::TK_LOGOR;
|
|
76 "==" return token::TK_EQ;
|
|
77 "!=" return token::TK_NE;
|
|
78 ">=" return token::TK_GE;
|
|
79 "<=" return token::TK_LE;
|
|
80 "<<" return token::TK_LSHIFT;
|
|
81 ">>" return token::TK_RSHIFT;
|
|
82
|
|
83 "+=" return token::TK_ADD_ASSIGN;
|
|
84 "-=" return token::TK_SUB_ASSIGN;
|
|
85 "*=" return token::TK_MUL_ASSIGN;
|
|
86 "/=" return token::TK_DIV_ASSIGN;
|
|
87 "%=" return token::TK_MOD_ASSIGN;
|
|
88
|
|
89 {blank}+ yylloc->step();
|
|
90 \" {
|
|
91 yylloc->step();
|
|
92 string_buffer.clear();
|
|
93 BEGIN(STRING);
|
|
94 }
|
|
95 {int} {
|
|
96 errno = 0;
|
|
97 long n = strtol(yytext, NULL, 10);
|
|
98 if (n < LONG_MIN || n > LONG_MAX || errno == ERANGE)
|
|
99 driver.error(*yylloc, "整数が範囲外です。");
|
|
100 yylval->ival = n;
|
|
101 return token::TK_IVAL;
|
|
102 }
|
|
103 "0" {
|
|
104 yylval->ival = 0;
|
|
105 return token::TK_IVAL;
|
|
106 }
|
|
107 {id} {
|
|
108 yylval->sval = new std::string(yytext);
|
|
109 return token::TK_IDENTIFIER;
|
|
110 }
|
|
111 . driver.error(*yylloc, "この文字を識別子で使用することはできません。");
|
|
112 }
|
|
113 <STRING>{
|
|
114 \n {
|
|
115 yylloc->lines();
|
|
116 driver.error(*yylloc, "文字列がとじられていません");
|
|
117 string_buffer.clear();
|
|
118 BEGIN(INITIAL);
|
|
119 }
|
|
120 <<EOF>> {
|
|
121 driver.error(*yylloc, "文字列の途中でファイルが終了しました");
|
|
122 string_buffer.clear();
|
|
123 BEGIN(INITIAL);
|
|
124 }
|
|
125 ([\x81-\x9f\xe0-\xef][\x40-\x7e\x80-\xfc])+ {
|
|
126 string_buffer += yytext;
|
|
127 }
|
|
128 [^\\\n"]+ { string_buffer += yytext; }
|
|
129 \\\n yylloc->lines();
|
|
130 \\[^\n] {
|
|
131 switch (yytext[yyleng-1]) {
|
|
132 case 'n':
|
|
133 string_buffer += '\n';
|
|
134 break;
|
|
135
|
|
136 default:
|
|
137 string_buffer += yytext[yyleng-1];
|
|
138 break;
|
|
139 }
|
|
140 }
|
|
141 \" {
|
|
142 BEGIN(INITIAL);
|
|
143 yylval->sval = new std::string(string_buffer);
|
|
144 return token::TK_SVAL;
|
|
145 }
|
|
146 }
|
|
147 <CPP_COMMENT>{
|
|
148 [^\n]*
|
|
149 \n {
|
|
150 yylloc->lines();
|
|
151 yylloc->step();
|
|
152 BEGIN(INITIAL);
|
|
153 }
|
|
154 }
|
|
155 <C_COMMENT>{
|
|
156 [^*\n]*
|
|
157 [^*\n]*\n { yylloc->lines(); }
|
|
158 "*"+[^*/\n]* /* 余分な*を探す */
|
|
159 "*"+[^*/\n]*\n { yylloc->lines(); }
|
|
160 <<EOF>> driver.error(*yylloc, "コメントの途中でファイルが終了しました");
|
|
161 "*"+"/" BEGIN(INITIAL);
|
|
162 }
|
|
163 %%
|
|
164
|
|
165 void compiler::scan_begin()
|
|
166 {
|
|
167 if ((yyin = fopen(file.c_str(), "r")) == 0)
|
|
168 error(file + " がオープンできません。");
|
|
169 }
|
|
170
|
|
171 void compiler::scan_end()
|
|
172 {
|
|
173 fclose(yyin);
|
|
174 yylex_destroy();
|
|
175 }
|