/* csv.l */ /* disable unused functions so we don't get compiler warnings about them */ %option noyywrap nounput noinput /* change our prefix from yy to csv */ %option prefix="csv" /* use the pure parser calling convention */ %option reentrant bison-bridge bison-locations %{ #include "csv.tab.h" #define YY_EXIT_FAILURE ((void)yyscanner, EXIT_FAILURE) /* XOPEN for strdup */ #define _XOPEN_SOURCE 600 #include #include /* seems like a bug that I have to do this, since flex should know prefix=csv and match bison's CSVSTYPE */ #define YYSTYPE CSVSTYPE #define YYLTYPE CSVLTYPE %} %% \"([^"]|\"\")*\" { /* Update location */ yylloc->first_line = yylloc->last_line; yylloc->first_column = yylloc->last_column; yylloc->last_column += yyleng; /* yyleng is precomputed strlen(yytext) */ size_t i, n = yyleng; char *s; s = yylval->str = calloc(n, 1); if (!s) return FIELD; /* copy yytext, changing "" to " */ for (i = 1 /*skip 0="*/; i < n-1; i++) { *s++ = yytext[i]; if (yytext[i] == '"') i++; /* skip second one */ } return FIELD; } [^",\r\n]+ { /* Update location */ yylloc->first_line = yylloc->last_line; yylloc->first_column = yylloc->last_column; yylloc->last_column += yyleng; yylval->str = strdup(yytext); return FIELD; } \n|\r\n { /* Update location - newline resets column and increments line */ yylloc->first_line = yylloc->last_line; yylloc->first_column = yylloc->last_column; yylloc->last_line++; yylloc->last_column = 1; return CRLF; } . { /* Update location */ yylloc->first_line = yylloc->last_line; yylloc->first_column = yylloc->last_column; yylloc->last_column++; return *yytext; } %%