Switch to a custom source location type

This commit is contained in:
Nikita Lisitsa 2025-12-18 01:11:45 +03:00
parent 56c8214f36
commit 39de1cd73c
7 changed files with 80 additions and 22 deletions

View 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;
}
}

View file

@ -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}

View 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;
}; };

View file

@ -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_;
}; };
} }

View file

@ -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); }

View file

@ -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 {

View file

@ -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};