Switch to using FILE* and default YY_INPUT.
This commit is contained in:
parent
820a8bc5e9
commit
9a591d6da6
|
@ -37,6 +37,7 @@ add_executable(compiler
|
||||||
instruction.cpp instruction.hpp
|
instruction.cpp instruction.hpp
|
||||||
graph.cpp graph.hpp
|
graph.cpp graph.hpp
|
||||||
global_scope.cpp global_scope.hpp
|
global_scope.cpp global_scope.hpp
|
||||||
|
parse_driver.cpp parse_driver.hpp
|
||||||
${BISON_parser_OUTPUTS}
|
${BISON_parser_OUTPUTS}
|
||||||
${FLEX_scanner_OUTPUTS}
|
${FLEX_scanner_OUTPUTS}
|
||||||
main.cpp
|
main.cpp
|
||||||
|
|
55
13/parse_driver.cpp
Normal file
55
13/parse_driver.cpp
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
#include "parse_driver.hpp"
|
||||||
|
#include "scanner.hpp"
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
|
@ -13,7 +13,6 @@ 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::ostringstream string_stream;
|
std::ostringstream string_stream;
|
||||||
|
|
||||||
yy::location location;
|
yy::location location;
|
||||||
|
@ -21,58 +20,17 @@ struct parse_driver {
|
||||||
|
|
||||||
std::vector<size_t> line_offsets;
|
std::vector<size_t> line_offsets;
|
||||||
definition_group global_defs;
|
definition_group global_defs;
|
||||||
std::string read_file;
|
std::string file_contents;
|
||||||
|
|
||||||
parse_driver(const std::string& file)
|
parse_driver(const std::string& file)
|
||||||
: file_name(file), file_offset(0) {}
|
: file_name(file), file_offset(0) {}
|
||||||
|
|
||||||
bool run_parse() {
|
bool run_parse();
|
||||||
file_stream.open(file_name);
|
void write(const char* buff, size_t len);
|
||||||
if(!file_stream.good()) return false;
|
void mark_line();
|
||||||
line_offsets.push_back(0);
|
size_t get_index(int line, int column);
|
||||||
yyscan_t scanner;
|
size_t get_line_end(int line);
|
||||||
scanner_init(this, &scanner);
|
void print_highlighted_location(std::ostream& stream, const yy::location& loc);
|
||||||
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);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define YY_DECL yy::parser::symbol_type yylex(yyscan_t yyscanner, parse_driver& drv)
|
#define YY_DECL yy::parser::symbol_type yylex(yyscan_t yyscanner, parse_driver& drv)
|
||||||
|
|
18
13/scanner.l
18
13/scanner.l
|
@ -1,5 +1,6 @@
|
||||||
%option noyywrap
|
%option noyywrap
|
||||||
%option reentrant
|
%option reentrant
|
||||||
|
%option header-file="scanner.hpp"
|
||||||
|
|
||||||
%{
|
%{
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
@ -8,18 +9,12 @@
|
||||||
#include "parse_driver.hpp"
|
#include "parse_driver.hpp"
|
||||||
#include "parser.hpp"
|
#include "parser.hpp"
|
||||||
|
|
||||||
#define YY_EXTRA_TYPE parse_driver*
|
#define YY_USER_ACTION drv.write(yytext, yyleng); drv.location.step(); drv.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(); \
|
|
||||||
result = (c == EOF) ? YY_NULL : (buf[0] = c, 1); \
|
|
||||||
}
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
\n { drv.location.lines(); }
|
\n { drv.location.lines(); drv.mark_line(); }
|
||||||
[ ]+ {}
|
[ ]+ {}
|
||||||
\\ { return yy::parser::make_BACKSLASH(drv.location); }
|
\\ { return yy::parser::make_BACKSLASH(drv.location); }
|
||||||
\+ { return yy::parser::make_PLUS(drv.location); }
|
\+ { return yy::parser::make_PLUS(drv.location); }
|
||||||
|
@ -49,10 +44,3 @@ in { return yy::parser::make_IN(drv.location); }
|
||||||
<<EOF>> { return yy::parser::make_YYEOF(drv.location); }
|
<<EOF>> { 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);
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user