summaryrefslogtreecommitdiff
path: root/src/nsgenbind-lexer.l
diff options
context:
space:
mode:
authorVincent Sanders <vince@kyllikki.org>2015-09-28 00:06:47 +0100
committerVincent Sanders <vince@kyllikki.org>2015-09-28 00:06:47 +0100
commit767e69459ca7b4c13fe93875177040ab3eec8b56 (patch)
tree349e255c7c370594edfda939dc19cf6fe7247270 /src/nsgenbind-lexer.l
parent017eb2ef4da167466c05ad83eb0714129a2e46ff (diff)
downloadnsgenbind-767e69459ca7b4c13fe93875177040ab3eec8b56.tar.gz
nsgenbind-767e69459ca7b4c13fe93875177040ab3eec8b56.tar.bz2
Improve the parser error reporting
The parser now reports the correct file and line number for errors. Additionally the @n location structure in rules now has a filename member in addition to first_line. These members are useful for adding location information in generated source.
Diffstat (limited to 'src/nsgenbind-lexer.l')
-rw-r--r--src/nsgenbind-lexer.l55
1 files changed, 48 insertions, 7 deletions
diff --git a/src/nsgenbind-lexer.l b/src/nsgenbind-lexer.l
index f32a948..af77368 100644
--- a/src/nsgenbind-lexer.l
+++ b/src/nsgenbind-lexer.l
@@ -15,9 +15,10 @@
#include "nsgenbind-parser.h"
#include "nsgenbind-ast.h"
-#define YY_USER_ACTION yylloc->first_line = yylloc->last_line; \
- yylloc->first_column = yylloc->last_column + 1; \
- yylloc->last_column += yyleng;
+#define YY_USER_ACTION \
+ yylloc->first_line = yylloc->last_line = yylineno; \
+ yylloc->first_column = yylloc->last_column + 1; \
+ yylloc->last_column += yyleng;
/* Ensure compatability with bison 2.6 and later */
@@ -29,6 +30,43 @@
#define YYLTYPE NSGENBIND_LTYPE
#endif
+static struct YYLTYPE *locations = NULL;
+
+static struct YYLTYPE *push_location(struct YYLTYPE *head,
+ struct YYLTYPE *loc,
+ const char *filename)
+{
+ struct YYLTYPE *res;
+ res = calloc(1, sizeof(struct YYLTYPE));
+ /* copy current location and line number */
+ *res = *loc;
+ res->start_line = yylineno;
+ res->next = head;
+
+ /* reset current location */
+ loc->first_line = loc->last_line = 1;
+ loc->first_column = loc->last_column = 1;
+ loc->filename = strdup(filename);
+ yylineno = 1;
+
+ return res;
+}
+
+static struct YYLTYPE *pop_location(struct YYLTYPE *head, struct YYLTYPE *loc)
+{
+ struct YYLTYPE *res = NULL;
+
+ if (head != NULL) {
+ res = head->next;
+ *loc = *head;
+ free(head);
+
+ yylineno = loc->start_line;
+ }
+ return res;
+}
+
+
%}
/* lexer options */
@@ -165,8 +203,10 @@ unsigned return TOK_UNSIGNED;
fprintf(stderr, "Unable to open include %s\n", yytext);
exit(3);
}
- yypush_buffer_state(yy_create_buffer( yyin, YY_BUF_SIZE ));
-
+
+ locations = push_location(locations, yylloc, yytext);
+
+ yypush_buffer_state(yy_create_buffer(yyin, YY_BUF_SIZE));
BEGIN(INITIAL);
}
@@ -178,9 +218,10 @@ unsigned return TOK_UNSIGNED;
yypop_buffer_state();
if ( !YY_CURRENT_BUFFER ) {
- yyterminate();
+ yyterminate();
} else {
- BEGIN(incl);
+ locations = pop_location(locations, yylloc);
+ BEGIN(incl);
}
}