make_func.y

1     %{

2     #define EDIT_SOURCE

3     #define NO_OPCODES

4     #include "std.h"

5     #include "make_func.h"

6     #include "lex.h"

7     #include "preprocess.h"

8     #include "edit_source.h"

9    

10   #ifdef WIN32

11   #define MSDOS

12   #include <process.h>

13   #endif

14  

15       void mf_fatal(char *);

16      

17       int num_buff = 0;

18       int op_code, efun_code, efun1_code;

19       char *oper_codes[MAX_FUNC];

20       char *efun_codes[MAX_FUNC], *efun1_codes[MAX_FUNC];

21       char *efun_names[MAX_FUNC], *efun1_names[MAX_FUNC];

22       char *key[MAX_FUNC], *buf[MAX_FUNC];

23  

24       int min_arg = -1, limit_max = 0;

25      

26   /*

27   * arg_types is the types of all arguments. A 0 is used as a delimiter,

28   * marking next argument. An argument can have several types.

29   */

30   int arg_types[400], last_current_type;

31  

32   /*

33   * Store the types of the current efun. They will be copied into the

34   * arg_types list if they were not already there (to save memory).

35   */

36   int curr_arg_types[40], curr_arg_type_size;

37  

38   struct type {

39       char *name;

40       int num;

41   } types[] = {

42   { "void", VOID },

43   { "int", INT },

44   { "string", STRING },

45   { "object", OBJECT },

46   { "mapping", MAPPING },

47   { "mixed", MIXED },

48   { "unknown", UNKNOWN },

49   { "float", FLOAT},

50   { "function", FUNCTION},

51   { "buffer", BUFFER}

52   };

53  

54   #define NELEMS(arr)       (sizeof arr / sizeof arr[0])

55   %}

56  

57   %union {

58       int number;

59       char *string;

60   }

61  

62   %token ID NUM DEFAULT OPERATOR

63  

64   %type <number> type arg_list basic typel arg_type typel2 NUM

65  

66   %type <string> ID optional_ID optional_default

67  

68   %%

69  

70   specs: /* empty */ | specs spec ;

71  

72   spec: operator | func;

73      

74   operator: OPERATOR op_list ';' ;

75      

76   op_list: op | op_list ',' op ;

77  

78   op: ID

79       {

80          char f_name[500],c;

81          int i = 2;

82          sprintf(f_name, "F_%s", $1);

83          while ((c = f_name[i])) {

84              if (islower(c)) f_name[i++] = toupper(c);

85              else i++;

86          }

87          oper_codes[op_code] = (char *) malloc(i+1);

88          strcpy(oper_codes[op_code], f_name);

89           free($1);

90  

91          op_code++;

92       } ;

93  

94   optional_ID: ID | /* empty */ { $$ = ""; } ;

95  

96   optional_default: /* empty */ { $$="DEFAULT_NONE"; }

97                   | DEFAULT ':' NUM

98                     {

99                       static char buf[40];

100                       sprintf(buf, "%i", $3);

101                       $$ = buf;

102                 }

103                 | DEFAULT ':' ID

104                   {

105                       if (strcmp($3, "F__THIS_OBJECT"))

106                           yyerror("Illegal default");

107                       $$ = "DEFAULT_THIS_OBJECT";

108                   } ;

109

110 func: type ID optional_ID '(' arg_list optional_default ')' ';'

