source: dev/BasicCompiler_Common/LexicalAnalysis.cpp@ 14

Last change on this file since 14 was 14, checked in by dai_9181, 17 years ago

LexicalAnalysisのベース部分を用意。

File size: 4.8 KB
Line 
1#include "common.h"
2
3char *basbuf;
4
5extern CDefine *pobj_define;
6
7
8CSource CSource::obj;
9
10CToken::CToken(int pos, int length, TOKENTYPE type, int extended){
11 this->pos = pos;
12 this->length = length;
13 this->type = type;
14 this->extended = extended;
15}
16CToken::~CToken(){
17}
18
19
20
21CSource::CSource(){
22}
23CSource::~CSource(){
24 Free();
25}
26
27void CSource::Free(){
28 if(SourceCode){
29 char *base = SourceCode-2;
30 free(base);
31 SourceCode = 0;
32 }
33
34 if(ppTokens){
35 for(int i=0; i<TokenNum; i++){
36 delete ppTokens[i];
37 }
38 free(ppTokens);
39 ppTokens = 0;
40 }
41}
42
43void CSource::Init(){
44
45 //古い情報を開放
46 Free();
47
48 ppTokens = (CToken **)malloc(1);
49 TokenNum = 0;
50}
51
52
53bool CSource::OpenFile(char *FileName){
54 char *buffer;
55 DWORD dwFileSize,dwAccBytes;
56 HANDLE hFile;
57
58 //ファイルオープン
59 hFile=CreateFile(FileName,GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
60 if(hFile==INVALID_HANDLE_VALUE) return false;
61
62 //バッファ領域確保
63 dwFileSize=GetFileSize(hFile,0);
64 buffer=(char *)malloc(dwFileSize+1);
65
66 //読み込み
67 ReadFile(hFile,buffer,dwFileSize,&dwAccBytes,0);
68 buffer[dwAccBytes]=0;
69
70 SetSourceCode(buffer);
71
72 free(buffer);
73
74 return true;
75}
76
77void CSource::SetSourceCode(char *source){
78
79 //初期化
80 Init();
81
82 //#define情報を初期化
83 pobj_define=new CDefine;
84
85 //バッファ領域確保
86 char *base,*buffer;
87 base=(char *)malloc(lstrlen(source)*2+255);
88 base[0]='\n';
89 base[1]='\n';
90 buffer=base+2;
91 lstrcpy(buffer,"#include <basic.sbp>\n");
92 buffer+=lstrlen(buffer);
93
94 //読み込み
95 lstrcpy(buffer,source);
96
97 //CRLFをLFに変換
98 ChangeReturnCode(buffer);
99
100 //コメント削除
101 DeleteComment(buffer);
102
103 //#ifdefディレクティブ
104 DirectiveIfdef(buffer);
105
106 //最終行には文字を含ませないようにする
107 lstrcat(buffer,"\n");
108
109 //インクルードファイルを読み込む
110 base=IncludeFiles(base);
111 buffer = base + 2;
112
113 //#define情報を破棄
114 delete pobj_define;
115 pobj_define=0;
116
117 SourceCode = buffer;
118}
119
120void CSource::AddSourceCode(char *source){
121 char *temp;
122 temp=(char *)malloc(lstrlen(source)+8192);
123 lstrcpy(temp,source);
124
125 //エスケープシーケンス設定
126 SetEscapeSequenceFormat(temp);
127
128 //コマンド対応
129 ChangeCommandToCode(temp);
130
131 //新しいソースコードバッファの容量
132 extern char *basbuf;
133 int NewSize;
134 NewSize=lstrlen(SourceCode)+lstrlen(temp);
135 NewSize*=2;
136 NewSize+=255;
137
138 //最後尾に貼り付け
139 char *base;
140 base = SourceCode - 2;
141 base = (char *)realloc(base, NewSize);
142 SourceCode = base + 2;
143 int oldlength = lstrlen(SourceCode);
144 lstrcat(SourceCode, temp);
145
146 free(temp);
147
148 //字句解析
149 CSource::obj.LexicalAnalysis(0);
150}
151
152
153//トークンを追加
154void CSource::AddToken(int pos, int length, TOKENTYPE type, int extended){
155 CToken *ptoken = new CToken(pos, length, type, extended);
156
157 ppTokens = (CToken **)realloc(ppTokens, (TokenNum + 1) * sizeof(CToken *));
158 ppTokens[TokenNum] = ptoken;
159 TokenNum++;
160}
161
162//字句解析(トークンを生成)
163void CSource::LexicalAnalysis(int StartPos){
164 int i = StartPos;
165 int i2;
166
167 try{
168
169 while(true){
170 if(SourceCode[i] == '\0') break;
171
172 //文字数
173 int length;
174
175 //トークンの種類
176 TOKENTYPE type;
177
178 //付加情報
179 int extended = 0;
180
181 if(IsNumCalcMark(SourceCode, i)){
182 //演算子
183 type = TOKEN_OPERATOR;
184
185 extended = GetCalcId(SourceCode + i, &i2);
186
187 length = i2 + 1;
188 }
189 else if(SourceCode[i] == 1){
190 //特殊字句
191 type = TOKEN_ESCAPESEQUENCE;
192
193 length = 2;
194 }
195 else if(IsNumberTopChar(SourceCode + i)){
196 //数値
197 type = TOKEN_NUMBER;
198
199 if(SourceCode[i] == '&') length = 2;
200 else length = 0;
201 for(length=0; IsNumberChar(SourceCode[i+length]); length++){
202 }
203 }
204 else if(SourceCode[i] == '\"'){
205 //文字列
206 type = TOKEN_STRING;
207
208 for(length=1;;length++){
209 if(SourceCode[i + length]=='\0') break;
210 if(SourceCode[i + length] == '\"'){
211 length++;
212 break;
213 }
214 }
215 }
216 else if(memicmp(SourceCode+i,"Ex",2) && SourceCode[i+3]=='\"'){
217 //拡張文字列
218 type = TOKEN_EXSTRING;
219
220 for(length=3;;length++){
221 if(SourceCode[i + length]=='\0') break;
222 if(SourceCode[i + length] == '\"'){
223 length++;
224 break;
225 }
226 }
227 }
228 else if(IsVariableTopChar(SourceCode[i])){
229 //識別子
230 type = TOKEN_IDENTIFIER;
231
232 for(length=0; IsVariableChar(SourceCode[i+length]); length++){
233 }
234 }
235 else if(SourceCode[i] == 0x10 || SourceCode[i] == 0x11){
236 //コマンド
237 type = TOKEN_COMMAND;
238 length = 2;
239 }
240 else{
241 throw "字句解析に失敗\n";
242 }
243
244 if(length == 0){
245 throw "字句解析に失敗\n";
246 }
247
248 //トークンを追加
249 AddToken(i, length, type, extended);
250
251 //次の字句の位置へ
252 i += length;
253
254 //空白を除去
255 while(IsBlank(SourceCode[i])) i++;
256 }
257
258 }
259 catch(const char *msg){
260 OutputDebugString(msg);
261 }
262}
Note: See TracBrowser for help on using the repository browser.