%{ #include "email.h" #include %} %union { struct message *m; struct header *h; sz *text; char *string; } %token HEADERNAME, HEADERBODY, CONTINUATION, LINE, EMPTY_LINE, FROMLINE %type body, continuations %type message, header %type headerline %% file: message | file message message: header EMPTY_LINE body { struct mlist *ml; $1->body = $3; $$ = $1; ml = new_mlist($1); if (last_message) { last_message->next = ml; last_message = ml; } else { first_message = ml; last_message = ml; } } header: FROMLINE headerline { struct message *m = new_message($2); debug(2, "fromline: %s\n", $1); m->fromline = str2sz($1); $$ = m; } | headerline { struct message *m = new_message($1); $$ = m; } | header headerline { add_header($1, $2); $$ = $1; } headerline: HEADERNAME HEADERBODY { struct header *h = new_header(str2sz($1), str2sz($2)); $$ = h; } | HEADERNAME HEADERBODY continuations { struct header *h; sz *s = str2sz($2); szcat(s, " "); szcat(s, $3); szfree($3); h = new_header(str2sz($1), s); $$ = h; } continuations: CONTINUATION { $$ = str2sz($1); } | continuations CONTINUATION { fprintf(stderr, "$1 : '%s'\n", szdata($1)); szcat($1, " "); fprintf(stderr, "$1+ : '%s'\n", szdata($1)); szcat($1, $2); $$ = $1; } body: LINE { $$ = str2sz($1); } | body LINE { $$ = szcat($1, $2); }