Skip to content

Commit de0ab9d

Browse files
committed
feat(lexer): add diagnostics with file:line:col
1 parent e6e4bf6 commit de0ab9d

File tree

9 files changed

+77
-10
lines changed

9 files changed

+77
-10
lines changed

src/codegen_lua.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,9 @@ static void emit_main_wrapper(FILE *out, const AstFunction *fn, const FunctionSi
9999
break;
100100
case TYPE_CHAR:
101101
fprintf(out, "local %s = args_table and args_table[%zu] and string.byte(args_table[%zu]) or 0\n",
102-
param->name,
103-
i + 1,
104-
i + 1);
102+
param->name,
103+
i + 1,
104+
i + 1);
105105
break;
106106
case TYPE_FLOAT:
107107
fprintf(out, "local %s = args_table and tonumber(args_table[%zu]) or 0.0\n", param->name, i + 1);

src/lexer.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#ifndef LEXER_H
2+
#define LEXER_H
3+
4+
const char *lexer_get_source_name(void);
5+
void lexer_set_source_name(const char *name);
6+
void lexer_reset_position(void);
7+
8+
extern int yy_line;
9+
extern int yy_column;
10+
extern int yy_token_line;
11+
extern int yy_token_column;
12+
13+
#endif

src/lexer.l

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,49 @@
33
#include <stdlib.h>
44
#include <string.h>
55
#include "parser.tab.h"
6+
#include "lexer.h"
7+
8+
int yy_line = 1;
9+
int yy_column = 1;
10+
int yy_token_line = 1;
11+
int yy_token_column = 1;
12+
static const char *yy_source_name = "<stdin>";
13+
14+
void lexer_set_source_name(const char *name)
15+
{
16+
yy_source_name = (name && *name) ? name : "<stdin>";
17+
}
18+
19+
const char *lexer_get_source_name(void)
20+
{
21+
return yy_source_name ? yy_source_name : "<stdin>";
22+
}
23+
24+
void lexer_reset_position(void)
25+
{
26+
yy_line = 1;
27+
yy_column = 1;
28+
yy_token_line = 1;
29+
yy_token_column = 1;
30+
}
31+
32+
#define YY_USER_ACTION \
33+
{ \
34+
yy_token_line = yy_line; \
35+
yy_token_column = yy_column; \
36+
for (int yy_i = 0; yy_i < yyleng; ++yy_i) \
37+
{ \
38+
if (yytext[yy_i] == '\n') \
39+
{ \
40+
yy_line++; \
41+
yy_column = 1; \
42+
} \
43+
else \
44+
{ \
45+
yy_column++; \
46+
} \
47+
} \
48+
}
649

750
static char *yy_strdup(const char *src)
851
{
@@ -156,6 +199,6 @@ static long long yy_parse_char_literal(const char *src)
156199
"}" { return RBRACE; }
157200
\"([^\"\n]|\\.)*\" { yylval.string = yy_parse_string_literal(yytext); return STRING_LITERAL; }
158201
'([^\\'\n]|\\.)' { yylval.intValue = yy_parse_char_literal(yytext); return CHAR_LITERAL; }
159-
. { fprintf(stderr, "invalid character '%s'\n", yytext); }
202+
. { fprintf(stderr, "%s:%d:%d: invalid character '%s'\n", lexer_get_source_name(), yy_token_line, yy_token_column, yytext); }
160203

161204
%%

src/main.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
#include "ast.h"
77
#include "codegen_lua.h"
8+
#include "lexer.h"
89
#include "optimizer.h"
910
#include "semantic.h"
1011
#include "parser.tab.h"
@@ -19,6 +20,10 @@ int main(int argc, char **argv)
1920
return EXIT_FAILURE;
2021
}
2122

23+
const char *source_name = (argc == 2) ? argv[1] : "<stdin>";
24+
lexer_set_source_name(source_name);
25+
lexer_reset_position();
26+
2227
AstProgram *program = c2lua_parse(input);
2328
if (!program)
2429
{

src/parser.y

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <string.h>
55

66
#include "ast.h"
7+
#include "lexer.h"
78

89
static AstProgram *make_program_with_function(AstFunction *fn);
910
int yyerror(AstProgram **out_program, const char *msg);
@@ -557,8 +558,13 @@ static void parser_error_cleanup(AstProgram **out_program)
557558

558559
int yyerror(AstProgram **out_program, const char *msg)
559560
{
560-
(void)out_program;
561-
fprintf(stderr, "syntax error: %s\n", msg);
561+
(void)out_program;
562+
fprintf(stderr,
563+
"%s:%d:%d: syntax error: %s\n",
564+
lexer_get_source_name(),
565+
yy_token_line,
566+
yy_token_column,
567+
msg ? msg : "unknown");
562568
return 0;
563569
}
564570

tests/fail/bad_if.err

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
syntax error: syntax error
1+
tests/fail/bad_if.c:4:2: syntax error: syntax error

tests/fail/int_plus_string.err

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
syntax error: syntax error
1+
tests/fail/int_plus_string.c:4:7: syntax error: syntax error

tests/fail/missing_return.err

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
syntax error: syntax error
1+
tests/fail/missing_return.c:4:5: syntax error: syntax error

tests/fail/wrong_assign.err

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
syntax error: syntax error
1+
tests/fail/wrong_assign.c:4:6: syntax error: syntax error

0 commit comments

Comments
 (0)