268 lines
5.2 KiB
ReasonML
268 lines
5.2 KiB
ReasonML
|
#include <stdlib.h>
|
||
|
#include <stdio.h>
|
||
|
#include <sys/stat.h>
|
||
|
#include <sys/mman.h>
|
||
|
#include <string.h>
|
||
|
|
||
|
#define ADDEQ 257
|
||
|
#define ANDAND 258
|
||
|
#define ANDEQ 259
|
||
|
#define ARRAY 260
|
||
|
#define ASM 261
|
||
|
#define AUTO 262
|
||
|
#define BREAK 263
|
||
|
#define CASE 264
|
||
|
#define CHAR 265
|
||
|
#define CONST 266
|
||
|
#define CONTINUE 267
|
||
|
#define DECR 268
|
||
|
#define DEFAULT 269
|
||
|
#define DEREF 270
|
||
|
#define DIVEQ 271
|
||
|
#define DO 272
|
||
|
#define DOUBLE 273
|
||
|
#define ELLIPSIS 274
|
||
|
#define ELSE 275
|
||
|
#define ENUM 276
|
||
|
#define EQL 277
|
||
|
#define EXTERN 278
|
||
|
#define FCON 279
|
||
|
#define FLOAT 280
|
||
|
#define FOR 281
|
||
|
#define FUNCTION 282
|
||
|
#define GEQ 283
|
||
|
#define GOTO 284
|
||
|
#define ICON 285
|
||
|
#define ID 286
|
||
|
#define IF 287
|
||
|
#define INCR 288
|
||
|
#define INT 289
|
||
|
#define LEQ 290
|
||
|
#define LONG 291
|
||
|
#define LSHIFT 292
|
||
|
#define LSHIFTEQ 293
|
||
|
#define MODEQ 294
|
||
|
#define MULEQ 295
|
||
|
#define NEQ 296
|
||
|
#define OREQ 297
|
||
|
#define OROR 298
|
||
|
#define POINTER 299
|
||
|
#define REGISTER 300
|
||
|
#define RETURN 301
|
||
|
#define RSHIFT 302
|
||
|
#define RSHIFTEQ 303
|
||
|
#define SCON 304
|
||
|
#define SHORT 305
|
||
|
#define SIGNED 306
|
||
|
#define SIZEOF 307
|
||
|
#define STATIC 308
|
||
|
#define STRUCT 309
|
||
|
#define SUBEQ 310
|
||
|
#define SWITCH 311
|
||
|
#define TYPEDEF 312
|
||
|
#define UNION 313
|
||
|
#define UNSIGNED 314
|
||
|
#define VOID 315
|
||
|
#define VOLATILE 316
|
||
|
#define WHILE 317
|
||
|
#define XOREQ 318
|
||
|
#define EOI 319
|
||
|
|
||
|
typedef unsigned int unint;
|
||
|
typedef unsigned char uchar;
|
||
|
|
||
|
#define YYCTYPE uchar
|
||
|
#define YYCURSOR cursor
|
||
|
#define YYLIMIT s->lim
|
||
|
#define YYMARKER s->ptr
|
||
|
#define YYFILL(n) {cursor = fill(s, cursor);}
|
||
|
|
||
|
#define RET(i) {s->cur = cursor; return i;}
|
||
|
|
||
|
typedef struct Scanner {
|
||
|
uchar *tok, *ptr, *cur, *pos, *lim, *eof;
|
||
|
unint line;
|
||
|
} Scanner;
|
||
|
|
||
|
uchar *fill(Scanner *s, uchar *cursor){
|
||
|
if(!s->eof){
|
||
|
unint cnt = s->lim - s->tok;
|
||
|
uchar *buf = malloc((cnt + 1)*sizeof(uchar));
|
||
|
memcpy(buf, s->tok, cnt);
|
||
|
cursor = &buf[cursor - s->tok];
|
||
|
s->pos = &buf[s->pos - s->tok];
|
||
|
s->ptr = &buf[s->ptr - s->tok];
|
||
|
s->lim = &buf[cnt];
|
||
|
s->eof = s->lim; *(s->eof)++ = '\n';
|
||
|
s->tok = buf;
|
||
|
}
|
||
|
return cursor;
|
||
|
}
|
||
|
|
||
|
int scan(Scanner *s){
|
||
|
uchar *cursor = s->cur;
|
||
|
std:
|
||
|
s->tok = cursor;
|
||
|
/*!re2c
|
||
|
any = [\000-\377];
|
||
|
O = [0-7];
|
||
|
D = [0-9];
|
||
|
L = [a-zA-Z_];
|
||
|
H = [a-fA-F0-9];
|
||
|
E = [Ee] [+-]? D+;
|
||
|
FS = [fFlL];
|
||
|
IS = [uUlL]*;
|
||
|
ESC = [\\] ([abfnrtv?'"\\] | "x" H+ | O+);
|
||
|
*/
|
||
|
|
||
|
/*!re2c
|
||
|
"/*" { goto comment; }
|
||
|
|
||
|
"auto" { RET(AUTO); }
|
||
|
"break" { RET(BREAK); }
|
||
|
"case" { RET(CASE); }
|
||
|
"char" { RET(CHAR); }
|
||
|
"const" { RET(CONST); }
|
||
|
"continue" { RET(CONTINUE); }
|
||
|
"default" { RET(DEFAULT); }
|
||
|
"do" { RET(DO); }
|
||
|
"double" { RET(DOUBLE); }
|
||
|
"else" { RET(ELSE); }
|
||
|
"enum" { RET(ENUM); }
|
||
|
"extern" { RET(EXTERN); }
|
||
|
"float" { RET(FLOAT); }
|
||
|
"for" { RET(FOR); }
|
||
|
"goto" { RET(GOTO); }
|
||
|
"if" { RET(IF); }
|
||
|
"int" { RET(INT); }
|
||
|
"long" { RET(LONG); }
|
||
|
"register" { RET(REGISTER); }
|
||
|
"return" { RET(RETURN); }
|
||
|
"short" { RET(SHORT); }
|
||
|
"signed" { RET(SIGNED); }
|
||
|
"sizeof" { RET(SIZEOF); }
|
||
|
"static" { RET(STATIC); }
|
||
|
"struct" { RET(STRUCT); }
|
||
|
"switch" { RET(SWITCH); }
|
||
|
"typedef" { RET(TYPEDEF); }
|
||
|
"union" { RET(UNION); }
|
||
|
"unsigned" { RET(UNSIGNED); }
|
||
|
"void" { RET(VOID); }
|
||
|
"volatile" { RET(VOLATILE); }
|
||
|
"while" { RET(WHILE); }
|
||
|
|
||
|
L (L|D)* { RET(ID); }
|
||
|
|
||
|
("0" [xX] H+ IS?) | ("0" D+ IS?) | (D+ IS?) |
|
||
|
(['] (ESC|any\[\n\\'])* ['])
|
||
|
{ RET(ICON); }
|
||
|
|
||
|
(D+ E FS?) | (D* "." D+ E? FS?) | (D+ "." D* E? FS?)
|
||
|
{ RET(FCON); }
|
||
|
|
||
|
(["] (ESC|any\[\n\\"])* ["])
|
||
|
{ RET(SCON); }
|
||
|
|
||
|
"..." { RET(ELLIPSIS); }
|
||
|
">>=" { RET(RSHIFTEQ); }
|
||
|
"<<=" { RET(LSHIFTEQ); }
|
||
|
"+=" { RET(ADDEQ); }
|
||
|
"-=" { RET(SUBEQ); }
|
||
|
"*=" { RET(MULEQ); }
|
||
|
"/=" { RET(DIVEQ); }
|
||
|
"%=" { RET(MODEQ); }
|
||
|
"&=" { RET(ANDEQ); }
|
||
|
"^=" { RET(XOREQ); }
|
||
|
"|=" { RET(OREQ); }
|
||
|
">>" { RET(RSHIFT); }
|
||
|
"<<" { RET(LSHIFT); }
|
||
|
"++" { RET(INCR); }
|
||
|
"--" { RET(DECR); }
|
||
|
"->" { RET(DEREF); }
|
||
|
"&&" { RET(ANDAND); }
|
||
|
"||" { RET(OROR); }
|
||
|
"<=" { RET(LEQ); }
|
||
|
">=" { RET(GEQ); }
|
||
|
"==" { RET(EQL); }
|
||
|
"!=" { RET(NEQ); }
|
||
|
";" { RET(';'); }
|
||
|
"{" { RET('{'); }
|
||
|
"}" { RET('}'); }
|
||
|
"," { RET(','); }
|
||
|
":" { RET(':'); }
|
||
|
"=" { RET('='); }
|
||
|
"(" { RET('('); }
|
||
|
")" { RET(')'); }
|
||
|
"[" { RET('['); }
|
||
|
"]" { RET(']'); }
|
||
|
"." { RET('.'); }
|
||
|
"&" { RET('&'); }
|
||
|
"!" { RET('!'); }
|
||
|
"~" { RET('~'); }
|
||
|
"-" { RET('-'); }
|
||
|
"+" { RET('+'); }
|
||
|
"*" { RET('*'); }
|
||
|
"/" { RET('/'); }
|
||
|
"%" { RET('%'); }
|
||
|
"<" { RET('<'); }
|
||
|
">" { RET('>'); }
|
||
|
"^" { RET('^'); }
|
||
|
"|" { RET('|'); }
|
||
|
"?" { RET('?'); }
|
||
|
|
||
|
|
||
|
[ \t\v\f]+ { goto std; }
|
||
|
|
||
|
"\n"
|
||
|
{
|
||
|
if(cursor == s->eof) RET(EOI);
|
||
|
s->pos = cursor; s->line++;
|
||
|
goto std;
|
||
|
}
|
||
|
|
||
|
any
|
||
|
{
|
||
|
printf("unexpected character: %c\n", *s->tok);
|
||
|
goto std;
|
||
|
}
|
||
|
*/
|
||
|
|
||
|
comment:
|
||
|
/*!re2c
|
||
|
"*/" { goto std; }
|
||
|
"\n"
|
||
|
{
|
||
|
if(cursor == s->eof) RET(EOI);
|
||
|
s->tok = s->pos = cursor; s->line++;
|
||
|
goto comment;
|
||
|
}
|
||
|
any { goto comment; }
|
||
|
*/
|
||
|
}
|
||
|
|
||
|
#ifndef MAP_NORESERVE
|
||
|
#define MAP_NORESERVE 0
|
||
|
#endif
|
||
|
|
||
|
main(){
|
||
|
Scanner in;
|
||
|
struct stat statbuf;
|
||
|
uchar *buf;
|
||
|
fstat(0, &statbuf);
|
||
|
buf = mmap(NULL, statbuf.st_size, PROT_READ, MAP_SHARED|MAP_NORESERVE,
|
||
|
0, 0);
|
||
|
if(buf != (uchar*)(-1)){
|
||
|
int t;
|
||
|
in.lim = &(in.cur = buf)[statbuf.st_size];
|
||
|
in.pos = NULL;
|
||
|
in.eof = NULL;
|
||
|
while((t = scan(&in)) != EOI){
|
||
|
/*
|
||
|
printf("%d\t%.*s\n", t, in.cur - in.tok, in.tok);
|
||
|
printf("%d\n", t);
|
||
|
*/
|
||
|
}
|
||
|
munmap(buf, statbuf.st_size);
|
||
|
}
|
||
|
}
|