aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTeddy <ted.sybil@gmail.com>2014-03-26 03:12:31 +0800
committerTeddy <ted.sybil@gmail.com>2014-03-26 03:12:31 +0800
commitaf5df36aa343234c945fa6eae30d9bb03551e1a5 (patch)
treecf66d88a4c707d5fcac52cd89aa0759c7ca09742
parent2883565cc927fcc3de2297ed69500b8c59a4f625 (diff)
fancy error report
-rw-r--r--ast.c2
-rw-r--r--cibic.l28
-rw-r--r--main.c15
3 files changed, 34 insertions, 11 deletions
diff --git a/ast.c b/ast.c
index 97ab281..b76790e 100644
--- a/ast.c
+++ b/ast.c
@@ -371,7 +371,7 @@ char *cnode_debug_type_repr(CNode *ast) {
else
{
*aptr = '\0';
- sprintf(buffer, "%s:%s(%d,%d)", type, abuff,
+ sprintf(buffer, "%s:%s(%d:%d)", type, abuff,
ast->loc.row, ast->loc.col);
}
return buffer;
diff --git a/cibic.l b/cibic.l
index e857046..52ba764 100644
--- a/cibic.l
+++ b/cibic.l
@@ -1,11 +1,23 @@
%{
#include "cibic.tab.h"
+
int yycolumn = 1;
-#define YY_USER_ACTION \
- yylloc.first_line = yylloc.last_line = yylineno; \
- yylloc.first_column = yycolumn; yylloc.last_column = yycolumn + yyleng - 1; \
- yycolumn += yyleng;
+char linebuff[1024], *lptr = linebuff;
+#define YY_USER_ACTION \
+ do { \
+ yylloc.first_line = yylloc.last_line = yylineno; \
+ yylloc.first_column = yycolumn; yylloc.last_column = yycolumn + yyleng - 1; \
+ yycolumn += yyleng; \
+ memmove(lptr, yytext, yyleng); \
+ lptr += yyleng; \
+ } while (0);
+
+#define NEW_LINE_USER_ACTION \
+ do { \
+ yycolumn = 1; \
+ lptr = linebuff; \
+ } while (0)
%}
letter [a-zA-Z_$]
@@ -25,14 +37,14 @@ char ([^\n'\\]|\\.|\\[0-7]+|\\[xX][0-9a-fA-F]+)
"*/" BEGIN(INITIAL);
[^*\n]+ // eat comment in chunks
"*" // eat the lone star
-\n { yycolumn = 1; }
+\n { NEW_LINE_USER_ACTION; }
}
<INITIAL>{
"//" BEGIN(IN_INLINE_COMMENT);
}
<IN_INLINE_COMMENT>{
-\n { yycolumn = 1; BEGIN(INITIAL); }
+\n { NEW_LINE_USER_ACTION; BEGIN(INITIAL); }
[^\n]+
}
@@ -40,7 +52,7 @@ char ([^\n'\\]|\\.|\\[0-7]+|\\[xX][0-9a-fA-F]+)
"#" BEGIN(IN_DIRECTIVE);
}
<IN_DIRECTIVE>{
-\n { yycolumn = 1; BEGIN(INITIAL); }
+\n { NEW_LINE_USER_ACTION; BEGIN(INITIAL); }
[^\n]+
}
@@ -121,6 +133,6 @@ char ([^\n'\\]|\\.|\\[0-7]+|\\[xX][0-9a-fA-F]+)
[();,={}\[\]*|\^&<>+\-*//%~!.] { return *yytext; }
[ \t\r] /* skip whitespaces */
-\n { yycolumn = 1; }
+\n { NEW_LINE_USER_ACTION; }
. { return UNKNOWN; }
%%
diff --git a/main.c b/main.c
index 2e6fb35..d36dd6c 100644
--- a/main.c
+++ b/main.c
@@ -4,6 +4,8 @@
#include "cibic.tab.h"
#include "ast.h"
+extern char linebuff[];
+extern char *lptr;
extern int yyparse();
extern FILE *yyin;
char *fname;
@@ -12,8 +14,17 @@ int yywrap() {
return 1;
}
-int yyerror(char *s) {
- fprintf(stderr, "%s\n", s);
+void print_error(char *err_msg, int row, int col) {
+ *lptr = '\0';
+ fprintf(stderr, "%d:%d: %s\n%s\n",
+ row, col, err_msg, linebuff);
+ while (--col) putchar(' ');
+ putchar('^');
+}
+
+int yyerror(char *err_msg) {
+ print_error(err_msg,
+ yylloc.first_line, yylloc.first_column);
return 0;
}