]> begriffs open source - sa-parse/blob - src/csv.l
Track error locations
[sa-parse] / src / csv.l
1 /* csv.l */
2
3 /* disable unused functions so we don't
4    get compiler warnings about them */
5
6 %option noyywrap nounput noinput
7
8 /* change our prefix from yy to csv */
9
10 %option prefix="csv"
11
12 /* use the pure parser calling convention */
13
14 %option reentrant bison-bridge bison-locations
15
16 %{
17 #include "csv.tab.h"
18
19 #define YY_EXIT_FAILURE ((void)yyscanner, EXIT_FAILURE)
20
21 /* XOPEN for strdup */
22 #define _XOPEN_SOURCE 600
23 #include <stdlib.h>
24 #include <string.h>
25
26 /* seems like a bug that I have to do this, since flex
27    should know prefix=csv and match bison's CSVSTYPE */
28 #define YYSTYPE CSVSTYPE
29 #define YYLTYPE CSVLTYPE
30
31 %}
32
33 %%
34
35 \"([^"]|\"\")*\" {
36         /* Update location */
37         yylloc->first_line = yylloc->last_line;
38         yylloc->first_column = yylloc->last_column;
39         yylloc->last_column += yyleng;
40         
41         /* yyleng is precomputed strlen(yytext) */
42     size_t i, n = yyleng;
43     char *s;
44
45     s = yylval->str = calloc(n, 1);
46     if (!s)
47         return FIELD;
48
49         /* copy yytext, changing "" to " */
50     for (i = 1 /*skip 0="*/; i < n-1; i++)
51     {
52         *s++ = yytext[i];
53         if (yytext[i] == '"')
54             i++; /* skip second one */
55     }
56     return FIELD;
57 }
58
59 [^",\r\n]+ { 
60         /* Update location */
61         yylloc->first_line = yylloc->last_line;
62         yylloc->first_column = yylloc->last_column;
63         yylloc->last_column += yyleng;
64         
65         yylval->str = strdup(yytext); 
66         return FIELD; 
67 }
68
69 \n|\r\n    { 
70         /* Update location - newline resets column and increments line */
71         yylloc->first_line = yylloc->last_line;
72         yylloc->first_column = yylloc->last_column;
73         yylloc->last_line++;
74         yylloc->last_column = 1;
75         
76         return CRLF; 
77 }
78
79 .          { 
80         /* Update location */
81         yylloc->first_line = yylloc->last_line;
82         yylloc->first_column = yylloc->last_column;
83         yylloc->last_column++;
84         
85         return *yytext; 
86 }
87
88 %%