From: Michael D. Lowis Date: Thu, 30 Oct 2014 14:45:47 +0000 (-0400) Subject: Added line and column data to tokens during lexical analysis X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=a87b4dd030d1e8a4e45cabe5e42a3c2de7d8b9fa;p=proto%2Fsclpl.git Added line and column data to tokens during lexical analysis --- diff --git a/source/sclpl/lexer.c b/source/sclpl/lexer.c index d498235..2bd31f5 100644 --- a/source/sclpl/lexer.c +++ b/source/sclpl/lexer.c @@ -10,7 +10,7 @@ #include #include -static lex_tok_t* lexer_make_token(char* text); +static lex_tok_t* lexer_make_token(size_t line, size_t col, char* text); static lex_tok_t* lexer_punc(char* text); static lex_tok_t* lexer_char(char* text); static lex_tok_t* lexer_radix_int(char* text); @@ -48,9 +48,11 @@ lexer_t* lexer_new(char* p_prompt, FILE* p_input) { lex_tok_t* lexer_read(lexer_t* p_lexer) { lex_tok_t* p_tok = NULL; - char* text = scanner_read(p_lexer->scanner); + size_t line; + size_t col; + char* text = scanner_read(p_lexer->scanner, &line, &col); if (NULL != text) { - p_tok = lexer_make_token(text); + p_tok = lexer_make_token(line, col, text); free(text); } return p_tok; @@ -60,7 +62,7 @@ void lexer_skipline(lexer_t* p_lexer) { scanner_getline(p_lexer->scanner); } -static lex_tok_t* lexer_make_token(char* text) { +static lex_tok_t* lexer_make_token(size_t line, size_t col, char* text) { lex_tok_t* p_tok = NULL; if (0 == strcmp(text,"end")) { p_tok = lex_tok_new(T_END, NULL); @@ -80,6 +82,11 @@ static lex_tok_t* lexer_make_token(char* text) { } else { p_tok = lexer_var(text); } + /* If we found a valid token then fill in the location details */ + if (NULL != p_tok) { + p_tok->line = line; + p_tok->col = col; + } return p_tok; } diff --git a/source/sclpl/lexer.h b/source/sclpl/lexer.h index 1f345e7..04fa117 100644 --- a/source/sclpl/lexer.h +++ b/source/sclpl/lexer.h @@ -25,7 +25,7 @@ typedef struct { lex_tok_type_t type; const char* file; size_t line; - size_t column; + size_t col; void* value; } lex_tok_t; diff --git a/source/sclpl/main.c b/source/sclpl/main.c index 7afc1fd..9b77876 100644 --- a/source/sclpl/main.c +++ b/source/sclpl/main.c @@ -240,7 +240,7 @@ str_t* token_file(str_t* in) { lexer_t* p_lexer = lexer_new(NULL, input); lex_tok_t* token; while(NULL != (token = lexer_read(p_lexer))) { - pprint_token(output, token); + pprint_token(output, token, true); mem_release(token); } mem_release(p_lexer); diff --git a/source/sclpl/pprint.c b/source/sclpl/pprint.c index 36bf2d8..6c3c146 100644 --- a/source/sclpl/pprint.c +++ b/source/sclpl/pprint.c @@ -69,8 +69,12 @@ void pprint_token_value(FILE* file, lex_tok_t* token) { } } -void pprint_token(FILE* file, lex_tok_t* token) +void pprint_token(FILE* file, lex_tok_t* token, bool print_loc) { + if (print_loc) { + fprintf(file, "%zu:", token->line); + fprintf(file, "%zu:", token->col); + } pprint_token_type(file, token); if (token->type < T_LBRACE) { fprintf(file, ":"); @@ -84,7 +88,7 @@ void pprint_tree(FILE* file, tree_t* tree, int depth) { print_indent(file, depth); if (tree->tag == ATOM) { - pprint_token(file, tree->ptr.tok); + pprint_token(file, tree->ptr.tok, false); } else { fputs("(tree", file); vec_t* p_vec = tree->ptr.vec; diff --git a/source/sclpl/pprint.h b/source/sclpl/pprint.h index 9d54159..2693ff4 100644 --- a/source/sclpl/pprint.h +++ b/source/sclpl/pprint.h @@ -14,7 +14,7 @@ void pprint_token_type(FILE* file, lex_tok_t* token); void pprint_token_value(FILE* file, lex_tok_t* token); -void pprint_token(FILE* file, lex_tok_t* token); +void pprint_token(FILE* file, lex_tok_t* token, bool print_loc); void pprint_tree(FILE* file, tree_t* tree, int depth); diff --git a/source/sclpl/scanner.c b/source/sclpl/scanner.c index 9db651b..5000534 100644 --- a/source/sclpl/scanner.c +++ b/source/sclpl/scanner.c @@ -17,14 +17,17 @@ scanner_t* scanner_new(char* p_prompt, FILE* p_file) { scanner_t* p_scanner = (scanner_t*)mem_allocate(sizeof(scanner_t), &scanner_free); p_scanner->p_line = NULL; p_scanner->index = 0; + p_scanner->line = 0; p_scanner->p_input = p_file; p_scanner->p_prompt = p_prompt; return p_scanner; } -char* scanner_read(scanner_t* p_scanner) { +char* scanner_read(scanner_t* p_scanner, size_t* line, size_t* column) { char* p_tok = NULL; scanner_skip_ws(p_scanner); + *line = p_scanner->line; + *column = p_scanner->index+1; if (!scanner_eof(p_scanner)) { if (scanner_oneof(p_scanner, "()[]{};,'")) { p_tok = scanner_dup(p_scanner, p_scanner->index, 1); @@ -126,6 +129,8 @@ void scanner_getline(scanner_t* p_scanner) { p_scanner->p_line[index++] = (c == EOF) ? '\0' : c; p_scanner->p_line[index++] = '\0'; p_scanner->index = 0; + /* Increment line count */ + p_scanner->line++; } } diff --git a/source/sclpl/scanner.h b/source/sclpl/scanner.h index 31afcea..1d05285 100644 --- a/source/sclpl/scanner.h +++ b/source/sclpl/scanner.h @@ -13,13 +13,14 @@ typedef struct { char* p_line; size_t index; + size_t line; FILE* p_input; char* p_prompt; } scanner_t; scanner_t* scanner_new(char* p_prompt, FILE* p_file); -char* scanner_read(scanner_t* p_scanner); +char* scanner_read(scanner_t* p_scanner, size_t* line, size_t* col); bool scanner_eof(scanner_t* p_scanner); diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 409f27a..6913d97 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -9,7 +9,7 @@ def cli(options, input = "") end def lexer(input) - cli(['--tokens'], input).scan(/^(T_[A-Z]+(:("[^"]*"|[^\n]+))?)/m).map {|m| m[0] } + cli(['--tokens'], input).scan(/^\d+:\d+:(T_[A-Z]+(:("[^"]*"|[^\n]+))?)/m).map {|m| m[0] } end def re_structure( token_array, offset = 0 )