A [a-zA-Z_] N [a-zA-Z0-9_.] W [ \t\n]* %{ #undef input #undef unput #define input() parser_input.f_input() #define unput(c) parser_input.f_unput(c) static char * buf_s; static size_t buf_n, buf_m; static int paren_lev = 0; struct list * f(char const *, ...); #define CHUNK 1024 %} %start CODE %% <INITIAL>\'([^\\\']|(\\.))\' { yylval.list = f("'", yytext); return ID; } <INITIAL>(\'([^\\\']|(\\.))*\')|(\"([^\\\"]|(\\.))*\") { yylval.list = f("'", yytext); return CCODE; } <INITIAL>"error" { char * p = yytext, tmp; while (*p && !isspace(*p)) p++; tmp = *p; *p = 0; yylval.list = f("'", yytext); *p = tmp; yylval.list->next = f("w", p); return CCODE; } <INITIAL>{A}{N}*{W}: { char tmp, *p = yytext, *q, * r; for (q = p; *q && !isspace(*q) && *q != ':'; q++) ; tmp=*q, *q='\0', yylval.list = f("i", yytext), *q=tmp; for (r = q; *r && isspace(*r); r++) ; tmp=*r, *r='\0', yylval.list->next = f("ws", q, ":"); *r = tmp; def_nonterminal(yylval.list); return PREFIX; } <INITIAL>\<{W}{A}{N}*{W}\> { char tmp, *p = yytext + 1, *q, * r; while (*p && isspace(*p)) p++; tmp=*p, *p=0, yylval.list=f("w", p), *p = tmp; for (q = p; *q && !isspace(*q) && *q != '>'; q++) ; tmp=*q, *q='\0', yylval.list->next = f("T", p), *q=tmp; for (r = q; *r && isspace(*r); r++) ; tmp=*r, *r='\0', yylval.list->next->next = f("w", q), *r=tmp; yylval.list = f("sls", "<", yylval.list, ">"); return TAG; } <INITIAL>{A}{N}* { yylval.list = f("i", yytext); return ID; } <INITIAL>%% return MARK; <INITIAL>\/\* { buf_n = 0; put('/'); put('*'); skipahead('*', '/', "comment"); put('*'); put('/'); yylval.list = f("w", buf_s); return WS; } <INITIAL>%\{ { buf_n = 0; skipahead('%', '}', "%{...%}"); yylval.list = f("scs","%{", buf_s, "%}"); return CURLS; } <INITIAL>%start return START; <INITIAL>%union { return UNION; } <INITIAL>%token { yylval.list = f("s", yytext); return TOKEN; } <INITIAL>%(right|left|nonassoc|type) { yylval.list = f("s", yytext); return RWORD; } <INITIAL>%prec return PREC; <INITIAL>[ \t\n]+ { yylval.list = f("w", yytext); return WS; } <INITIAL>[0-9]+ { yylval.list = f("c", yytext); return NUMBER; } <INITIAL>\{ { BEGIN CODE; paren_lev = 1; buf_n = 0; put('{'); } <INITIAL>[:|<>;] return *yytext; <INITIAL>. { yylval.list = f("s", yytext); return CCODE; } <CODE>\"([^\\\"]|(\\.))*\" { append(yytext); } <CODE>\'([^\\\']|(\\.))*\' { append(yytext); } <CODE>\/\* { put('/'); put('*'); skipahead('*', '/', "comment"); put('*'); put('/'); } <CODE>\{ { ++paren_lev; put('{'); } <CODE>\} { put('}'); if (!--paren_lev) { BEGIN INITIAL; yylval.list = f("c", buf_s); return CCODE; } } <CODE>(.|\n) { put(*yytext); } %% put(c) int c; { if (!buf_m) buf_s = TMALLOC(char, buf_m = CHUNK); if (buf_n + 1 >= buf_m) buf_s = TREALLOC(char, buf_s, buf_m += CHUNK); buf_s[buf_n++] = c; buf_s[buf_n] = 0; } append(str) char const * str; { while (*str) put(*str++); } skipahead(c1, c2, section) int c1, c2; char const * section; { int c; assert(CHUNK > 1); while ((c = input()) && c != EOF) { if (c == c1) { if ((c = input()) == EOF || !c) goto eof_in; if (c == c2) { buf_s[buf_n] = 0; return; } unput(c); c = c1; } put(c); } if (c1 == EOF) { buf_s[buf_n] = 0; return; } eof_in: parser_error("EOF in %s\n", section); }