Switch to a custom source location type
This commit is contained in:
parent
56c8214f36
commit
39de1cd73c
7 changed files with 80 additions and 22 deletions
59
libs/ast/include/pslang/ast/location.hpp
Normal file
59
libs/ast/include/pslang/ast/location.hpp
Normal file
|
|
@ -0,0 +1,59 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string_view>
|
||||||
|
#include <ostream>
|
||||||
|
|
||||||
|
namespace pslang::ast
|
||||||
|
{
|
||||||
|
|
||||||
|
struct location
|
||||||
|
{
|
||||||
|
struct position
|
||||||
|
{
|
||||||
|
std::size_t line = 1;
|
||||||
|
std::size_t column = 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::string_view filename;
|
||||||
|
position begin = {};
|
||||||
|
position end = {};
|
||||||
|
|
||||||
|
void step()
|
||||||
|
{
|
||||||
|
begin = end;
|
||||||
|
}
|
||||||
|
|
||||||
|
void move_lines(std::size_t count)
|
||||||
|
{
|
||||||
|
if (count > 0)
|
||||||
|
{
|
||||||
|
end.column = 1;
|
||||||
|
end.line = add(end.line, count, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void move_columns(std::size_t count)
|
||||||
|
{
|
||||||
|
end.column = add(end.column, count, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::size_t add(std::size_t lhs, std::size_t rhs, std::size_t min)
|
||||||
|
{
|
||||||
|
return lhs + rhs < min ? min : lhs + rhs;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
inline std::ostream & operator << (std::ostream & out, location const & location)
|
||||||
|
{
|
||||||
|
out << location.filename << ':' << location.begin.line << '.' << location.begin.column;
|
||||||
|
|
||||||
|
std::size_t end_column = std::max<std::size_t>(1, location.end.column) - 1;
|
||||||
|
if (location.begin.line < location.end.line)
|
||||||
|
out << '-' << location.end.line << '.' << end_column;
|
||||||
|
else if (location.begin.column < end_column)
|
||||||
|
out << '-' << end_column;
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -10,8 +10,6 @@ set(PSLANG_LEXER_SOURCE_FILE "${CMAKE_CURRENT_BINARY_DIR}/generated/gen_lexer.cp
|
||||||
set(PSLANG_PARSER_HEADER_FILE "${CMAKE_CURRENT_BINARY_DIR}/generated/gen_parser.hpp")
|
set(PSLANG_PARSER_HEADER_FILE "${CMAKE_CURRENT_BINARY_DIR}/generated/gen_parser.hpp")
|
||||||
set(PSLANG_PARSER_SOURCE_FILE "${CMAKE_CURRENT_BINARY_DIR}/generated/gen_parser.cpp")
|
set(PSLANG_PARSER_SOURCE_FILE "${CMAKE_CURRENT_BINARY_DIR}/generated/gen_parser.cpp")
|
||||||
|
|
||||||
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/generated/pslang/parser")
|
|
||||||
|
|
||||||
flex_target(
|
flex_target(
|
||||||
generate-pslang-lexer
|
generate-pslang-lexer
|
||||||
${PSLANG_LEXER_RULES_FILE}
|
${PSLANG_LEXER_RULES_FILE}
|
||||||
|
|
|
||||||
|
|
@ -2,19 +2,19 @@
|
||||||
|
|
||||||
#include <pslang/parser/indented_statement.hpp>
|
#include <pslang/parser/indented_statement.hpp>
|
||||||
|
|
||||||
|
namespace pslang::ast
|
||||||
|
{
|
||||||
|
|
||||||
|
struct location;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
namespace pslang::parser
|
namespace pslang::parser
|
||||||
{
|
{
|
||||||
|
|
||||||
namespace bison
|
|
||||||
{
|
|
||||||
|
|
||||||
class location;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
struct context
|
struct context
|
||||||
{
|
{
|
||||||
bison::location & location;
|
ast::location & location;
|
||||||
indented_statement_list & result;
|
indented_statement_list & result;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <pslang/parser/location.hpp>
|
#include <pslang/ast/location.hpp>
|
||||||
|
|
||||||
#include <exception>
|
#include <exception>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace pslang::parser
|
namespace pslang::parser
|
||||||
{
|
{
|
||||||
|
|
@ -10,13 +11,12 @@ namespace pslang::parser
|
||||||
struct parse_error
|
struct parse_error
|
||||||
: std::exception
|
: std::exception
|
||||||
{
|
{
|
||||||
parse_error(std::string message, bison::location location)
|
parse_error(std::string message, ast::location location)
|
||||||
: message_(std::move(message))
|
: message_(std::move(message))
|
||||||
, filename_(*location.begin.filename)
|
, filename_(location.filename)
|
||||||
, location_(location)
|
, location_(location)
|
||||||
{
|
{
|
||||||
location_.begin.filename = &filename_;
|
location_.filename = filename_;
|
||||||
location_.end.filename = &filename_;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char const * what() const noexcept
|
char const * what() const noexcept
|
||||||
|
|
@ -24,7 +24,7 @@ namespace pslang::parser
|
||||||
return message_.c_str();
|
return message_.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
bison::location location() const noexcept
|
ast::location location() const noexcept
|
||||||
{
|
{
|
||||||
return location_;
|
return location_;
|
||||||
}
|
}
|
||||||
|
|
@ -32,7 +32,7 @@ namespace pslang::parser
|
||||||
private:
|
private:
|
||||||
std::string message_;
|
std::string message_;
|
||||||
std::string filename_;
|
std::string filename_;
|
||||||
bison::location location_;
|
ast::location location_;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
using bp = ::pslang::parser::bison::parser;
|
using bp = ::pslang::parser::bison::parser;
|
||||||
|
|
||||||
#define YY_DECL bp::symbol_type yylex(::pslang::parser::context& ctx)
|
#define YY_DECL bp::symbol_type yylex(::pslang::parser::context& ctx)
|
||||||
#define YY_USER_ACTION ctx.location.columns(yyleng);
|
#define YY_USER_ACTION ctx.location.move_columns(yyleng);
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
|
@ -49,7 +49,7 @@ f64 { return bp::make_f64(ctx.location); }
|
||||||
|
|
||||||
[a-zA-Z_]+[a-zA-Z0-9_]* { return bp::make_name(yytext, ctx.location); }
|
[a-zA-Z_]+[a-zA-Z0-9_]* { return bp::make_name(yytext, ctx.location); }
|
||||||
|
|
||||||
"\n" { ctx.location.lines(1); return bp::make_newline(ctx.location); }
|
"\n" { ctx.location.move_lines(1); return bp::make_newline(ctx.location); }
|
||||||
"\t" { return bp::make_indent(ctx.location); }
|
"\t" { return bp::make_indent(ctx.location); }
|
||||||
"=" { return bp::make_assignment(ctx.location); }
|
"=" { return bp::make_assignment(ctx.location); }
|
||||||
":" { return bp::make_colon(ctx.location); }
|
":" { return bp::make_colon(ctx.location); }
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,7 @@
|
||||||
|
|
||||||
%language "C++"
|
%language "C++"
|
||||||
%define api.namespace {pslang::parser::bison}
|
%define api.namespace {pslang::parser::bison}
|
||||||
%define api.location.file "pslang/parser/location.hpp"
|
%define api.location.type { ::pslang::ast::location }
|
||||||
%define api.location.include "<pslang/parser/location.hpp>"
|
|
||||||
|
|
||||||
%define api.token.raw
|
%define api.token.raw
|
||||||
%define api.token.constructor
|
%define api.token.constructor
|
||||||
|
|
@ -33,6 +32,7 @@ void yyerror(char const * s)
|
||||||
%code requires {
|
%code requires {
|
||||||
|
|
||||||
#include <pslang/ast/statement.hpp>
|
#include <pslang/ast/statement.hpp>
|
||||||
|
#include <pslang/ast/location.hpp>
|
||||||
#include <pslang/parser/indented_statement.hpp>
|
#include <pslang/parser/indented_statement.hpp>
|
||||||
|
|
||||||
namespace pslang::parser {
|
namespace pslang::parser {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#include <pslang/parser/parser.hpp>
|
#include <pslang/parser/parser.hpp>
|
||||||
#include <pslang/parser/context.hpp>
|
#include <pslang/parser/context.hpp>
|
||||||
#include <pslang/parser/indented_statement.hpp>
|
#include <pslang/parser/indented_statement.hpp>
|
||||||
|
#include <pslang/ast/location.hpp>
|
||||||
#include "gen_parser.hpp"
|
#include "gen_parser.hpp"
|
||||||
#include "gen_lexer.hpp"
|
#include "gen_lexer.hpp"
|
||||||
|
|
||||||
|
|
@ -15,7 +16,7 @@ namespace pslang::parser
|
||||||
if (!yyin)
|
if (!yyin)
|
||||||
throw std::system_error(std::make_error_code(static_cast<std::errc>(errno)));
|
throw std::system_error(std::make_error_code(static_cast<std::errc>(errno)));
|
||||||
|
|
||||||
bison::location location(&filename);
|
ast::location location{filename};
|
||||||
indented_statement_list result;
|
indented_statement_list result;
|
||||||
context ctx{location, result};
|
context ctx{location, result};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue