peter-winter / ctpg

Compile Time Parser Generator is a C++ single header library which takes a language description as a C++ code and turns it into a LR1 table parser with a deterministic finite automaton lexical analyzer, all in compile time.
MIT License
460 stars 24 forks source link

[MSVC] Compilation error, unable to resolve operator overload of `ctpg::stdex::cbitset<N>::operator==` #76

Closed moritz-geier closed 7 months ago

moritz-geier commented 7 months ago

Hello,

I'm trying to build the main branch with MSVC 19.39 on Windows 11. But the build is resulting in the following error.

[build] C:\Users\Moritz Geier\Git\cellcycler\experiments\build\_deps\ctpg-src\include\ctpg/ctpg.hpp(2380): error C2666: 'ctpg::stdex::cbitset<960>::operator ==': overloaded functions have similar conversions
[build] C:\Users\Moritz Geier\Git\cellcycler\experiments\build\_deps\ctpg-src\include\ctpg/ctpg.hpp(268): note: could be 'bool ctpg::stdex::cbitset<960>::operator ==(const ctpg::stdex::cbitset<960> &)'
[build] C:\Users\Moritz Geier\Git\cellcycler\experiments\build\_deps\ctpg-src\include\ctpg/ctpg.hpp(268): note: or 'bool ctpg::stdex::cbitset<960>::operator ==(const ctpg::stdex::cbitset<960> &)' [synthesized expression 'y == x']
[build] C:\Users\Moritz Geier\Git\cellcycler\experiments\build\_deps\ctpg-src\include\ctpg/ctpg.hpp(2380): note: while trying to match the argument list '(ctpg::stdex::cbitset<960>, ctpg::stdex::cbitset<960>)'
[build] C:\Users\Moritz Geier\Git\cellcycler\experiments\build\_deps\ctpg-src\include\ctpg/ctpg.hpp(1915): note: while evaluating constexpr function 'ctpg::parser<ctpg::nterm<ctpg::regex::regex_parser::slice>,std::tuple<ctpg::custom_term<ctpg::regex::regex_parser::<lambda_1>>,ctpg::custom_term<ctpg::regex::char_subset (__cdecl *)(std::string_view)>,ctpg::char_term,ctpg::char_term,ctpg::char_term,ctpg::char_term,ctpg::char_term,ctpg::char_term,ctpg::char_term,ctpg::char_term>,std::tuple<ctpg::nterm<ctpg::regex::regex_parser::slice>,ctpg::nterm<ctpg::regex::regex_parser::slice>,ctpg::nterm<ctpg::regex::regex_parser::slice>,ctpg::nterm<ctpg::regex::regex_parser::slice>,ctpg::nterm<ctpg::regex::regex_parser::slice>,ctpg::nterm<ctpg::size32_t>>,std::tuple<ctpg::detail::rule<false,std::nullptr_t,ctpg::nterm<ctpg::size32_t>,ctpg::custom_term<ctpg::regex::regex_parser::<lambda_1>>>,ctpg::detail::rule<false,ctpg::regex::regex_parser::<lambda_2>,L,ctpg::nterm<ctpg::size32_t>,ctpg::custom_term<ctpg::regex::regex_parser::<lambda_1>>>,ctpg::detail::rule<true,ctpg::regex::regex_parser::<lambda_3>,ctpg::nterm<ctpg::regex::regex_parser::slice>,ctpg::custom_term<ctpg::regex::regex_parser::<lambda_1>>>,ctpg::detail::rule<true,ctpg::regex::regex_parser::<lambda_4>,ctpg::nterm<ctpg::regex::regex_parser::slice>,ctpg::custom_term<ctpg::regex::char_subset (__cdecl *)(std::string_view)>>,ctpg::detail::rule<false,ctpg::ftors::element<2,std::integer_sequence<size_t,0>>,ctpg::nterm<ctpg::regex::regex_parser::slice>,ctpg::char_term,ctpg::nterm<ctpg::regex::regex_parser::slice>,ctpg::char_term>,ctpg::detail::rule<false,std::nullptr_t,ctpg::nterm<ctpg::regex::regex_parser::slice>,ctpg::nterm<ctpg::regex::regex_parser::slice>>,ctpg::detail::rule<true,ctpg::regex::regex_parser::<lambda_5>,ctpg::nterm<ctpg::regex::regex_parser::slice>,ctpg::nterm<ctpg::regex::regex_parser::slice>,ctpg::char_term>,ctpg::detail::rule<true,ctpg::regex::regex_parser::<lambda_6>,ctpg::nterm<ctpg::regex::regex_parser::slice>,ctpg::nterm<ctpg::regex::regex_parser::slice>,ctpg::char_term>,ctpg::detail::rule<true,ctpg::regex::regex_parser::<lambda_7>,ctpg::nterm<ctpg::regex::regex_parser::slice>,ctpg::nterm<ctpg::regex::regex_parser::slice>,ctpg::char_term>,ctpg::detail::rule<true,ctpg::regex::regex_parser::<lambda_8>,ctpg::nterm<ctpg::regex::regex_parser::slice>,ctpg::nterm<ctpg::regex::regex_parser::slice>,ctpg::char_term,ctpg::nterm<ctpg::size32_t>,ctpg::char_term>,ctpg::detail::rule<false,std::nullptr_t,ctpg::nterm<ctpg::regex::regex_parser::slice>,ctpg::nterm<ctpg::regex::regex_parser::slice>>,ctpg::detail::rule<true,ctpg::regex::regex_parser::<lambda_9>,ctpg::nterm<ctpg::regex::regex_parser::slice>,ctpg::nterm<ctpg::regex::regex_parser::slice>,ctpg::nterm<ctpg::regex::regex_parser::slice>>,ctpg::detail::rule<false,std::nullptr_t,ctpg::nterm<ctpg::regex::regex_parser::slice>,ctpg::nterm<ctpg::regex::regex_parser::slice>>,ctpg::detail::rule<true,ctpg::regex::regex_parser::<lambda_10>,ctpg::nterm<ctpg::regex::regex_parser::slice>,ctpg::nterm<ctpg::regex::regex_parser::slice>,ctpg::char_term,ctpg::nterm<ctpg::regex::regex_parser::slice>>,ctpg::detail::rule<false,std::nullptr_t,ctpg::nterm<ctpg::regex::regex_parser::slice>,ctpg::nterm<ctpg::regex::regex_parser::slice>>>,ctpg::use_lexer<ctpg::regex::regex_lexer>,ctpg::default_limits>::state_analyzer::analyze_states'

