From 578d58068301e0507596685d06a381815d82c553 Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Wed, 9 Sep 2020 13:57:01 -0700 Subject: [PATCH] Make driver keep track of line numbers and locations. --- code/compiler/13/parse_driver.hpp | 25 ++++++++++++++-- code/compiler/13/scanner.l | 50 +++++++++++++++---------------- 2 files changed, 47 insertions(+), 28 deletions(-) diff --git a/code/compiler/13/parse_driver.hpp b/code/compiler/13/parse_driver.hpp index a00c586..580e250 100644 --- a/code/compiler/13/parse_driver.hpp +++ b/code/compiler/13/parse_driver.hpp @@ -1,6 +1,7 @@ #pragma once #include #include +#include #include "definition.hpp" #include "location.hh" #include "parser.hpp" @@ -13,15 +14,17 @@ void scanner_destroy(yyscan_t* scanner); struct parse_driver { std::string file_name; std::ifstream file_stream; + std::ostringstream string_stream; yy::location location; size_t file_offset; std::vector line_offsets; definition_group global_defs; + std::string read_file; parse_driver(const std::string& file) - : file_name(file) {} + : file_name(file), file_offset(0) {} void run_parse() { file_stream.open(file_name); @@ -31,10 +34,28 @@ struct parse_driver { yy::parser parser(scanner, *this); parser(); scanner_destroy(&scanner); + read_file = string_stream.str(); } int get() { - return file_stream.get(); + int new_char = file_stream.get(); + if(new_char == EOF) return EOF; + file_offset++; + if(new_char == '\n') line_offsets.push_back(file_offset); + string_stream.put(new_char); + return new_char; + } + + size_t get_index(int line, int column) { + assert(line-1 < line_offsets.size()); + size_t file_offset = line ? 0 : line_offsets[line-1]; + file_offset += column - 1; + return file_offset; + } + + size_t get_line_end(int line) { + assert(line < line_offsets.size()); + return line_offsets[line] - 1; } }; diff --git a/code/compiler/13/scanner.l b/code/compiler/13/scanner.l index e409014..6f201c5 100644 --- a/code/compiler/13/scanner.l +++ b/code/compiler/13/scanner.l @@ -8,10 +8,8 @@ #include "parse_driver.hpp" #include "parser.hpp" -yy::parser::location_type location; - #define YY_EXTRA_TYPE parse_driver* -#define YY_USER_ACTION location.step(); location.columns(yyleng); +#define YY_USER_ACTION drv.location.step(); drv.location.columns(yyleng); #define YY_INPUT(buf,result,max_size) \ { \ int c = yyextra->get(); \ @@ -21,30 +19,30 @@ yy::parser::location_type location; %% -\n { location.lines(); } +\n { drv.location.lines(); } [ ]+ {} -\\ { return yy::parser::make_BACKSLASH(location); } -\+ { return yy::parser::make_PLUS(location); } -\* { return yy::parser::make_TIMES(location); } -- { return yy::parser::make_MINUS(location); } -\/ { return yy::parser::make_DIVIDE(location); } -[0-9]+ { return yy::parser::make_INT(atoi(yytext), location); } -defn { return yy::parser::make_DEFN(location); } -data { return yy::parser::make_DATA(location); } -case { return yy::parser::make_CASE(location); } -of { return yy::parser::make_OF(location); } -let { return yy::parser::make_LET(location); } -in { return yy::parser::make_IN(location); } -\{ { return yy::parser::make_OCURLY(location); } -\} { return yy::parser::make_CCURLY(location); } -\( { return yy::parser::make_OPAREN(location); } -\) { return yy::parser::make_CPAREN(location); } -, { return yy::parser::make_COMMA(location); } --> { return yy::parser::make_ARROW(location); } -= { return yy::parser::make_EQUAL(location); } -[a-z][a-zA-Z]* { return yy::parser::make_LID(std::string(yytext), location); } -[A-Z][a-zA-Z]* { return yy::parser::make_UID(std::string(yytext), location); } -<> { return yy::parser::make_YYEOF(location); } +\\ { return yy::parser::make_BACKSLASH(drv.location); } +\+ { return yy::parser::make_PLUS(drv.location); } +\* { return yy::parser::make_TIMES(drv.location); } +- { return yy::parser::make_MINUS(drv.location); } +\/ { return yy::parser::make_DIVIDE(drv.location); } +[0-9]+ { return yy::parser::make_INT(atoi(yytext), drv.location); } +defn { return yy::parser::make_DEFN(drv.location); } +data { return yy::parser::make_DATA(drv.location); } +case { return yy::parser::make_CASE(drv.location); } +of { return yy::parser::make_OF(drv.location); } +let { return yy::parser::make_LET(drv.location); } +in { return yy::parser::make_IN(drv.location); } +\{ { return yy::parser::make_OCURLY(drv.location); } +\} { return yy::parser::make_CCURLY(drv.location); } +\( { return yy::parser::make_OPAREN(drv.location); } +\) { return yy::parser::make_CPAREN(drv.location); } +, { return yy::parser::make_COMMA(drv.location); } +-> { return yy::parser::make_ARROW(drv.location); } += { return yy::parser::make_EQUAL(drv.location); } +[a-z][a-zA-Z]* { return yy::parser::make_LID(std::string(yytext), drv.location); } +[A-Z][a-zA-Z]* { return yy::parser::make_UID(std::string(yytext), drv.location); } +<> { return yy::parser::make_YYEOF(drv.location); } %%