Quellcode durchsuchen

[lexer.h] Adding error reporing to lexer_next_token

Vinicius Teshima vor 1 Jahr
Ursprung
Commit
9df9b4243d
2 geänderte Dateien mit 51 neuen und 10 gelöschten Zeilen
  1. 2 3
      src/cint.c
  2. 49 7
      src/lexer.h

+ 2 - 3
src/cint.c

@@ -47,9 +47,8 @@ main(int argc, const char *argv[])
 	str = str_from_cstr(src, src_size);
 
 	l = lexer_create(str);
-	t = lexer_next_token(&l);
-	for ( ; t.typ.code != TT_EOF; t = lexer_next_token(&l) ) {
-		printf("%ld -> %s\n", ts_size, t.typ.name);
+	t = lexer_next_token(&l, NULL);
+	for ( ; t.typ.code != TT_EOF; t = lexer_next_token(&l, NULL) ) {
 		ts[ts_size++] = t;
 	}
 

+ 49 - 7
src/lexer.h

@@ -13,10 +13,20 @@ struct lexer {
 	char c;
 };
 
+enum lexer_err_code {
+	LEXER_ERR_OK = 0,
+	LEXER_ERR_INVALID_PP_IDENT
+};
+
+struct lexer_err {
+	enum lexer_err_code code;
+	const char *name;
+};
+
 struct lexer lexer_create(struct str in);
 void lexer_read_char(struct lexer *l);
 
-struct token lexer_next_token(struct lexer *l);
+struct token lexer_next_token(struct lexer *l, struct lexer_err *err);
 
 struct str lexer_read_ident(struct lexer *l);
 struct str lexer_read_str_lit(struct lexer *l);
@@ -26,8 +36,11 @@ enum token_type_enum lexer_lookup_ident(struct str ident);
 enum token_type_enum lexer_lookup_pp(struct str ident);
 void lexer_skip_whitespace(struct lexer *l);
 
+struct lexer_err lexer_err_create(enum lexer_err_code code);
+
 bool _lexer_is_letter(char c);
 bool _lexer_is_number(char c);
+void _lexer_set_err(struct lexer_err *err, enum lexer_err_code code);
 
 #if defined(IMP) || defined(LEXER_IMP)
 
@@ -53,7 +66,7 @@ lexer_read_char(struct lexer *l)
 }
 
 struct token 
-lexer_next_token(struct lexer *l)
+lexer_next_token(struct lexer *l, struct lexer_err *err)
 {
 #define _LEXER_CUR_CHAR str_slice(l->in, l->pos, l->pos+1)
 
@@ -81,11 +94,14 @@ lexer_next_token(struct lexer *l)
 		if ( _lexer_is_letter(l->c) ) {
 			struct str ident = lexer_read_ident(l);
 			t = token_create(lexer_lookup_pp(ident), ident);
+			if ( t.typ.code == TT_ILLEGAL ) {
+				goto invalid_pp;
+			}
 			return t;
 		}
-		if ( _lexer_is_number(l->c) ) {
-			return token_create(TT_INT_LIT, lexer_read_int_lit(l));
-		}
+invalid_pp:
+		_lexer_set_err(err, LEXER_ERR_INVALID_PP_IDENT);
+		return TOKEN_ILLEGAL;
 		break;
 	case '"':
 		t = token_create(TT_STR_LIT, lexer_read_str_lit(l));
@@ -189,7 +205,7 @@ enum token_type_enum
 lexer_lookup_pp(struct str ident)
 {
 	if ( ident.size < 2 ) {
-		return TT_IDENT;
+		return TT_ILLEGAL;
 	}
 
 	switch ( ident.size ) {
@@ -218,7 +234,7 @@ lexer_lookup_pp(struct str ident)
 		break;
 	}
 
-	return TT_IDENT;
+	return TT_ILLEGAL;
 }
 
 void 
@@ -237,6 +253,22 @@ loop:
 	return;
 }
 
+struct lexer_err
+lexer_err_create(enum lexer_err_code code)
+{
+#define _LEXER_ERR_CASE(it) case it: le.name = #it; break;
+	struct lexer_err le = {0};
+	le.code = code;
+
+	switch ( code ) {
+	_LEXER_ERR_CASE(LEXER_ERR_OK);
+	_LEXER_ERR_CASE(LEXER_ERR_INVALID_PP_IDENT);
+	}
+
+	return le;
+#undef _LEXER_ERR_CASE
+}
+
 bool
 _lexer_is_letter(char c)
 {
@@ -251,6 +283,16 @@ _lexer_is_number(char c)
 	return ( c >= '0' && c <= '9' );
 }
 
+void
+_lexer_set_err(struct lexer_err *err, enum lexer_err_code code)
+{
+	if ( err == NULL ) {
+		return;
+	}
+
+	*err = lexer_err_create(code);
+}
+
 #endif /* defined(IMP) || defined(LEXER_IMP) */
 
 #endif /* LEXER_H */