From 39de1cd73cc95fbd37bb14759928a941543db6ce Mon Sep 17 00:00:00 2001 From: lisyarus Date: Thu, 18 Dec 2025 01:11:45 +0300 Subject: [PATCH] Switch to a custom source location type --- libs/ast/include/pslang/ast/location.hpp | 59 +++++++++++++++++++ libs/parser/CMakeLists.txt | 2 - libs/parser/include/pslang/parser/context.hpp | 16 ++--- libs/parser/include/pslang/parser/error.hpp | 14 ++--- libs/parser/rules/pslang.l | 4 +- libs/parser/rules/pslang.y | 4 +- libs/parser/source/parser.cpp | 3 +- 7 files changed, 80 insertions(+), 22 deletions(-) create mode 100644 libs/ast/include/pslang/ast/location.hpp diff --git a/libs/ast/include/pslang/ast/location.hpp b/libs/ast/include/pslang/ast/location.hpp new file mode 100644 index 0000000..fe79f09 --- /dev/null +++ b/libs/ast/include/pslang/ast/location.hpp @@ -0,0 +1,59 @@ +#pragma once + +#include +#include + +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(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; + } + +} diff --git a/libs/parser/CMakeLists.txt b/libs/parser/CMakeLists.txt index e48f5ce..4050593 100644 --- a/libs/parser/CMakeLists.txt +++ b/libs/parser/CMakeLists.txt @@ -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_SOURCE_FILE "${CMAKE_CURRENT_BINARY_DIR}/generated/gen_parser.cpp") -file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/generated/pslang/parser") - flex_target( generate-pslang-lexer ${PSLANG_LEXER_RULES_FILE} diff --git a/libs/parser/include/pslang/parser/context.hpp b/libs/parser/include/pslang/parser/context.hpp index d195795..a94f3ad 100644 --- a/libs/parser/include/pslang/parser/context.hpp +++ b/libs/parser/include/pslang/parser/context.hpp @@ -2,19 +2,19 @@ #include +namespace pslang::ast +{ + + struct location; + +} + namespace pslang::parser { - namespace bison - { - - class location; - - } - struct context { - bison::location & location; + ast::location & location; indented_statement_list & result; }; diff --git a/libs/parser/include/pslang/parser/error.hpp b/libs/parser/include/pslang/parser/error.hpp index 98238eb..8b569c0 100644 --- a/libs/parser/include/pslang/parser/error.hpp +++ b/libs/parser/include/pslang/parser/error.hpp @@ -1,8 +1,9 @@ #pragma once -#include +#include #include +#include namespace pslang::parser { @@ -10,13 +11,12 @@ namespace pslang::parser struct parse_error : std::exception { - parse_error(std::string message, bison::location location) + parse_error(std::string message, ast::location location) : message_(std::move(message)) - , filename_(*location.begin.filename) + , filename_(location.filename) , location_(location) { - location_.begin.filename = &filename_; - location_.end.filename = &filename_; + location_.filename = filename_; } char const * what() const noexcept @@ -24,7 +24,7 @@ namespace pslang::parser return message_.c_str(); } - bison::location location() const noexcept + ast::location location() const noexcept { return location_; } @@ -32,7 +32,7 @@ namespace pslang::parser private: std::string message_; std::string filename_; - bison::location location_; + ast::location location_; }; } diff --git a/libs/parser/rules/pslang.l b/libs/parser/rules/pslang.l index 21e53ca..8a47dd0 100644 --- a/libs/parser/rules/pslang.l +++ b/libs/parser/rules/pslang.l @@ -9,7 +9,7 @@ using bp = ::pslang::parser::bison::parser; #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); } -"\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); } "=" { return bp::make_assignment(ctx.location); } ":" { return bp::make_colon(ctx.location); } diff --git a/libs/parser/rules/pslang.y b/libs/parser/rules/pslang.y index 6c3a9c4..85f8b7e 100644 --- a/libs/parser/rules/pslang.y +++ b/libs/parser/rules/pslang.y @@ -4,8 +4,7 @@ %language "C++" %define api.namespace {pslang::parser::bison} -%define api.location.file "pslang/parser/location.hpp" -%define api.location.include "" +%define api.location.type { ::pslang::ast::location } %define api.token.raw %define api.token.constructor @@ -33,6 +32,7 @@ void yyerror(char const * s) %code requires { #include +#include #include namespace pslang::parser { diff --git a/libs/parser/source/parser.cpp b/libs/parser/source/parser.cpp index 8e49f3c..5e3aa2b 100644 --- a/libs/parser/source/parser.cpp +++ b/libs/parser/source/parser.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include "gen_parser.hpp" #include "gen_lexer.hpp" @@ -15,7 +16,7 @@ namespace pslang::parser if (!yyin) throw std::system_error(std::make_error_code(static_cast(errno))); - bison::location location(&filename); + ast::location location{filename}; indented_statement_list result; context ctx{location, result};