1 /* Scanner for config specs -*- C -*- */
2 %option 8bit never-interactive yylineno
3 %option bison-bridge bison-locations
4 %option reentrant noyywrap
6 %option outfile="lex.yy.c" prefix="augl_"
9 /* config.h must precede flex's inclusion of <stdio.h>
10 in order for its _GNU_SOURCE definition to take effect. */
18 typedef struct info YYLTYPE;
19 #define YYLTYPE_IS_DECLARED 1
23 /* Advance of NUM lines. */
24 # define LOCATION_LINES(Loc, Num) \
25 (Loc).last_column = 0; \
26 (Loc).last_line += Num;
28 /* Restart: move the first cursor to the last position. */
29 # define LOCATION_STEP(Loc) \
30 (Loc).first_column = (Loc).last_column; \
31 (Loc).first_line = (Loc).last_line;
33 /* The lack of reference counting for filename is intentional */
34 #define YY_USER_ACTION \
36 yylloc->last_column += yyleng; \
37 yylloc->filename = augl_get_info(yyscanner)->filename; \
38 yylloc->error = augl_get_info(yyscanner)->error; \
41 #define YY_USER_INIT LOCATION_STEP(*yylloc)
43 #define YY_EXTRA_TYPE struct state *
45 int augl_init_lexer(struct state *state, yyscan_t * scanner);
46 void augl_close_lexer(yyscan_t *scanner);
47 struct info *augl_get_info(yyscan_t yyscanner);
49 static void loc_update(YYLTYPE *yylloc, const char *s, int len) {
50 for (int i=0; i < len; i++) {
52 LOCATION_LINES(*yylloc, 1);
57 static char *regexp_literal(const char *s, int len) {
58 char *u = unescape(s, len, RX_ESCAPES);
59 size_t u_len = strlen(u);
64 regexp_c_locale(&u, &u_len);
71 UID [A-Z][A-Za-z0-9_]*
72 LID [a-z_][A-Za-z0-9_]*
83 [ \t]* LOCATION_STEP(*yylloc);
84 \n+ LOCATION_LINES(*yylloc, yyleng); LOCATION_STEP(*yylloc);
85 (\r\n)+ LOCATION_LINES(*yylloc, yyleng/2); LOCATION_STEP(*yylloc);
91 loc_update(yylloc, yytext, yyleng);
92 yylval->string = unescape(yytext+1, yyleng-2, STR_ESCAPES);
97 loc_update(yylloc, yytext, yyleng);
98 yylval->regexp.nocase = 1;
99 yylval->regexp.pattern = regexp_literal(yytext+1, yyleng-3);
104 loc_update(yylloc, yytext, yyleng);
105 yylval->regexp.nocase = 0;
106 yylval->regexp.pattern = regexp_literal(yytext+1, yyleng-2);
110 [|*?+()=:;\.\[\]{}-] return yytext[0];
112 module return KW_MODULE;
114 {LETREC}/{WS} return KW_LET_REC;
117 string return KW_STRING;
118 regexp return KW_REGEXP;
121 autoload return KW_AUTOLOAD;
127 after return KW_AFTER;
129 {ARROW} return ARROW;
132 yylval->string = strndup(yytext, yyleng);
136 yylval->string = strndup(yytext, yyleng);
140 yylval->string = strndup(yytext, yyleng);
144 augl_get_extra(yyscanner)->comment_depth = 1;
148 report_error(augl_get_info(yyscanner)->error, AUG_ESYNTAX,
149 "%s:%d:%d: Unexpected character %c",
150 augl_get_info(yyscanner)->filename->str,
151 yylineno, yylloc->first_column, yytext[0]);
155 augl_close_lexer(yyscanner);
164 augl_get_extra(yyscanner)->comment_depth += 1;
167 augl_get_extra(yyscanner)->comment_depth -= 1;
168 if (augl_get_extra(yyscanner)->comment_depth == 0)
173 report_error(augl_get_info(yyscanner)->error, AUG_ESYNTAX,
174 "%s:%d:%d: Missing *)",
175 augl_get_info(yyscanner)->filename->str,
176 yylineno, yylloc->first_column);
177 augl_close_lexer(yyscanner);
183 void augl_close_lexer(yyscan_t *scanner) {
184 FILE *fp = augl_get_in(scanner);
188 augl_set_in(NULL, scanner);
192 int augl_init_lexer(struct state *state, yyscan_t *scanner) {
194 struct string *name = state->info->filename;
196 f = fopen(name->str, "r");
200 if (augl_lex_init(scanner) != 0) {
204 augl_set_extra(state, *scanner);
205 augl_set_in(f, *scanner);
209 struct info *augl_get_info(yyscan_t scanner) {
210 return augl_get_extra(scanner)->info;