#pragma once #include #include #include #include "definition.hpp" #include "location.hh" #include "parser.hpp" struct parse_driver; void scanner_init(parse_driver* d, yyscan_t* scanner); 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_offset(0) {} void run_parse() { file_stream.open(file_name); if(!file_stream.good()) throw 0; 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(); } 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); } }; #define YY_DECL yy::parser::symbol_type yylex(yyscan_t yyscanner, parse_driver& drv) YY_DECL;