%option noyywrap bison-bridge bison-locations %{ #include #include #define TAG_IDENT 1 #define TAG_KEYW 2 char *tag_names[] = { "END_OF_PROGRAM", "IDENT", "KEYW" }; struct Position { int line, pos, index; }; void print_pos(struct Position *p) { printf("(%d, %d)", p->line, p->pos); } struct Fragment { struct Position starting, following; }; typedef struct Fragment YYLTYPE; void print_frag(struct Fragment *f) { print_pos(&(f->starting)); printf("-"); print_pos(&(f->following)); } union Token { int code; long num; char ch; }; typedef union Token YYSTYPE; int continued; struct Position cur; #define YY_USER_ACTION \ {\ int i; \ if (! continued)\ yylloc->starting = cur;\ continued = 0;\ \ for (i = 0; i < yyleng; i++) {\ if (yytext[i] == '\n') {\ cur.line++;\ cur.pos = 1;\ }\ else\ cur.pos++;\ cur.index++;\ }\ yylloc->following = cur;\ } void init_scanner(char *program) { continued = 0; cur.line = 1; cur.pos = 1; cur.index = 0; yy_scan_string(program); } struct Error { struct Position pos; char *msg; } *errors; int capacity = 0; int errLength = 0; void err(char *msg, struct Position pos) { struct Error err; err.msg = msg; err.pos = pos; if (capacity == errLength) { if (capacity == 0) { capacity = 1; } else { capacity *= 2; } struct Error* errors1 = (struct Error*)malloc((capacity) * sizeof(struct Error)); int i; for (i = 0; i < errLength; i++) { errors1[i] = errors[i]; } free(errors); errors = errors1; } errors[errLength] = err; errLength++; } struct Comment { struct Fragment pos; } *comments; int capacityCom = 0; int comLength = 0; void com(struct Fragment pos) { struct Fragment f; f.starting = pos.starting; f.following = pos.following; struct Comment com; com.pos = f; if (capacityCom == comLength) { if (capacityCom == 0) { capacityCom = 1; } else { capacityCom *= 2; } struct Comment* comments1 = (struct Comment*)malloc((capacityCom) * sizeof(struct Comment)); int i; for (i = 0; i < comLength; i++) { comments1[i] = comments[i]; } free(comments); comments = comments1; } comments[comLength] = com; comLength++; } char **names; int nameslen = 0; int contain(char *name) { int i; for (i = 0; i < nameslen; i++) { if (strcmp(names[i], name) == 0) { return i; } } return -1; } int addName(char *name) { if (contain(name) == -1) { if (!nameslen % 10) { char** names1 = (char**)malloc((nameslen +10) * sizeof(char*)); int i; for (i = 0; i < nameslen; i++) { names1[i] = names[i]; } free(names); names = names1; } names[nameslen] = name; return nameslen++; } else { return contain(name); } } %} %x STATE1 %% [ \n\t]+ (with|end|\*\*) { yylval->code = addName(yytext); yylloc->following = cur; return TAG_KEYW; } [a-zA-Z]+ { if (yyleng % 2 == 1) { yylval->code = addName(yytext); yylloc->following = cur; return TAG_IDENT; } else { err("syntax error", yylloc->starting); BEGIN(0); } } [\*]{3,} { yylval->code = addName(yytext); yylloc->following = cur; return TAG_IDENT; } [\*]{1} BEGIN(STATE1); continued = 1; [^\n]* { com(*yylloc); yylloc->following = cur; BEGIN(0); } [.] { err("syntax error", yylloc->starting); BEGIN(0); } <> { return 0; } %% #define PROGRAM "*njnbbjntj\n bmkgmglkm *** ** gggmgm with " int main() { int tag; YYSTYPE value; YYLTYPE coords; init_scanner(PROGRAM); do { tag = yylex(&value, &coords); if (tag != 0) { printf("%s ", tag_names[tag]); print_frag(&coords); printf(" %s\n", names[value.code]); } else { int i; for (i = 0; i < comLength; i++) { printf("COMMENT "); print_frag(&(comments[i].pos)); printf("\n"); } for (i = 0; i < errLength; i++) { printf("ERROR "); print_pos(&(errors[i].pos)); printf(" %s ", errors[i].msg); printf("\n"); } printf("END_OF_PROGRAM "); print_pos(&(coords.following)); printf("\n"); } } while (tag != 0); return 0; }