diff --git a/code/compiler/13/CMakeLists.txt b/code/compiler/13/CMakeLists.txt index 851c568..3ddf289 100644 --- a/code/compiler/13/CMakeLists.txt +++ b/code/compiler/13/CMakeLists.txt @@ -37,6 +37,7 @@ add_executable(compiler instruction.cpp instruction.hpp graph.cpp graph.hpp global_scope.cpp global_scope.hpp + parse_driver.cpp parse_driver.hpp ${BISON_parser_OUTPUTS} ${FLEX_scanner_OUTPUTS} main.cpp diff --git a/code/compiler/13/parse_driver.cpp b/code/compiler/13/parse_driver.cpp new file mode 100644 index 0000000..971f844 --- /dev/null +++ b/code/compiler/13/parse_driver.cpp @@ -0,0 +1,55 @@ +#include "parse_driver.hpp" +#include "scanner.hpp" +#include + +bool parse_driver::run_parse() { + FILE* stream = fopen(file_name.c_str(), "r"); + if(!stream) return false; + string_stream = std::ostringstream(); + file_offset = 0; + line_offsets.push_back(0); + yyscan_t scanner; + yylex_init(&scanner); + yyset_in(stream, scanner); + yy::parser parser(scanner, *this); + parser(); + yylex_destroy(scanner); + fclose(stream); + file_contents = string_stream.str(); + return true; +} + +void parse_driver::write(const char* buf, size_t len) { + string_stream.write(buf, len); + file_offset += len; +} + +void parse_driver::mark_line() { + line_offsets.push_back(file_offset); +} + +size_t parse_driver::get_index(int line, int column) { + assert(line > 0); + assert(line <= line_offsets.size()); + size_t file_offset = line_offsets[line-1]; + file_offset += column - 1; + return file_offset; +} + +size_t parse_driver::get_line_end(int line) { + if(line > line_offsets.size()) return file_contents.size(); + return get_index(line+1, 1); +} + +void parse_driver::print_highlighted_location(std::ostream& stream, const yy::location& loc) { + size_t print_start = get_index(loc.begin.line, 1); + size_t highlight_start = get_index(loc.begin.line, loc.begin.column); + size_t highlight_end = get_index(loc.end.line, loc.end.column); + size_t print_end = get_line_end(loc.end.line); + const char* content = file_contents.c_str(); + stream.write(content + print_start, highlight_start - print_start); + stream << "\033[4;31m"; + stream.write(content + highlight_start, highlight_end - highlight_start); + stream << "\033[0m"; + stream.write(content + highlight_end, print_end - highlight_end); +} diff --git a/code/compiler/13/parse_driver.hpp b/code/compiler/13/parse_driver.hpp index a12b41b..14ffb8d 100644 --- a/code/compiler/13/parse_driver.hpp +++ b/code/compiler/13/parse_driver.hpp @@ -13,7 +13,6 @@ void scanner_destroy(yyscan_t* scanner); struct parse_driver { std::string file_name; - std::ifstream file_stream; std::ostringstream string_stream; yy::location location; @@ -21,58 +20,17 @@ struct parse_driver { std::vector line_offsets; definition_group global_defs; - std::string read_file; + std::string file_contents; parse_driver(const std::string& file) : file_name(file), file_offset(0) {} - bool run_parse() { - file_stream.open(file_name); - if(!file_stream.good()) return false; - line_offsets.push_back(0); - yyscan_t scanner; - scanner_init(this, &scanner); - yy::parser parser(scanner, *this); - parser(); - scanner_destroy(&scanner); - read_file = string_stream.str(); - return true; - } - - int 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 > 0); - assert(line <= line_offsets.size()); - size_t file_offset = line_offsets[line-1]; - file_offset += column - 1; - return file_offset; - } - - size_t get_line_end(int line) { - if(line > line_offsets.size()) return read_file.size(); - return get_index(line+1, 1); - } - - void print_highlighted_location(std::ostream& stream, const yy::location& loc) { - size_t print_start = get_index(loc.begin.line, 1); - size_t highlight_start = get_index(loc.begin.line, loc.begin.column); - size_t highlight_end = get_index(loc.end.line, loc.end.column); - size_t print_end = get_line_end(loc.end.line); - const char* content = read_file.c_str(); - stream.write(content + print_start, highlight_start - print_start); - stream << "\033[4;31m"; - stream.write(content + highlight_start, highlight_end - highlight_start); - stream << "\033[0m"; - stream.write(content + highlight_end, print_end - highlight_end); - } + bool run_parse(); + void write(const char* buff, size_t len); + void mark_line(); + size_t get_index(int line, int column); + size_t get_line_end(int line); + void print_highlighted_location(std::ostream& stream, const yy::location& loc); }; #define YY_DECL yy::parser::symbol_type yylex(yyscan_t yyscanner, parse_driver& drv) diff --git a/code/compiler/13/scanner.l b/code/compiler/13/scanner.l index ddd46da..e967d23 100644 --- a/code/compiler/13/scanner.l +++ b/code/compiler/13/scanner.l @@ -1,5 +1,6 @@ %option noyywrap %option reentrant +%option header-file="scanner.hpp" %{ #include @@ -8,18 +9,12 @@ #include "parse_driver.hpp" #include "parser.hpp" -#define YY_EXTRA_TYPE parse_driver* -#define YY_USER_ACTION drv.location.step(); drv.location.columns(yyleng); -#define YY_INPUT(buf,result,max_size) \ - { \ - int c = yyextra->get(); \ - result = (c == EOF) ? YY_NULL : (buf[0] = c, 1); \ - } +#define YY_USER_ACTION drv.write(yytext, yyleng); drv.location.step(); drv.location.columns(yyleng); %} %% -\n { drv.location.lines(); } +\n { drv.location.lines(); drv.mark_line(); } [ ]+ {} \\ { return yy::parser::make_BACKSLASH(drv.location); } \+ { return yy::parser::make_PLUS(drv.location); } @@ -49,10 +44,3 @@ in { return yy::parser::make_IN(drv.location); } <> { return yy::parser::make_YYEOF(drv.location); } %% - -void scanner_init(parse_driver* d, yyscan_t* scanner) { - yylex_init_extra(d, scanner); -} -void scanner_destroy(yyscan_t* scanner) { - yylex_destroy(*scanner); -}