111     {

112        char buff[500];

113        char f_name[500];

114        int i, len;

115        if (min_arg == -1)

116            min_arg = $5;

117         if (min_arg > 4) mf_fatal("min_arg > 4/n");

118        if ($3[0] == '/0') {

119            if (strlen($2) + 1 + 2 > sizeof f_name)

120               mf_fatal("A local buffer was too small!(1)/n");

121            sprintf(f_name, "F_%s", $2);

122            len = strlen(f_name);

123            for (i=0; i < len; i++) {

124               if (islower(f_name[i]))

125                   f_name[i] = toupper(f_name[i]);

126            }

127             if (min_arg == 1 && !limit_max && $5 == 1) {

128                efun1_codes[efun1_code] = (char *) malloc(len + 1);

129                strcpy(efun1_codes[efun1_code], f_name);

130               efun1_names[efun1_code] = (char *) malloc(len - 1);

131               strcpy(efun1_names[efun1_code], $2);

132                efun1_code++;

133            } else {

134                efun_codes[efun_code] = (char *) malloc(len + 1);

135                strcpy(efun_codes[efun_code], f_name);

136               efun_names[efun_code] = (char *) malloc(len - 1);

137               strcpy(efun_names[efun_code], $2);

138                efun_code++;

139            }

140        } else {

141            if (strlen($3) + 1 + 17 > sizeof f_name)

142               mf_fatal("A local buffer was too small(2)!/n");

143            sprintf(f_name, "F_%s | F_ALIAS_FLAG", $3);

144            len = strlen(f_name);

145            for (i=0; i < len; i++) {

146               if (islower(f_name[i]))

147                   f_name[i] = toupper(f_name[i]);

148            }

149            free($3);

150        }

151        for(i=0; i < last_current_type; i++) {

152            int j;

153            for (j = 0; j+i<last_current_type && j < curr_arg_type_size; j++)

154            {

155               if (curr_arg_types[j] != arg_types[i+j])

156                   break;

157            }

158            if (j == curr_arg_type_size)

159               break;

160        }

161        if (i == last_current_type) {

162            int j;

163            for (j=0; j < curr_arg_type_size; j++) {

164               arg_types[last_current_type++] = curr_arg_types[j];

165               if (last_current_type == NELEMS(arg_types))

166                   yyerror("Array 'arg_types' is too small");

167            }

168        }

169         if (!strcmp($2, "call_other") && !lookup_define("CAST_CALL_OTHERS")) {

170            $1 = MIXED;

171        }

172          sprintf(buff, "{/"%s/",%s,0,0,%d,%d,%s,%s,%s,%s,%s,%d,%s},/n",

173               $2, f_name, min_arg, limit_max ? -1 : $5,

174               $1 != VOID ? ctype($1) : "TYPE_NOVALUE",

175               etype(0), etype(1), etype(2), etype(3), i, $6);

176        if (strlen(buff) > sizeof buff)

177            mf_fatal("Local buffer overwritten !/n");

178

179         key[num_buff] = $2;

180        buf[num_buff] = (char *) malloc(strlen(buff) + 1);

181         strcpy(buf[num_buff], buff);

182         num_buff++;

183        min_arg = -1;

184        limit_max = 0;

185        curr_arg_type_size = 0;

186     } ;

187

188 type: basic | basic '*' { $$ = $1 | 0x10000; };

189

190 basic: ID

191     {

192        int i = NELEMS(types);

193        $$ = 0;

194        while (i--){

195            if (strcmp($1, types[i].name) == 0) {

196               $$ = types[i].num;

197               break;

198            }

199        }

200        if (!$$) {

201               char buf[256];

202               sprintf(buf, "Invalid type: %s", $1);

203               yyerror(buf);

204        }

205         free($1);

206     };

207

208 arg_list: /* empty */            { $$ = 0; }

209        | typel2                 { $$ = 1; if ($1) min_arg = 0; }

210        | arg_list ',' typel2        { $$ = $1 + 1; if ($3) min_arg = $$ - 1; } ;

211

212 typel2: typel

213     {

214        $$ = $1;

215        curr_arg_types[curr_arg_type_size++] = 0;

216        if (curr_arg_type_size == NELEMS(curr_arg_types))

217            yyerror("Too many arguments");

218     } ;

219

220 arg_type: type

221     {

222        if ($1 != VOID) {

223            curr_arg_types[curr_arg_type_size++] = $1;

224            if (curr_arg_type_size == NELEMS(curr_arg_types))

225               yyerror("Too many arguments");

226        }

227        $$ = $1;

228     } ;

229

230 typel: arg_type                    { $$ = ($1 == VOID && min_arg == -1); }

231      | typel '|' arg_type     { $$ = (min_arg == -1 && ($1 || $3 == VOID));}

232      | '.' '.' '.'              { $$ = min_arg == -1 ; limit_max = 1; } ;

233

234 %%

235

236 char *ctype P1(int, n)

237 {

238     static char buff[100];   /* 100 is such a comfortable size :-) */

239     char *p = (char *)NULL;

240

241     if (n & 0x10000)

242        strcpy(buff, "TYPE_MOD_ARRAY|");

243     else

244        buff[0] = '/0';

245     n &= ~0x10000;

246     switch(n) {

247        case FLOAT: p = "TYPE_REAL"; break;

248        case FUNCTION: p = "TYPE_FUNCTION"; break;

249        case VOID: p = "TYPE_VOID"; break;

250        case STRING: p = "TYPE_STRING"; break;

251        case INT: p = "TYPE_NUMBER"; break;

252        case OBJECT: p = "TYPE_OBJECT"; break;

253        case MAPPING: p = "TYPE_MAPPING"; break;

254        case BUFFER: p = "TYPE_BUFFER"; break;

255        case MIXED: p = "TYPE_ANY"; break;

256        case UNKNOWN: p = "TYPE_UNKNOWN"; break;

257        default: yyerror("Bad type!");

258     }

259     strcat(buff, p);

260     if (strlen(buff) + 1 > sizeof buff)

261        mf_fatal("Local buffer overwritten in ctype()");

262     return buff;

263 }

