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);
}