Make driver keep track of line numbers and locations.
This commit is contained in:
parent
789f277780
commit
578d580683
|
@ -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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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); }
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user