264

265 char *etype1 P1(int, n)

266 {

267     if (n & 0x10000)

268        return "T_ARRAY";

269     switch(n) {

270     case FLOAT:

271     return "T_REAL";

272     case FUNCTION:

273     return "T_FUNCTION";

274     case INT:

275        return "T_NUMBER";

276     case OBJECT:

277        return "T_OBJECT";

278     case MAPPING:

279        return "T_MAPPING";

280     case STRING:

281        return "T_STRING";

282     case BUFFER:

283        return "T_BUFFER";

284     case MIXED:

285        return "T_ANY";  /* 0 means any type */

286     default:

287        yyerror("Illegal type for argument");

288     }

289     return "What?";

290 }

291

292 char *etype P1(int, n)

293 {

294     int i;

295     int local_size = 100;

296     char *buff = (char *)malloc(local_size);

297

298     for (i=0; i < curr_arg_type_size; i++) {

299        if (n == 0)

300            break;

301        if (curr_arg_types[i] == 0)

302            n--;

303     }

304     if (i == curr_arg_type_size)

305        return "T_ANY";

306     buff[0] = '/0';

307     for(; curr_arg_types[i] != 0; i++) {

308        char *p;

309        if (curr_arg_types[i] == VOID)

310            continue;

311        if (buff[0] != '/0')

312            strcat(buff, "|");

313        p = etype1(curr_arg_types[i]);

314        /*

315        * The number 2 below is to include the zero-byte and the next

316        * '|' (which may not come).

317        */

318        if (strlen(p) + strlen(buff) + 2 > local_size) {

319            fprintf(stderr, "Buffer overflow!/n");

320            exit(1);

321        }

322        strcat(buff, etype1(curr_arg_types[i]));

323     }

324     if (!strcmp(buff, ""))

325       strcpy(buff, "T_ANY");

326     return buff;

327 }

328

329 int ident PROT((int));

330

331 int yylex() {

332     register int c;

333    

334     for(;;) {

335        switch(c = getc(yyin)){

336        case ' ':

337        case '/t':

338            continue;

339        case '/n':

340            current_line++;

341            continue;

342        case '!':

343        {

344            char buff[2048];

345            fgets(buff, 2047, yyin);

346            fprintf(stderr, "Configuration problem: %s/n", buff);

347            exit(-1);

348        }

349        case '#':

350        {

351            int line;

352

353            char aBuf[2048], fname[2048];

354            fgets(aBuf, 2047, yyin);

355            if (sscanf(aBuf, "%d /"%[^/"]/"", &line, fname)) {

356               current_line = line;

357               if (current_file) free(current_file);

358               current_file = (char*)malloc(strlen(fname) + 1);

359               strcpy(current_file, fname);

360            } else

361            if (sscanf(aBuf, "%d", &line)) current_line = line;

362             current_line++;

363            continue;

364        }

365        case EOF:

366            fclose(yyin);

367            return -1;

368        default:

369            if ((c >= '0' && c <= '9') || c == '-') {

370               int v;

371               int neg = 0;

372               v = 0;

373               if (c == '-') {

374                   neg = 1;

375                   c = '0';

376               }

377               do {

378                   v = v * 10 + (c - '0');

379                   c = getc(yyin);

380               } while (c >= '0' && c <= '9');

381               ungetc(c, yyin);

382               yylval.number = (neg ? -v : v);

383               return NUM;

384            }

385            if (isalunum(c))

386               return ident(c);

387            return c;

388        }

389     }

390 }

391

392 int ident P1(int, c)

393 {

394     char buff[100];

395     int len;

396

397     for (len = 0; isalunum(c); c = getc(yyin)) {

398        buff[len++] = c;

399        if (len == sizeof buff - 1) {

400            yyerror("Too long indentifier");

401            break;

402        }

403     }

404     (void)ungetc(c, yyin);

405     buff[len] = '/0';

406     if (!strcmp(buff, "default"))

407        return DEFAULT;

408     if (!strcmp(buff, "operator"))

409        return OPERATOR;

410

411     yylval.string = (char *)malloc(strlen(buff)+1);

412     strcpy(yylval.string, buff);

413     return ID;

414 }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值