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
750static char *yy_strdup (const char *src)
851{
@@ -60,6 +103,43 @@ static char *yy_parse_string_literal(const char *src)
60103 buffer[out] = ' \0 ' ;
61104 return buffer;
62105}
106+
107+ static long long yy_parse_char_literal (const char *src)
108+ {
109+ size_t len = strlen (src);
110+ if (len < 3 || src[0 ] != ' \' ' || src[len - 1 ] != ' \' ' )
111+ {
112+ return 0 ;
113+ }
114+ if (src[1 ] != ' \\ ' )
115+ {
116+ return (unsigned char )src[1 ];
117+ }
118+ if (len < 4 )
119+ {
120+ return 0 ;
121+ }
122+ char esc = src[2 ];
123+ switch (esc)
124+ {
125+ case ' \\ ' :
126+ return ' \\ ' ;
127+ case ' \' ' :
128+ return ' \' ' ;
129+ case ' n' :
130+ return ' \n ' ;
131+ case ' r' :
132+ return ' \r ' ;
133+ case ' t' :
134+ return ' \t ' ;
135+ case ' 0' :
136+ return ' \0 ' ;
137+ case ' "' :
138+ return ' "' ;
139+ default :
140+ return (unsigned char )esc;
141+ }
142+ }
63143%}
64144
65145%option noyywrap nodefault noinput nounput
@@ -70,6 +150,7 @@ static char *yy_parse_string_literal(const char *src)
70150
71151[ \t\r\n ]+ { /* skip whitespace */ }
72152" int" { return KW_INT; }
153+ " char" { return KW_CHAR; }
73154" float" { return KW_FLOAT; }
74155" bool" { return KW_BOOL; }
75156" void" { return KW_VOID; }
@@ -78,8 +159,8 @@ static char *yy_parse_string_literal(const char *src)
78159" for" { return FOR; }
79160" true" { return TRUE ; }
80161" false" { return FALSE ; }
81- " \\ [" { return LBRACKET; }
82- " \\ ]" { return RBRACKET; }
162+ " \[ " { return LBRACKET; }
163+ " \] " { return RBRACKET; }
83164" //" [^ \n ]* { /* skip single line comments */ }
84165" /*" { BEGIN (COMMENT); }
85166<COMMENT >{
@@ -117,6 +198,7 @@ static char *yy_parse_string_literal(const char *src)
117198" {" { return LBRACE; }
118199" }" { return RBRACE; }
119200\" ([^ \"\n ]| \\ . )* \" { yylval.string = yy_parse_string_literal (yytext); return STRING_LITERAL; }
120- . { fprintf (stderr, " invalid character '%s'\n " , yytext); }
201+ '([^ \\ ' \n ]| \\ . )' { yylval.intValue = yy_parse_char_literal (yytext); return CHAR_LITERAL; }
202+ . { fprintf (stderr, " %s:%d:%d: invalid character '%s'\n " , lexer_get_source_name (), yy_token_line, yy_token_column, yytext); }
121203
122204%%
0 commit comments