Develop and Download Open Source Software

Browse Subversion Repository

Contents of /trunk/ec.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 41 - (show annotations) (download) (as text)
Mon Mar 28 13:05:01 2011 UTC (13 years ago) by narata196
File MIME type: text/x-csrc
File size: 5460 byte(s)
配列を関数として認識しないようにした
またデバッグ用出力に引数を表示するようにした
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <stdarg.h>
5 #include <process.h>
6
7 #define DEBUG
8
9 #define MAX_ARGS 64
10 #define MAX_VALUES 256
11 #define MAX_FUNCS 256
12
13 #define MAX_FUNCNAME 64
14 #define MAX_VALUENAME 64
15
16 #define GLOBAL_FUNCID 0
17 #define MAIN_FUNCID 1
18
19 void ERROR(char *put);
20 char *skipspace(char *p);
21 void processing_block(char *code);
22 void processing_block0(char *code);
23
24 char version[] = "1.01";
25
26 char *filedat; // 文字列格納用
27 int cnt0_0; // [ の数
28 int cnt0_1; // ] の数
29 int funcs; // 関数の数
30 int i;
31
32 int arg_values; // 変数の数
33
34 //
35 // 一つの変数
36 // とりあえずMAX_VALUES個確保しておく
37 // データの大きさについては検討が必要
38 //
39 // name 変数名
40 // type 型
41 // value データ
42 // funcid 所属関数 グローバル変数の時は0
43 // flag 存在確認
44 //
45 struct VALUE {
46 char name[MAX_VALUENAME];
47 int type;
48 long value;
49 int funcid;
50 int flag;
51 } alloc_values[MAX_VALUES];
52
53 //
54 // 一つの関数
55 // 引数はMAX_ARGS個までサポート
56 // これそのものはMAX_FUNCS個確保しておく
57 //
58 // id 関数のID
59 // name 関数名
60 // ret 戻り値
61 // args 引数
62 // flag 存在確認
63 //
64 struct FUNCTION {
65 int id;
66 char name[MAX_FUNCNAME];
67 char ret[6];
68 struct VALUE args[MAX_ARGS];
69 int flag;
70 } alloc_funcs[MAX_FUNCS];
71
72 void main (int argc, char *argv[])
73 {
74 int c, v;
75 char infile[256];
76 FILE *ifp;
77 char outfile[256];
78 FILE *ofp;
79
80 // ソフト名、バージョン表示
81 printf("Edison Compiler Ver.%s\n", version);
82
83 // 領域確保
84 // 4096バイト(半角4096文字)まで読み込み可能
85 filedat = (char *)malloc(4096);
86
87 // ************************************
88 // ********* ファイル関連処理 *********
89 // ************************************
90
91 // 出力ファイル名が指定されていればそれをそれで出力
92 // 無ければ入力ファイル名に.objを付加した名前で出力
93 if (argc < 2) {
94 ERROR(" usage >ec.exe [inputfile] (outputfile)");
95 } else if (argc < 3) {
96 strcpy(outfile, argv[1]);
97 strcat(outfile, ".obj");
98 } else {
99 strcpy(outfile, argv[2]);
100 }
101 strcpy(infile, argv[1]);
102 printf(" Input: %s\n", infile);
103 printf(" Output: %s\n", outfile);
104
105 ifp = fopen(infile, "r");
106 if (!ifp) {
107 ERROR("File open error(r)");
108 }
109
110 // 読み込む
111 fread(filedat, sizeof(char), 4096, ifp);
112 fclose(ifp);
113
114 // ****************************
115 // ********* 解析処理 *********
116 // ****************************
117
118 puts("Compiling..\n");
119
120 // 初期化処理
121 for (c = 0;c < MAX_FUNCS;c++) {
122 alloc_funcs[c].flag = 0;
123 }
124 for (c = 0;c < MAX_VALUES;c++) {
125 alloc_values[c].flag = 0;
126 }
127 funcs = 0;
128
129 // 処理開始
130 processing_block(filedat);
131
132 ofp = fopen(outfile, "w");
133 if (!ofp) {
134 ERROR("File open error(w)");
135 }
136 fputs(filedat, ofp);
137
138 fclose(ofp);
139
140 #ifdef DEBUG
141 printf("cnt0_0=%d cnt0_1=%d\n", cnt0_0, cnt0_1);
142 funcs = 0;
143 while (alloc_funcs[funcs].flag == 1) {
144 printf("関数「%s」はFunctionID = %d で、引数は%sです。\n", alloc_funcs[funcs].name, alloc_funcs[funcs].id, alloc_funcs[funcs].ret);
145 funcs++;
146 }
147 #endif
148
149 free(filedat);
150 }
151
152 //
153 // エラーを出力して終了
154 //
155 void ERROR(char *put)
156 {
157 puts(put);
158 exit(1);
159 }
160
161 //
162 // 空白を読み飛ばす
163 //
164 char *skipspace(char *p)
165 {
166 for (; *p == ' '; p++) ;
167 return p;
168 }
169
170 //
171 // コード全体を処理する
172 // […]も処理する
173 //
174 void processing_block(char *code)
175 {
176 char buf[2];
177 int c;
178
179 cnt0_0 = 0;
180 cnt0_1 = 0;
181
182 // […]を探してカウントする
183 while (1) {
184 code = skipspace(code);
185 switch (*code) {
186 case '[':
187 cnt0_0++;
188 code++;
189
190 // 関数名をスキャンする
191 // 途中で終わったらエラー
192 // 空白はスキップするのでcontinueする
193 while (*code != ']') {
194 if (*code == ' ') {
195 code++;
196 continue;
197 }
198 sprintf(buf, "%c", *code);
199 strcat(alloc_funcs[funcs].name, buf);
200 alloc_funcs[funcs].flag = 1;
201
202 code++;
203 if (*code == '\0') {
204 ERROR("Syntax error.");
205 }
206 }
207
208 //関数にIDを付与
209 if (alloc_funcs[funcs].name == "main") {
210 alloc_funcs[funcs].id = MAIN_FUNCID;
211 } else {
212 alloc_funcs[funcs].id = funcs + MAIN_FUNCID;
213 }
214 // 関数名を表示してから
215 // 引数リストスキャンのために一つ戻す
216 code--;
217 break;
218 case ']':
219 cnt0_1++;
220
221 code = skipspace(code);
222 // […]の数が合わないとエラー
223 if (cnt0_1 != cnt0_0) {
224 ERROR("Syntax error.");
225 }
226 code++;
227 code = skipspace(code);
228 if (*code != '(') {
229 alloc_funcs[funcs].id = 0;
230 alloc_funcs[funcs].flag = 0;
231 memset(alloc_funcs[funcs].name, 0, sizeof(alloc_funcs[funcs].name));
232 break;
233 }
234 code--;
235 funcs++;
236 processing_block0(code);
237 break;
238 case '\0':
239 // ソースファイルそのものが終わり
240 return;
241 default:
242 ;
243 }
244 code++;
245 }
246
247 }
248
249 //
250 // (…)を処理する
251 //
252 void processing_block0(char *code)
253 {
254 char buf[2];
255 while (1) {
256 code = skipspace(code);
257 switch (*code) {
258 case '(':
259 code++;
260 funcs--;
261 // 引数リストをスキャンする
262 // 途中で終わったらエラー
263 // 空白はスキップするのでcontinueする
264 while (*code != '/') {
265 if (*code == ' ') {
266 code++;
267 continue;
268 }
269 sprintf(buf, "%c", *code);
270 strcat(alloc_funcs[funcs].ret, buf);
271 code++;
272 if (*code == '\0') {
273 ERROR("Syntax error.");
274 }
275 }
276 funcs++;
277 return;
278 case '\0':
279 ERROR("Syntax error.");
280 return;
281 default:
282 ;
283
284 }
285 code++;
286 }
287 }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26