Make driver keep track of line numbers and locations.

This commit is contained in:
Danila Fedorin 2020-09-09 13:57:01 -07:00
parent 789f277780
commit 578d580683
2 changed files with 47 additions and 28 deletions

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <string> #include <string>
#include <fstream> #include <fstream>
#include <sstream>
#include "definition.hpp" #include "definition.hpp"
#include "location.hh" #include "location.hh"
#include "parser.hpp" #include "parser.hpp"
@ -13,15 +14,17 @@ void scanner_destroy(yyscan_t* scanner);
struct parse_driver { struct parse_driver {
std::string file_name; std::string file_name;
std::ifstream file_stream; std::ifstream file_stream;
std::ostringstream string_stream;
yy::location location; yy::location location;
size_t file_offset; size_t file_offset;
std::vector<size_t> line_offsets; std::vector<size_t> line_offsets;
definition_group global_defs; definition_group global_defs;
std::string read_file;
parse_driver(const std::string& file) parse_driver(const std::string& file)
: file_name(file) {} : file_name(file), file_offset(0) {}
void run_parse() { void run_parse() {
file_stream.open(file_name); file_stream.open(file_name);
@ -31,10 +34,28 @@ struct parse_driver {
yy::parser parser(scanner, *this); yy::parser parser(scanner, *this);
parser(); parser();
scanner_destroy(&scanner); scanner_destroy(&scanner);
read_file = string_stream.str();
} }
int get() { 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;
} }
}; };

View File

@ -8,10 +8,8 @@
#include "parse_driver.hpp" #include "parse_driver.hpp"
#include "parser.hpp" #include "parser.hpp"
yy::parser::location_type location;
#define YY_EXTRA_TYPE parse_driver* #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) \ #define YY_INPUT(buf,result,max_size) \
{ \ { \
int c = yyextra->get(); \ 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_BACKSLASH(drv.location); }
\+ { return yy::parser::make_PLUS(location); } \+ { return yy::parser::make_PLUS(drv.location); }
\* { return yy::parser::make_TIMES(location); } \* { return yy::parser::make_TIMES(drv.location); }
- { return yy::parser::make_MINUS(location); } - { return yy::parser::make_MINUS(drv.location); }
\/ { return yy::parser::make_DIVIDE(location); } \/ { return yy::parser::make_DIVIDE(drv.location); }
[0-9]+ { return yy::parser::make_INT(atoi(yytext), location); } [0-9]+ { return yy::parser::make_INT(atoi(yytext), drv.location); }
defn { return yy::parser::make_DEFN(location); } defn { return yy::parser::make_DEFN(drv.location); }
data { return yy::parser::make_DATA(location); } data { return yy::parser::make_DATA(drv.location); }
case { return yy::parser::make_CASE(location); } case { return yy::parser::make_CASE(drv.location); }
of { return yy::parser::make_OF(location); } of { return yy::parser::make_OF(drv.location); }
let { return yy::parser::make_LET(location); } let { return yy::parser::make_LET(drv.location); }
in { return yy::parser::make_IN(location); } in { return yy::parser::make_IN(drv.location); }
\{ { return yy::parser::make_OCURLY(location); } \{ { return yy::parser::make_OCURLY(drv.location); }
\} { return yy::parser::make_CCURLY(location); } \} { return yy::parser::make_CCURLY(drv.location); }
\( { return yy::parser::make_OPAREN(location); } \( { return yy::parser::make_OPAREN(drv.location); }
\) { return yy::parser::make_CPAREN(location); } \) { return yy::parser::make_CPAREN(drv.location); }
, { return yy::parser::make_COMMA(location); } , { return yy::parser::make_COMMA(drv.location); }
-> { return yy::parser::make_ARROW(location); } -> { return yy::parser::make_ARROW(drv.location); }
= { return yy::parser::make_EQUAL(location); } = { return yy::parser::make_EQUAL(drv.location); }
[a-z][a-zA-Z]* { return yy::parser::make_LID(std::string(yytext), 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), location); } [A-Z][a-zA-Z]* { return yy::parser::make_UID(std::string(yytext), drv.location); }
<<EOF>> { return yy::parser::make_YYEOF(location); } <<EOF>> { return yy::parser::make_YYEOF(drv.location); }
%% %%