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_"
7 %option noinput nounput
10 /* config.h must precede flex's inclusion of <stdio.h>
11 in order for its _GNU_SOURCE definition to take effect. */
19 typedef struct info YYLTYPE;
20 #define YYLTYPE_IS_DECLARED 1
24 /* Advance of NUM lines. */
25 # define LOCATION_LINES(Loc, Num) \
26 (Loc).last_column = 0; \
27 (Loc).last_line += Num;
29 /* Restart: move the first cursor to the last position. */
30 # define LOCATION_STEP(Loc) \
31 (Loc).first_column = (Loc).last_column; \
32 (Loc).first_line = (Loc).last_line;
34 /* The lack of reference counting for filename is intentional */
35 #define YY_USER_ACTION \
37 yylloc->last_column += yyleng; \
38 yylloc->filename = augl_get_info(yyscanner)->filename; \
39 yylloc->error = augl_get_info(yyscanner)->error; \
42 #define YY_USER_INIT LOCATION_STEP(*yylloc)
44 #define YY_EXTRA_TYPE struct state *
46 int augl_init_lexer(struct state *state, yyscan_t * scanner);
47 void augl_close_lexer(yyscan_t *scanner);
48 struct info *augl_get_info(yyscan_t yyscanner);
50 static void loc_update(YYLTYPE *yylloc, const char *s, int len) {
51 for (int i=0; i < len; i++) {
53 LOCATION_LINES(*yylloc, 1);
58 static char *regexp_literal(const char *s, int len) {
59 char *u = unescape(s, len, RX_ESCAPES);
64 size_t u_len = strlen(u);
65 regexp_c_locale(&u, &u_len);
72 UID [A-Z][A-Za-z0-9_]*
73 LID [a-z_][A-Za-z0-9_]*
84 [ \t]* LOCATION_STEP(*yylloc);
85 \n+ LOCATION_LINES(*yylloc, yyleng); LOCATION_STEP(*yylloc);
86 (\r\n)+ LOCATION_LINES(*yylloc, yyleng/2); LOCATION_STEP(*yylloc);
91 \"([^\\\"]|\\(.|\n))*\" {
92 loc_update(yylloc, yytext, yyleng);
93 yylval->string = unescape(yytext+1, yyleng-2, STR_ESCAPES);
97 \/([^\\\/]|\\(.|\n))*\/i {
98 loc_update(yylloc, yytext, yyleng);
99 yylval->regexp.nocase = 1;
100 yylval->regexp.pattern = regexp_literal(yytext+1, yyleng-3);
104 \/([^\\\/]|\\(.|\n))*\/ {
105 loc_update(yylloc, yytext, yyleng);
106 yylval->regexp.nocase = 0;
107 yylval->regexp.pattern = regexp_literal(yytext+1, yyleng-2);
111 [|*?+()=:;\.\[\]{}-] return yytext[0];
113 module return KW_MODULE;
115 {LETREC}/{WS} return KW_LET_REC;
118 string return KW_STRING;
119 regexp return KW_REGEXP;
122 autoload return KW_AUTOLOAD;
128 after return KW_AFTER;
130 {ARROW} return ARROW;
133 yylval->string = strndup(yytext, yyleng);
137 yylval->string = strndup(yytext, yyleng);
141 yylval->string = strndup(yytext, yyleng);
145 augl_get_extra(yyscanner)->comment_depth = 1;
149 report_error(augl_get_info(yyscanner)->error, AUG_ESYNTAX,
150 "%s:%d:%d: Unexpected character %c",
151 augl_get_info(yyscanner)->filename->str,
152 yylineno, yylloc->first_column, yytext[0]);
156 augl_close_lexer(yyscanner);
165 augl_get_extra(yyscanner)->comment_depth += 1;
168 augl_get_extra(yyscanner)->comment_depth -= 1;
169 if (augl_get_extra(yyscanner)->comment_depth == 0)
174 report_error(augl_get_info(yyscanner)->error, AUG_ESYNTAX,
175 "%s:%d:%d: Missing *)",
176 augl_get_info(yyscanner)->filename->str,
177 yylineno, yylloc->first_column);
178 augl_close_lexer(yyscanner);
184 void augl_close_lexer(yyscan_t *scanner) {
185 FILE *fp = augl_get_in(scanner);
189 augl_set_in(NULL, scanner);
193 int augl_init_lexer(struct state *state, yyscan_t *scanner) {
195 struct string *name = state->info->filename;
197 f = fopen(name->str, "r");
201 if (augl_lex_init(scanner) != 0) {
205 augl_set_extra(state, *scanner);
206 augl_set_in(f, *scanner);
210 struct info *augl_get_info(yyscan_t scanner) {
211 return augl_get_extra(scanner)->info;