1 #include <stdlib.h> 2 #include <stdio.h> 3 #include <string.h> 4 5 typedef unsigned int uint; 6 typedef unsigned char uchar; 7 8 #define BSIZE 8192 9 10 #define YYCTYPE uchar 11 #define YYCURSOR cursor 12 #define YYLIMIT s->lim 13 #define YYMARKER s->ptr 14 #define YYFILL {cursor = fill(s, cursor);} 15 16 #define RETURN(i) {s->cur = cursor; return i;} 17 18 typedef struct Scanner { 19 int fd; 20 uchar *bot, *tok, *ptr, *cur, *pos, *lim, *top, *eof; 21 uint line; 22 } Scanner; 23 24 uchar *fill(Scanner *s, uchar *cursor){ 25 if(!s->eof){ 26 uint cnt = s->tok - s->bot; 27 if(cnt){ 28 memcpy(s->bot, s->tok, s->lim - s->tok); 29 s->tok = s->bot; 30 s->ptr -= cnt; 31 cursor -= cnt; 32 s->pos -= cnt; 33 s->lim -= cnt; 34 } 35 if((s->top - s->lim) < BSIZE){ 36 uchar *buf = (uchar*) malloc(((s->lim - s->bot) + BSIZE)*sizeof(uchar)); 37 memcpy(buf, s->tok, s->lim - s->tok); 38 s->tok = buf; 39 s->ptr = &buf[s->ptr - s->bot]; 40 cursor = &buf[cursor - s->bot]; 41 s->pos = &buf[s->pos - s->bot]; 42 s->lim = &buf[s->lim - s->bot]; 43 s->top = &s->lim[BSIZE]; 44 free(s->bot); 45 s->bot = buf; 46 } 47 if((cnt = read(s->fd, (char*) s->lim, BSIZE)) != BSIZE){ 48 s->eof = &s->lim[cnt]; *(s->eof)++ = '\n'; 49 } 50 s->lim += cnt; 51 } 52 return cursor; 53 } 54 55 int scan(Scanner *s){ 56 uchar *cursor = s->cur; 57 uint depth; 58 std: 59 s->tok = cursor; 60 /*!re2c 61 any = [\000-\377]; 62 digit = [0-9]; 63 letter = [a-zA-Z]; 64 */ 65 66 /*!re2c 67 "(*" { depth = 1; goto comment; } 68 69 digit + {RETURN(1);} 70 digit + / ".." {RETURN(1);} 71 [0-7] + "B" {RETURN(2);} 72 [0-7] + "C" {RETURN(3);} 73 digit [0-9A-F] * "H" {RETURN(4);} 74 digit + "." digit * ("E" ([+-]) ? digit +) ? {RETURN(5);} 75 ['] (any\[\n']) * ['] | ["] (any\[\n"]) * ["] {RETURN(6);} 76 77 "#" {RETURN(7);} 78 "&" {RETURN(8);} 79 "(" {RETURN(9);} 80 ")" {RETURN(10);} 81 "*" {RETURN(11);} 82 "+" {RETURN(12);} 83 "," {RETURN(13);} 84 "-" {RETURN(14);} 85 "." {RETURN(15);} 86 ".." {RETURN(16);} 87 "/" {RETURN(17);} 88 ":" {RETURN(18);} 89 ":=" {RETURN(19);} 90 ";" {RETURN(20);} 91 "<" {RETURN(21);} 92 "<=" {RETURN(22);} 93 "<>" {RETURN(23);} 94 "=" {RETURN(24);} 95 ">" {RETURN(25);} 96 ">=" {RETURN(26);} 97 "[" {RETURN(27);} 98 "]" {RETURN(28);} 99 "^" {RETURN(29);} 100 "{" {RETURN(30);} 101 "|" {RETURN(31);} 102 "}" {RETURN(32);} 103 "~" {RETURN(33);} 104 105 "AND" {RETURN(34);} 106 "ARRAY" {RETURN(35);} 107 "BEGIN" {RETURN(36);} 108 "BY" {RETURN(37);} 109 "CASE" {RETURN(38);} 110 "CONST" {RETURN(39);} 111 "DEFINITION" {RETURN(40);} 112 "DIV" {RETURN(41);} 113 "DO" {RETURN(42);} 114 "ELSE" {RETURN(43);} 115 "ELSIF" {RETURN(44);} 116 "END" {RETURN(45);} 117 "EXIT" {RETURN(46);} 118 "EXPORT" {RETURN(47);} 119 "FOR" {RETURN(48);} 120 "FROM" {RETURN(49);} 121 "IF" {RETURN(50);} 122 "IMPLEMENTATION" {RETURN(51);} 123 "IMPORT" {RETURN(52);} 124 "IN" {RETURN(53);} 125 "LOOP" {RETURN(54);} 126 "MOD" {RETURN(55);} 127 "MODULE" {RETURN(56);} 128 "NOT" {RETURN(57);} 129 "OF" {RETURN(58);} 130 "OR" {RETURN(59);} 131 "POINTER" {RETURN(60);} 132 "PROCEDURE" {RETURN(61);} 133 "QUALIFIED" {RETURN(62);} 134 "RECORD" {RETURN(63);} 135 "REPEAT" {RETURN(64);} 136 "RETURN" {RETURN(65);} 137 "SET" {RETURN(66);} 138 "THEN" {RETURN(67);} 139 "TO" {RETURN(68);} 140 "TYPE" {RETURN(69);} 141 "UNTIL" {RETURN(70);} 142 "VAR" {RETURN(71);} 143 "WHILE" {RETURN(72);} 144 "WITH" {RETURN(73);} 145 146 letter (letter | digit) * {RETURN(74);} 147 148 [ \t]+ { goto std; } 149 150 "\n" 151 { 152 if(cursor == s->eof) RETURN(0); 153 s->pos = cursor; s->line++; 154 goto std; 155 } 156 157 any 158 { 159 printf("unexpected character: %c\n", *s->tok); 160 goto std; 161 } 162 */ 163 comment: 164 /*!re2c 165 "*)" 166 { 167 if(--depth == 0) 168 goto std; 169 else 170 goto comment; 171 } 172 "(*" { ++depth; goto comment; } 173 "\n" 174 { 175 if(cursor == s->eof) RETURN(0); 176 s->tok = s->pos = cursor; s->line++; 177 goto comment; 178 } 179 any { goto comment; } 180 */ 181 } 182 183 /* 184 void putStr(FILE *o, char *s, uint l){ 185 while(l-- > 0) 186 putc(*s++, o); 187 } 188 */ 189 190 main(){ 191 Scanner in; 192 memset((char*) &in, 0, sizeof(in)); 193 in.fd = 0; 194 while(scan(&in)){ 195 /* 196 putc('<', stdout); 197 putStr(stdout, (char*) in.tok, in.cur - in.tok); 198 putc('>', stdout); 199 putc('\n', stdout); 200 */ 201 } 202 } 203