I also tried building the release 1.3.7 which worked without problems.

peter-winter commented 7 months ago

The msvc support is the main time sink in this project. It takes 80% of the time to come up with workarounds just to make things compile. Not sure why the main branch is reporting no issues on github actions in msvc, maybe the compiler is different.

What exactly are you trying to build here?

moritz-geier commented 7 months ago

This is my current code. The error is indicated by the parser object. The goal is to create a parser to parse simple conditions like (5>3)&10>8.8. I tried to implement it on the release branch 1.3.7 but there my regex for floating point ("[-+]?[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?") numbers got me into some trouble, thus i wanted to try out the main branch. The code below is just a simple proof of concept, but it still fails.

///////////////////////////////////////////////////////////////////////////
static constexpr ctpg::nterm<bool> conditionExpression{"condition"};

static constexpr char integerPattern[] = "[-+]?[0-9]+";
static constexpr ctpg::regex_term<integerPattern> integerValue{"integer"};

static constexpr ctpg::char_term trueLiteral{'t'};
static constexpr ctpg::char_term falseLiteral{'f'};

///////////////////////////////////////////////////////////////////////////
static constexpr auto root = conditionExpression;

///////////////////////////////////////////////////////////////////////////
static constexpr auto terminals = ctpg::terms(
    integerValue,
    't',
    'f'
);

///////////////////////////////////////////////////////////////////////////
static constexpr auto nonTerminals = ctpg::nterms(
    conditionExpression
);

///////////////////////////////////////////////////////////////////////////
static constexpr ctpg::parser parser{
    root,
    terminals,
    nonTerminals,
    rules(
        conditionExpression(trueLiteral) >=
            [](const auto&) { return true; },
        conditionExpression(falseLiteral) >=
            [](const auto&) { return false; }
    )
};
moritz-geier commented 7 months ago

Oh, i tried to compile it with GCC, and it says:

ctpg.hpp:2380:42: error: C++20 says that these are ambiguous, even though the second is reversed: [-Werror]
[build]  2380 |                     if (states[i].kernel == kernel)
[build]       |                         ~~~~~~~~~~~~~~~~~^~~~~~~~~
peter-winter commented 7 months ago

Oh, you are supposed to use c++17. I did not work on the project quite a while, making it c++20 is my top priority though. I am aware there are issues with compilation using c++20

moritz-geier commented 7 months ago

Okay thank you, are there plans to upgrade to C++20 at any time?

peter-winter commented 7 months ago

Sure, but keep in mind I'm just another Nebraska dude: https://xkcd.com/2347/