Code Monkey home page Code Monkey logo

peter-winter / ctpg Goto Github PK

View Code? Open in Web Editor NEW
449.0 11.0 24.0 186 KB

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.

License: MIT License

C++ 97.78% CMake 2.22%
compile-time parser-generator c-plus-plus cpp17 header-only grammar regex compiler-compiler lr-parser lookahead

ctpg's Issues

Maybe it is possible that removing lexer scanner?

I am writing a grammar using another parser library. i find lexer-scanner is unnatural. when we define a token , we usually give it a name with some semantics such as VARIABLE, STRING, INT, FLOAT, BOOL etc , this is unnatural because the lexer should not carry any infomation about semantics. maybe it is more suitable that using LITTTLE_CHAR_SET, CHARS_SET_WITH_QUOTES, DIGIT_SET replace VARIABLE, STRING, INT, but obviously, these name are too verbose. it seems unimportant, but when i define a grammar, i always need make a tradeoff between an natural but complex grammar and a simple but incoherent grammar, because the place using same token often have different semantics.

So, i consider whether we can get a nature grammar definition by removing lexer-scanner and replacing lexer-token with inline regex. At the same time, i think of your lib and i feel it is suitable to your lib becase it is able to complement the problem about lexer priority.

[question solved] constexpr variable 'p' must be initialized by a constant expression

I'm trying to build a simple compiler for another language.

I've managed to add rules and AST for declaration statements successfully. But I encountered problem when adding maths operators, the rules I applied are like below:

constexpr nterm<ExpressionPtr> unary_expression("unary_expression"); 
constexpr nterm<ExpressionPtr> multiplicative_expression("multiplicative_expression"); 
constexpr nterm<ExpressionPtr> additive_expression("additive_expression"); 
... ...

constexpr parser p( 
    program, 
    terms(  o_plus, o_minus, o_mul, o_div, o_mod, ... ...  ),
    nterms( primary_expression, unary_expression, multiplicative_expression, additive_expression, expression, ... ..., program ),
    rules(
        ... ...
        unary_expression    (primary_expression)    >= [](const auto& w1) { return w1; }, 
        unary_expression    (o_minus, primary_expression) >= [](const auto& w1, const auto& w2) { return new NegOperatorAST(w2); }, 

        multiplicative_expression (unary_expression)      >= [](const auto& w1) { return w1; }, 
        multiplicative_expression (multiplicative_expression, o_mul, unary_expression)   >= [](const auto& w1, const auto& w2, const auto& w3) { return new MulOperatorAST(w1, w3); }, 
        multiplicative_expression (multiplicative_expression, o_div, unary_expression)   >= [](const auto& w1, const auto& w2, const auto& w3) { return new DivOperatorAST(w1, w3); }, 
        multiplicative_expression (multiplicative_expression, o_mod, unary_expression)   >= [](const auto& w1, const auto& w2, const auto& w3) { return new ModOperatorAST(w1, w3); }, 

        additive_expression (multiplicative_expression)     >= [](const auto& w1) { return w1; }, 
        additive_expression (additive_expression, o_plus, multiplicative_expression)    >= [](const auto& w1, const auto& w2, const auto& w3) { return new AddOperatorAST(w1, w3); }, 
        additive_expression (additive_expression, o_minus, multiplicative_expression)   >= [](const auto& w1, const auto& w2, const auto& w3) { return new SubOperatorAST(w1, w3); }, 
        ... ...
    )
);

The weird thing I found was, for the five rules where I applied MulOperatorAST, DivOperatorAST, ModOperatorAST, AddOperatorAST and SubOperatorAST, when I comment out whichever one of the five rules, the compiler would work fine and generate the ideal code. But when I use these five lines of rules altogether, I would receive an error message like this:

./include/parser.hpp:127:18: error: constexpr variable 'p' must be initialized by a constant expression
constexpr parser p( 
                 ^~
./include/ast/../ctpg.hpp:1339:17: note: constexpr evaluation hit maximum step limit; possible infinite loop?
                if (tr_from == uninitialized16) 
                ^

I've defined the five operators' AST in the same way. The only difference between them is inside the codegen() function:

class Expression 
{
public:
    virtual ~Expression() = default;
    virtual Value *codegen() const
    {   throw std::runtime_error("Not implemented."); }

    virtual Value *initgen(ExpressionPtr init) const
    {   throw std::runtime_error("Not implemented."); }

    virtual Value *initgen(std::string_view spec, ExpressionPtr init) const 
    {   throw std::runtime_error("Not implemented."); } 

    virtual Type *get_type() const
    {   return Type::getInt32Ty(TheContext); }

    virtual std::string_view get_name() const
    {   throw std::runtime_error("Not implemented."); }

    virtual std::string_view get_spec() const
    {   throw std::runtime_error("Not implemented."); }

    virtual Value *get_AllocaInst() const
    {   throw std::runtime_error("Not implemented."); }
}; 

class AddOperatorAST
    : public Expression
{
private: 
    ExpressionPtr left; 
    ExpressionPtr right;
public:
    AddOperatorAST(ExpressionPtr _left, ExpressionPtr _right)
        : left(_left)
        , right(_right)
    {}
    virtual Value *codegen() const
    {
        Value *vl = left->codegen(); 
        Value *vr = right->codegen(); 
        Value *add = Builder.CreateFAdd(vl, vr, "add"); 
        return add; 
    }
};

At this point I really don't understand why this problem occurs. Have I passed anything not compatible to the constexpr parser? If possible, do you think I could modify my code to solve it?


PS: I have noticed that any terminal/nonterminal symbols missing in the term/nterm list would also give the same error message, but for that the note message would be:

./include/parser.hpp:127:18: error: constexpr variable 'p' must be initialized by a constant expression
constexpr parser p( 
                 ^~
./include/ast/../ctpg.hpp:480:13: note: subexpression not valid in a constant expression
            throw std::runtime_error("string not found"); 
            ^

Make tests and examples executables conditional

Hi,

Having test and example executables optionally removed would be nice to have as it would cut down installation and package generation times (I'm writing an AUR package for ctpg right now btw).

Thanks for you work so far :)

Regards,
Jules

[question] Cant Parameterize and "Seperate out" Parser

I am trying to split apart (and parameterize) my parser, something like this..

template< 
        auto ConvertToTypeConstantParameter, 
        typename OperhandTypeParameterType, 
        auto DataTypeNameParameterConstant, 
        auto& LiteralRegexParameterConstant, 
                // = defualt_constant_expression_literal_regex, 
        auto& IdentifierRegexParameterConstant, 
                // = defualt_constant_expression_identifier_regex, 
        auto PlusCharacterParameterConstant = '+', 
        auto MinusCharacterParameterConstant = '-', 
        auto MultiplyCharacterParameterConstant = '*', 
        auto DivideCharacterParameterConstant = '/', 
        auto LeftParanethesisCharacterParameterConstant = '(', 
        auto RightParanethesisCharacterParameterConstant = ')', 
        auto& IdentifierNameParameterConstant 
                = identifier_name_string, 
        auto& FactorNameParameterConstant 
                = factor_name_string, 
        auto& SumNameParameterConstant 
                = sum_name_string, 
        auto& ParanthesisScopeParameterConstant 
                = parenthesis_scope_name_string 
    >
struct ConstantExpression
{
    using DataType = OperhandTypeParameterType;
    constexpr static auto data_type_name = DataTypeNameParameterConstant;

    constexpr static auto literal_term = ctpg::regex_term< LiteralRegexParameterConstant >{ 
            "num"
        };

    constexpr static auto identifier = ctpg::regex_term< IdentifierRegexParameterConstant >{ 
            "id"
        };

    constexpr static auto factor = ctpg::nterm< OperhandTypeParameterType >{ FactorNameParameterConstant };
    constexpr static auto sum = ctpg::nterm< OperhandTypeParameterType >{ SumNameParameterConstant };
    constexpr static auto parenthesis_scope = ctpg::nterm< OperhandTypeParameterType >{ ParanthesisScopeParameterConstant };

    constexpr static auto nterms = ctpg::nterms( 
            factor, sum, parenthesis_scope 
        );

    constexpr static auto plus_term = ctpg::char_term{ 
            PlusCharacterParameterConstant, 
            1, 
            ctpg::associativity::ltor 
        };
    constexpr static auto minus_term = ctpg::char_term{ 
            MinusCharacterParameterConstant, 
            1, 
            ctpg::associativity::ltor 
        };
    constexpr static auto multiply_term = ctpg::char_term{ 
            MultiplyCharacterParameterConstant, 
            2, 
            ctpg::associativity::ltor 
        };
    constexpr static auto divide_term = ctpg::char_term{ 
            DivideCharacterParameterConstant, 
            2, 
            ctpg::associativity::ltor 
        };
    constexpr static auto left_parenthesis_term = ctpg::char_term{ 
            LeftParanethesisCharacterParameterConstant, 
            3, 
            ctpg::associativity::ltor 
        };
    constexpr static auto right_parenthesis_term = ctpg::char_term{ 
            RightParanethesisCharacterParameterConstant, 
            3, 
            ctpg::associativity::ltor 
        };

    constexpr static auto terms = ctpg::terms(
            plus_term, 
            minus_term, 
            multiply_term, 
            divide_term, 
            left_parenthesis_term, 
            right_parenthesis_term 
        );

    constexpr static auto rules = ctpg::rules( 
            factor( literal_term ) >= ConvertToTypeConstantParameter, 
            factor( factor, multiply_term, literal_term ) 
                >= []( size_t current_factor, auto, const auto& next_token ) {  
                        return current_factor * ConvertToTypeConstantParameter( next_token ); 
                    }, 
            //More rules...
        );
};

This way, for multiple data-types I can make more constant expresssion regexes for different data-types (and for different types of literals with different regexes e.g natural number [0-9][0-9]* vs float [0-9]*.[0-9]+).

The problem comes when I try to use a literal, it seems to have trouble accepting the string for the regex in the literal_term

I have tried multiple methods, at first all the parameters were just plain auto, and I tried serializing the strings into templates, then injecting them back into an array type with the size known at compile time (as a bunch of errors with the size of the type not being known at compile time come up otherwise).

template< auto FirstConstantParameter, auto... SeriesConstantParameters >
struct TakeOneFromTemplateSeries {
    constexpr static auto first = FirstConstantParameter;
    using NextType = TakeOneFromTemplateSeries< SeriesConstantParameters... >;
};

template< auto... ElementParameterConstants >
struct RawTemplateArray
{
    using ElementType = decltype( 
            TakeOneFromTemplateSeries< ElementParameterConstants... >::first 
        );
    constexpr static auto size = sizeof...( ElementParameterConstants );
    constexpr static ElementType array[ size ] = { ElementParameterConstants... };
    constexpr static ElementType* pointer = array;
};

template< 
        auto ArrayParameterConstant, 
        size_t IndexParameterConstant, 
        size_t ArrayLengthParameterConstant, 
        auto... ElementParameterConstants 
    >
struct ToRawTemplateArrayImplementation
{
    using ResultType = typename ToRawTemplateArrayImplementation< 
            ArrayParameterConstant, 
            IndexParameterConstant + 1, 
            ArrayLengthParameterConstant, 
            ElementParameterConstants..., 
            ArrayParameterConstant[ IndexParameterConstant % ArrayLengthParameterConstant ] 
        >::ResultType;
};

template< 
        auto ArrayParameterConstant, 
        size_t IndexParameterConstant, 
        auto... ElementParameterConstants 
    >
struct ToRawTemplateArrayImplementation< 
        ArrayParameterConstant, 
        IndexParameterConstant, 
        IndexParameterConstant, 
        ElementParameterConstants... 
    >
{
    using ResultType = RawTemplateArray< 
            ElementParameterConstants... 
        >;
};

template< auto ArrayParameterConstant >
struct ToRawTemplateArray
{
    using ResultType = typename ToRawTemplateArrayImplementation< 
            ArrayParameterConstant, 
            0, 
            // std::strlen( ArrayParameterConstant ) 
            ctpg::utils::str_len( ArrayParameterConstant ) + 1
        >::ResultType;
};
constexpr static const char natural_number_regex_string[] = "[0-9][0-9]*";
constexpr static auto natural_number_regex = ToRawTemplateArray< natural_number_regex_string >::ResultType{};
constexpr static auto defualt_constant_expression_literal_regex = natural_number_regex;

I would then pass natural_number_regex into ConstantExpression
If I do it like this

template< 
        auto ConvertToTypeConstantParameter, 
        typename OperhandTypeParameterType, 
        auto& DataTypeNameParameterConstant = decltype( defualt_constant_expression_data_type_name )::array, 
        auto& LiteralRegexParameterConstant = decltype( defualt_constant_expression_literal_regex )::array,
        auto& IdentifierRegexParameterConstant = decltype( defualt_constant_expression_identifier_regex )::array, 
        auto& IdentifierNameParameterConstant = decltype( defualt_constant_expression_identifier_term_name )::array, 
        auto& FactorNameParameterConstant = decltype( defualt_constant_expression_factor_nterm_name )::array, 
        auto& SumNameParameterConstant = decltype( defualt_constant_expression_sum_nterm_name )::array, 
        auto& ParanthesisScopeParameterConstant = decltype( defualt_constant_expression_parenthesis_scope_nterm_name )::array, 
        auto PlusCharacterParameterConstant = '+', 
        auto MinusCharacterParameterConstant = '-', 
        auto MultiplyCharacterParameterConstant = '*', 
        auto DivideCharacterParameterConstant = '/', 
        auto LeftParanethesisCharacterParameterConstant = '(', 
        auto RightParanethesisCharacterParameterConstant = ')', 
    >

The compiler would spit out a whole bunch of template barf I have spent a while formatting and trying to make some sense of, clang is giving me something GCC wont

ctpg.hpp:180:25: warning: ISO C++20 considers use of overloaded operator '==' (with operand types 'ctpg::stdex::cvector<unsigned short, 13>::iterator' and 'ctpg::stdex::cvector<unsigned short, 13>::iterator') to be ambiguous despite there being a unique best viable function [-Wambiguous-reversed-operator]
            while (!(it == end()))
                     ~~ ^  ~~~~~
/root/.conan/data/ctpg/1.3.6/_/_/package/5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9/include/ctpg.hpp:2546:25: note: in instantiation of member function 'ctpg::stdex::cvector<unsigned short, 13>::erase' requested here
        ps.cursor_stack.erase(ps.cursor_stack.end() - ri.r_elements, ps.cursor_stack.end());
ng_buffer<12>, ctpg::detail::no_stream>' requested here
        auto res = p.parse(
                     ^
/root/.conan/data/ctpg/1.3.6/_/_/package/5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9/include/ctpg.hpp:3285:43: note: in instantiation of function template specialization 'ctpg::regex::analyze_dfa_size<12UL>' requested here
    static const size_t dfa_size = regex::analyze_dfa_size(Pattern);
                                          ^
/root/workdir/Include/Warp/Expression.hpp:134:42: note: in instantiation of template class 'ctpg::regex_term<natural_number_regex_string>' requested here
    constexpr static auto literal_term = ctpg::regex_term< LiteralRegexParameterConstant >{ 
                                         ^
/root/workdir/Source/Main.cpp:19:9: note: in instantiation of template class 'ConstantExpression<&to_size_t, unsigned long, natural_number_name_string, natural_number_regex_string, identifier_regex_string, '+', '-', '*', '/', '(', ')', identifier_name_string, factor_name_string, sum_name_string, parenthesis_scope_name_string>' requested here
        NaturalNumberConstantExpression::factor, 
        ^
/root/.conan/data/ctpg/1.3.6/_/_/package/5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9/include/ctpg.hpp:127:28: note: ambiguity is between a regular call to this operator and a call with the argument order reversed
            constexpr bool operator == (const it_type& other) const { return cast()->ptr == other.ptr; }
                           ^
/root/.conan/data/ctpg/1.3.6/_/_/package/5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9/include/ctpg.hpp:180:25: warning: ISO C++20 considers use of overloaded operator '==' (with operand types 'ctpg::stdex::cvector<unsigned short, 26>::iterator' and 'ctpg::stdex::cvector<unsigned short, 26>::iterator') to be ambiguous despite there being a unique best viable function [-Wambiguous-reversed-operator]
            while (!(it == end()))
                     ~~ ^  ~~~~~
/root/.conan/data/ctpg/1.3.6/_/_/package/5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9/include/ctpg.hpp:2546:25: note: in instantiation of member function 'ctpg::stdex::cvector<unsigned short, 26>::erase' requested here
        ps.cursor_stack.erase(ps.cursor_stack.end() - ri.r_elements, ps.cursor_stack.end());
/root/.conan/data/ctpg/1.3.6/_/_/package/5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9/include/ctpg.hpp:127:28: note: ambiguity is between a regular call to this operator and a call with the argument order reversed
            constexpr bool operator == (const it_type& other) const { return cast()->ptr == other.ptr; }
                           ^
In file included from /root/workdir/Source/Main.cpp:1:
In file included from /root/workdir/Include/Warp/Expression.hpp:10:
In file included from /root/.conan/data/ctpg/1.3.6/_/_/package/5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9/include/ctpg.hpp:12:
/usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/variant:1100:7: error: static_assert failed due to requirement '__detail::__variant::__exactly_once<ctpg::term_value<std::basic_string_view<char, std::char_traits<char>>>, std::nullptr_t, ctpg::no_type, unsigned long, ctpg::term_value<char>>' "T must occur exactly once in alternatives"
      static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,

These are just a few errors/warnings/notes I thought may be relevant

I have also tried specifying auto& (because I saw it in ctpg::buffers::cstring_buffer) instead of just auto -- no dice

With either, if I specify raw literals in the parameters I get something like

/root/workdir/Source/Main.cpp:6:9: error: pointer to subobject of string literal is not allowed in a template argument
        "[0-9][0-9]*",

If I try to substitute constants such as

constexpr static const char natural_number_regex_string[] = "[0-9][0-9]*";

I get right back to the errors I had before

I have no idea how to make this work properly and think I may be forced to go back to a "monolithic" parser. Anyone know how to make this work

Thank you,

  • Chris
    P.s Here is a gist of a full compiler output and here is my header file and this is a Main.cpp using it, if you comment out the second rule, it works because it does not have the literal term
    P.s.s If I substitute the mock rules with the actual ones I want too use, I get
/root/.conan/data/ctpg/1.3.6/_/_/package/5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9/include/ctpg.hpp:127:28: note: ambiguity is between a regular call to this operator and a call with the argument order reversed
            constexpr bool operator == (const it_type& other) const { return cast()->ptr == other.ptr; }
                           ^
/root/workdir/Source/Main.cpp:16:9: error: excess elements in struct initializer
        NaturalNumberConstantExpression::factor, 
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 warnings and 1 error generated.

This warning is showing up quite persistently.

Precedence When Matching/Lexing

Possible to use precedence in pattern matching step?

I have 3 terms on for digits ("[0-9]+"), "u" and one for identifiers "[a-zA-Z_][a-zA-Z_0-9]+"

I "u" to identify an unsigned integer and I can specify its bit arity with a number after it

e.g "100u8" is an an unsigned 8-bit integer with value 100.

100u works fine (unsigned integer with value 100 and unspecified bit-arity)

However 100 is pared as "Digits" <- "Base10Digits", (I do this because I can parse digits in different bases) then "u8" is parsed as an identifier, and there is no rule to match this.

Right now "u" has a higher precedence than "Identifier" but identifier gets matched first.

Would it be possible to:
A ) Try matching patterns with higher precedence first
B ) If there is no suitable rule for the matched term, fallback and see if there is a suitable term (case: Unexpected Identifier)?

Big Parsers?

Hey, thanks for writing this library. Is ctpg capable of parsing complex languages like JSON, YAML, or even C/C++? I noticed most of the examples are pretty simple, and feel like toy parsers. Have there been any open source big parsers with many rules and terms built on top of ctpg that I could refer to?

[Feture Request] Integration with CTRE

CTRE is a dedicated Compile Time Regex library, as such it seems to have more regex features, and supports unicode, would it be possible to integrate it into CTPG?

Constexpr parsing: non-constexpr containers

I'm currently facing an issue while using ctpg::parser:

  • libstdc++ doesn't have a constexpr-ready version of std::optional
  • libc++ doesn't have a constexpr-ready version of std::vector

This makes ctpg::parser currently unusable in constexpr functions since both are required but no standard library implementation has them both constexpr-ready.

There could several ways to make constexpr ctpg happen, being:

I will probably go for one of these options on my side because I need ctpg to work in constexpr contexts for my research, but I would like to know if merging one of these changes on your side sounds reasonable to you, and eventually which one you prefer so I can put my focus on it.

Regards,
Jules

string_view buffer

Thanks for your work! I'm enjoying playing with the library.

I found this handy fwiw:

struct sv_buffer
{
public:
    constexpr sv_buffer(std::string_view str) : str(str) {}
    constexpr sv_buffer(const char *str) : str(str) {}

    constexpr auto begin() const { return str.cbegin(); }
    constexpr auto end() const { return str.cend(); }

    using iterator = std::string_view::const_iterator;

    constexpr std::string_view get_view(iterator start, iterator end) const
    {
        return std::string_view(str.data() + (start - str.begin()),
                                end - start);
    }

private:
    std::string_view str;
};

Regex Fails to Match

using namespace ctpg;
using namespace ctpg::buffers;

constexpr char number_pattern[] = "0|[1-9][0-9]*";
constexpr ctpg::regex::expr<number_pattern> r;
const bool match = r.match(string_buffer("0"));

match returns false, whereas matching string_buffer("1") returns true.

Simple expression example and AST

Hi, I started with the examples/simple-expr-parser.cpp and I am wondering if it would be possible to retrieve from the parser p a type, or some other data, to inspect (or derive from it, if needed) the AST associated to an expression.

For example, when either running the program ./simple-expr-parser '3*(1-5)' or writing code p.parse(cstring_buffer("3*(1-5)") is there somewhere, even if internal, something like o_mul<<number<3>, o_minus<number<1>, number<5>>>?

Thank you very much in advance for any help!

[Question] Did I exceed the maximum number of rules?

I got a pretty nasty error log, it seems to make a lot of references too a maximum of some kind, my question is: did I exceed the maximum number of allowed rules?

Example Error:

/root/.conan/data/ctpg/1.3.7/_/_/package/5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9/include/ctpg/ctpg.hpp:2004:72: error: โ€˜nโ€™ is not a member of โ€˜std::tuple<ctpg::detail::rule<true, Warp::Parsing::FunctionDeclarationParser<Warp::Parsing::Terms<Warp::Parsing::Terms<Warp::Parsing::Terms<Warp::Parsing::Terms<Warp::Parsing::Terms<Warp::Parsing::Terms<Warp::Parsing::Terms<Warp::Parsing::Terms<Warp::Parsing::Terms<void, 0, Warp::Parsing::TreeTerm<Warp::Parsing::MathematicalExpression::Add, Warp::Parsing::CharTerm, '+', ctpg::associativity::ltor>, Warp::Parsing::TreeTerm<Warp::Parsing::MathematicalExpression::Subtract, Warp::Parsing::CharTerm, '-', ctpg::associativity::ltor> >, 1, Warp::Parsing::TreeTerm<Warp::Parsing::MathematicalExpression::Multiply, Warp::Parsing::CharTerm, '*', ctpg::associativity::ltor>, Warp::Parsing::TreeTerm<Warp::Parsing::MathematicalExpression::Divide, Warp::Parsing::CharTerm, '/', ctpg::associativity::ltor> >, 2, Warp::Parsing::TypeTreeTerm<Warp::Runtime::Compiler::NumericTypeTag::FixedPoint, Warp::Parsing::NonTerminalTerm, Warp::Runtime::Compiler::NumericType<Warp::Runtime::Compiler::NumericTypeTag::FixedPoint, numeric::fixed<16, 16> >, Warp::Utilities::FixedString<11>{"FixedPoint"}>, Warp::Parsing::TypeTreeTerm<Warp::Runtime::Compiler::NumericTypeTag::Whole, Warp::Parsing::NonTerminalTerm, Warp::Runtime::Compiler::NumericType<Warp::Runtime::Compiler::NumericTypeTag::Whole, long unsigned int>, Warp::Utilities::FixedString<6>{"Whole"}>, Warp::Parsing::TypeTreeTerm<Warp::Runtime::Compiler::NumericTypeTag::Integer, Warp::Parsing::NonTerminalTerm, Warp::Runtime::Compiler::NumericType<Warp::Runtime::Compiler::NumericTypeTag::Integer, long long int>, Warp::Utilities::FixedString<8>{"Integer"}>, Warp::Parsing::TypeTreeTerm<Warp::Runtime::Compiler::NumericTypeTag::FixedPoint, Warp::Parsing::NonTerminalTerm, Warp::Runtime::Compiler::NumericType<Warp::Runtime::Compiler::NumericTypeTag::FixedPoint, numeric::fixed<16, 16> >, Warp::Utilities::FixedString<11>{"FixedPoint"}>, Warp::Parsing::TypeTreeTerm<Warp::Runtime::Compiler::NumericTypeTag::Character, Warp::Parsing::NonTerminalTerm, Warp::Runtime::Compiler::NumericType<Warp::Runtime::Compiler::NumericTypeTag::Character, char>, Warp::Utilities::FixedString<10>{"Character"}>, Warp::Parsing::TypeTreeTerm<Warp::Runtime::Compiler::NumericTypeTag::Bool, Warp::Parsing::NonTerminalTerm, Warp::Runtime::Compiler::NumericType<Warp::Runtime::Compiler::NumericTypeTag::Bool, Warp::Runtime::Compiler::WarpBool>, Warp::Utilities::FixedString<5>{"Bool"}>, Warp::Parsing::TreeTerm<Warp::Parsing::NumericLiteral::Minus, Warp::Parsing::CharTerm, '-', ctpg::associativity::no_assoc>, Warp::Parsing::TreeTerm<Warp::Parsing::NumericLiteral::Dot, Warp::Parsing::CharTerm, '.', ctpg::associativity::no_assoc>, Warp::Parsing::TreeTerm<Warp::Parsing::NumericLiteral::IntegerMark, Warp::Parsing::CharTerm, 'i', ctpg::associativity::no_assoc>, Warp::Parsing::TreeTerm<Warp::Parsing::NumericLiteral::UnsignedMark, Warp::Parsing::CharTerm, 'u', ctpg::associativity::no_assoc>, Warp::Parsing::TreeTerm<Warp::Parsing::NumericLiteral::CharacterMark, Warp::Parsing::CharTerm, 'c', ctpg::associativity::no_assoc>, Warp::Parsing::TreeTerm<Warp::Parsing::NumericLiteral::FixedMark, Warp::Parsing::StringTerm, Warp::Utilities::FixedString<3>{"xp"}, ctpg::associativity::no_assoc>, Warp::Parsing::TreeTerm<Warp::Parsing::NumericLiteral::BoolMark, Warp::Parsing::StringTerm, Warp::Utilities::FixedString<3>{"bl"}, ctpg::associativity::no_assoc>, Warp::Parsing::TypeTreeTerm<Warp::Parsing::NumericLiteral::Digits, Warp::Parsing::NonTerminalTerm, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, Warp::Utilities::FixedString<7>{"Digits"}>, Warp::Parsing::TypeTreeTerm<Warp::Parsing::NumericLiteral::AnyDecimalDigitsReduction, Warp::Parsing::NonTerminalTerm, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, Warp::Utilities::FixedString<26>{"AnyDecimalDigitsReduction"}>, Warp::Parsing::TreeTerm<Warp::Parsing::NumericLiteral::Base10Digits, Warp::Parsing::RegexTerm, Warp::Utilities::FixedString<20>{"([0-9]+)|(0d[0-9]+)"}, Warp::Utilities::FixedString<13>{"Base10Digits"}, ctpg::associativity::no_assoc>, Warp::Parsing::TreeTerm<Warp::Parsing::NumericLiteral::Base2Digits, Warp::Parsing::RegexTerm, Warp::Utilities::FixedString<9>{"0b[0-1]+"}, Warp::Utilities::FixedString<12>{"Base2Digits"}, ctpg::associativity::no_assoc>, Warp::Parsing::TreeTerm<Warp::Parsing::NumericLiteral::Base16Digits, Warp::Parsing::RegexTerm, Warp::Utilities::FixedString<15>{"0x[0-9A-Fa-f]+"}, Warp::Utilities::FixedString<13>{"Base16Digits"}, ctpg::associativity::no_assoc>, Warp::Parsing::TreeTerm<Warp::Parsing::NumericLiteral::Base8Digits, Warp::Parsing::RegexTerm, Warp::Utilities::FixedString<9>{"0o[0-7]+"}, Warp::Utilities::FixedString<12>{"Base8Digits"}, ctpg::associativity::no_assoc>, Warp::Parsing::TreeTerm<Warp::Parsing::NumericLiteral::CharacterLiteral, Warp::Parsing::RegexTerm, Warp::Utilities::FixedString<48>{"(\'[a-zA-Z~`!@#$%^&*()-=_+<>,\\.\"/?;:|{}]\')|(\' \')"}, Warp::Utilities::FixedString<17>{"CharacterLiteral"}, ctpg::associativity::no_assoc>, Warp::Parsing::TreeTerm<Warp::Parsing::NumericLiteral::BooleanLiteral, Warp::Parsing::RegexTerm, Warp::Utilities::FixedString<15>{"(true)|(false)"}, Warp::Utilities::FixedString<15>{"BooleanLiteral"}, ctpg::associativity::no_assoc>, Warp::Parsing::TreeTerm<Warp::Parsing::NumericLiteral::EscapeCharacterLiteral, Warp::Parsing::RegexTerm, Warp::Utilities::FixedString<13>{"\'\\\\[0nt\'\\\\]\'"}, Warp::Utilities::FixedString<17>{"CharacterLiteral"}, ctpg::associativity::no_assoc>, Warp::Parsing::TreeTerm<Warp::Parsing::NumericLiteral::NumericalDelinator, Warp::Parsing::CharTerm, '_', ctpg::associativity::no_assoc>, Warp::Parsing::TreeTerm<Warp::Parsing::NumericLiteral::AnyDecimalDigits, Warp::Parsing::RegexTerm, Warp::Utilities::FixedString<15>{"\\.[0-9A-Fa-f]+"}, Warp::Utilities::FixedString<17>{"AnyDecimalDigits"}, ctpg::associativity::no_assoc> >, 3, Warp::Parsing::TreeTerm<Warp::Parsing::Brackets::OpenParenthesis, Warp::Parsing::CharTerm, '(', ctpg::associativity::no_assoc>, Warp::Parsing::TreeTerm<Warp::Parsing::Brackets::CloseParenthesis, Warp::Parsing::CharTerm, ')', ctpg::associativity::no_assoc> >, 4, Warp::Parsing::TreeTerm<Warp::Parsing::MultiPurposeOperator::Equal, Warp::Parsing::CharTerm, '=', ctpg::associativity::no_assoc> >, 5, Warp::Parsing::TreeTerm<Warp::Parsing::Identifier::Identifier, Warp::Parsing::RegexTerm, Warp::Utilities::FixedString<23>{"[a-zA-Z_][a-zA-Z0-9_]+"}, Warp::Utilities::FixedString<11>{"Identifier"}, ctpg::associativity::no_assoc> >, 6, Warp::Parsing::TreeTerm<Warp::Parsing::Keyword::Let, Warp::Parsing::StringTerm, Warp::Utilities::FixedString<4>{"let"}, ctpg::associativity::no_assoc> >, 7, Warp::Parsing::TreeTerm<Warp::Parsing::Declaration::SemiColon, Warp::Parsing::CharTerm, ';', ctpg::associativity::no_assoc> >, 8, Warp::Parsing::TypeTreeTerm<Warp::Parsing::Declaration::Constant, Warp::Parsing::NonTerminalTerm, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, Warp::Utilities::FixedString<20>{"ConstantDeclaration"}> >, Warp::Runtime::Compiler::NumericTypeResolver, Warp::Parsing::Construct::Constant, Warp::Runtime::Compiler::NumericTypeTag, Warp::Parsing::Constant<Warp::SyntaxAnalysis::SyntaxTree::SyntaxNode, Warp::Runtime::Compiler::NumericTypeTag> >::constant_from_math_term<Warp::Parsing::MathematicalExpressionParser<Warp::Parsing::Terms<Warp::Parsing::Terms<Warp::Parsing::Terms<Warp::Parsing::Terms<Warp::Parsing::Terms<Warp::Parsing::Terms<Warp::Parsing::Terms<Warp::Parsing::Terms<Warp::Parsing::Terms<Warp::Parsing::Terms<void, 0, Warp::Parsing::TreeTerm<Warp::Parsing::MathematicalExpression::Add, Warp::Parsing::CharTerm, '+', ctpg::associativity::ltor>, Warp::Parsing::TreeTerm<Warp::Parsing::MathematicalExpression::Subtract, Warp::Parsing::CharTerm, '-', ctpg::associativity::ltor> >, 1, Warp::Parsing::TreeTerm<Warp::Parsing::MathematicalExpression::Multiply, Warp::Parsing::CharTerm, '*', ctpg::associativity::ltor>, Warp::Parsing::TreeTerm<Warp::Parsing::MathematicalExpression::Divide, Warp::Parsing::CharTerm, '/', ctpg::associativity::ltor> >, 2, Warp::Parsing::TypeTreeTerm<Warp::Runtime::Compiler::NumericTypeTag::FixedPoint, Warp::Parsing::NonTerminalTerm, Warp::Runtime::Compiler::NumericType<Warp::Runtime::Compiler::NumericTypeTag::FixedPoint, numeric::fixed<16, 16> >, Warp::Utilities::FixedString<11>{"FixedPoint"}>, Warp::Parsing::TypeTreeTerm<Warp::Runtime::Compiler::NumericTypeTag::Whole, Warp::Parsing::NonTerminalTerm, Warp::Runtime::Compiler::NumericType<Warp::Runtime::Compiler::NumericTypeTag::Whole, long unsigned int>, Warp::Utilities::FixedString<6>{"Whole"}>, Warp::Parsing::TypeTreeTerm<Warp::Runtime::Compiler::NumericTypeTag::Integer, Warp::Parsing::NonTerminalTerm, Warp::Runtime::Compiler::NumericType<Warp::Runtime::Compiler::NumericTypeTag::Integer, long long int>, Warp::Utilities::FixedString<8>{"Integer"}>, Warp::Parsing::TypeTreeTerm<Warp::Runtime::Compiler::NumericTypeTag::FixedPoint, Warp::Parsing::NonTerminalTerm, Warp::Runtime::Compiler::NumericType<Warp::Runtime::Compiler::NumericTypeTag::FixedPoint, numeric::fixed<16, 16> >, Warp::Utilities::FixedString<11>{"FixedPoint"}>, Warp::Parsing::TypeTreeTerm<Warp::Runtime::Compiler::NumericTypeTag::Character, Warp::Parsing::NonTerminalTerm, Warp::Runtime::Compiler::NumericType<Warp::Runtime::Compiler::NumericTypeTag::Character, char>, Warp::Utilities::FixedString<10>{"Character"}>, Warp::Parsing::TypeTreeTerm<Warp::Runtime::Compiler::NumericTypeTag::Bool, Warp::Parsing::NonTerminalTerm, Warp::Runtime::Compiler::NumericType<Warp::Runtime::Compiler::NumericTypeTag::Bool, Warp::Runtime::Compiler::WarpBool>, Warp::Utilities::FixedString<5>{"Bool"}>, Warp::Parsing::TreeTerm<Warp::Parsing::NumericLiteral::Minus, Warp::Parsing::CharTerm, '-', ctpg::associativity::no_assoc>, Warp::Parsing::TreeTerm<Warp::Parsing::NumericLiteral::Dot, Warp::Parsing::CharTerm, '.', ctpg::associativity::no_assoc>, Warp::Parsing::TreeTerm<Warp::Parsing::NumericLiteral::IntegerMark, Warp::Parsing::CharTerm, 'i', ctpg::associativity::no_assoc>, Warp::Parsing::TreeTerm<Warp::Parsing::NumericLiteral::UnsignedMark, Warp::Parsing::CharTerm, 'u', ctpg::associativity::no_assoc>, Warp::Parsing::TreeTerm<Warp::Parsing::NumericLiteral::CharacterMark, Warp::Parsing::CharTerm, 'c', ctpg::associativity::no_assoc>, Warp::Parsing::TreeTerm<Warp::Parsing::NumericLiteral::FixedMark, Warp::Parsing::StringTerm, Warp::Utilities::FixedString<3>{"xp"}, ctpg::associativity::no_assoc>, Warp::Parsing::TreeTerm<Warp::Parsing::NumericLiteral::BoolMark, Warp::Parsing::StringTerm, Warp::Utilities::FixedString<3>{"bl"}, ctpg::associativity::no_assoc>, Warp::Parsing::TypeTreeTerm<Warp::Parsing::NumericLiteral::Digits, Warp::Parsing::NonTerminalTerm, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, Warp::Utilities::FixedString<7>{"Digits"}>, Warp::Parsing::TypeTreeTerm<Warp::Parsing::NumericLiteral::AnyDecimalDigitsReduction, Warp::Parsing::NonTerminalTerm, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, Warp::Utilities::FixedString<26>{"AnyDecimalDigitsReduction"}>, Warp::Parsing::TreeTerm<Warp::Parsing::NumericLiteral::Base10Digits, Warp::Parsing::RegexTerm, Warp::Utilities::FixedString<20>{"([0-9]+)|(0d[0-9]+)"}, Warp::Utilities::FixedString<13>{"Base10Digits"}, ctpg::associativity::no_assoc>, Warp::Parsing::TreeTerm<Warp::Parsing::NumericLiteral::Base2Digits, Warp::Parsing::RegexTerm, Warp::Utilities::FixedString<9>{"0b[0-1]+"}, Warp::Utilities::FixedString<12>{"Base2Digits"}, ctpg::associativity::no_assoc>, Warp::Parsing::TreeTerm<Warp::Parsing::NumericLiteral::Base16Digits, Warp::Parsing::RegexTerm, Warp::Utilities::FixedString<15>{"0x[0-9A-Fa-f]+"}, Warp::Utilities::FixedString<13>{"Base16Digits"}, ctpg::associativity::no_assoc>, Warp::Parsing::TreeTerm<Warp::Parsing::NumericLiteral::Base8Digits, Warp::Parsing::RegexTerm, Warp::Utilities::FixedString<9>{"0o[0-7]+"}, Warp::Utilities::FixedString<12>{"Base8Digits"}, ctpg::associativity::no_assoc>, Warp::Parsing::TreeTerm<Warp::Parsing::NumericLiteral::CharacterLiteral, Warp::Parsing::RegexTerm, Warp::Utilities::FixedString<48>{"(\'[a-zA-Z~`!@#$%^&*()-=_+<>,\\.\"/?;:|{}]\')|(\' \')"}, Warp::Utilities::FixedString<17>{"CharacterLiteral"}, ctpg::associativity::no_assoc>, Warp::Parsing::TreeTerm<Warp::Parsing::NumericLiteral::BooleanLiteral, Warp::Parsing::RegexTerm, Warp::Utilities::FixedString<15>{"(true)|(false)"}, Warp::Utilities::FixedString<15>{"BooleanLiteral"}, ctpg::associativity::no_assoc>, Warp::Parsing::TreeTerm<Warp::Parsing::NumericLiteral::EscapeCharacterLiteral, Warp::Parsing::RegexTerm, Warp::Utilities::FixedString<13>{"\'\\\\[0nt\'\\\\]\'"}, Warp::Utilities::FixedString<17>{"CharacterLiteral"}, ctpg::associativity::no_assoc>, Warp::Parsing::TreeTerm<Warp::Parsing::NumericLiteral::NumericalDelinator, Warp::Parsing::CharTerm, '_', ctpg::associativity::no_assoc>, Warp::Parsing::TreeTerm<Warp::Parsing::NumericLiteral::AnyDecimalDigits, Warp::Parsing::RegexTerm, Warp::Utilities::FixedString<15>{"\\.[0-9A-Fa-f]+"}, Warp::Utilities::FixedString<17>{"AnyDecimalDigits"}, ctpg::associativity::no_assoc> >, 3, Warp::Parsing::TreeTerm<Warp::Parsing::Brackets::OpenParenthesis, Warp::Parsing::CharTerm, '(', ctpg::associativity::no_assoc>, Warp::Parsing::TreeTerm<Warp::Parsing::Brackets::CloseParenthesis, Warp::Parsing::CharTerm, ')', ctpg::associativity::no_assoc> >, 4, Warp::Parsing::TreeTerm<Warp::Parsing::MultiPurposeOperator::Equal, Warp::Parsing::CharTerm, '=', ctpg::associativity::no_assoc> >, 5, Warp::Parsing::TreeTerm<Warp::Parsing::Identifier::Identifier, Warp::Parsing::RegexTerm, Warp::Utilities::FixedString<23>{"[a-zA-Z_][a-zA-Z0-9_]+"}, Warp::Utilities::FixedString<11>{"Identifier"}, ctpg::associativity::no_assoc> >, 6, Warp::Parsing::TreeTerm<Warp::Parsing::Keyword::Let, Warp::Parsing::StringTerm, Warp::Utilities::FixedString<4>{"let"}, ctpg::associativity::no_assoc> >, 7, Warp::Parsing::TreeTerm<Warp::Parsing::Declaration::SemiColon, Warp::Parsing::CharTerm, ';', ctpg::associativity::no_assoc> >, 8, Warp::Parsing::TypeTreeTerm<Warp::Parsing::Declaration::Constant, Warp::Parsing::NonTerminalTerm, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, Warp::Utilities::FixedString<20>{"ConstantDeclaration"}> >, 9, Warp::Parsing::TypeTreeTerm<Warp::Parsing::Construct::Constant, Warp::Parsing::NonTerminalTerm, Warp::Parsing::Constant<Warp::SyntaxAnalysis::SyntaxTree::SyntaxNode, Warp::Runtime::Compiler::NumericTypeTag>, Warp::Utilities::FixedString<9>{"Constant"}> >, Warp::Runtime::Compiler::NumericTypeResolver, Warp::Runtime::Compiler::NumericTypeTag::Whole, Warp::Runtime::Compiler::NumericTypeTag::Whole> >()::<lambda(auto:222&, auto:223, auto:224, auto:225)>, ctpg::nterm<Warp::Parsing::Constant<Warp::SyntaxAnalysis::SyntaxTree::SyntaxNode, Warp::Runtime::Compiler::NumericTypeTag> >, ctpg::nterm<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, ctpg::nterm<Warp::Parsing::MathematicalExpressionParser<Warp::Parsing::Terms<Warp::Parsing::Terms<Warp::Parsing::Terms<Warp::Parsing::Terms<Warp::Parsing::Terms<Warp::Parsing::Terms<Warp::Parsing::Terms<Warp::Parsing::Terms<Warp::Parsing::Terms<Warp::Parsing::Terms<void, 0, Warp::Parsing::TreeTerm<Warp::Parsing::MathematicalExpression::Add, Warp::Parsing::CharTerm, '+', ctpg::associativity::ltor>, Warp::Parsing::TreeTerm<Warp::Parsing::MathematicalExpression::Subtract, Warp::Parsing::CharTerm, '-', ctpg::associativity::ltor> >, 1, Warp::Parsing::TreeTerm<Warp::Parsing::MathematicalExpression::Multiply, Warp::Parsing::CharTerm, '*', ctpg::associativity::ltor>, Warp::Parsing::TreeTerm<Warp::Parsing::MathematicalExpression::Divide, Warp::Parsing::CharTerm, '/', ctpg::associativity::ltor> >, 2, Warp::Parsing::TypeTreeTerm<Warp::Runtime::Compiler::NumericTypeTag::FixedPoint, Warp::Parsing::NonTerminalTerm, Warp::Runtime::Compiler::NumericType<Warp::Runtime::Compiler::NumericTypeTag::FixedPoint, numeric::fixed<16, 16> >, Warp::Utilities::FixedString<11>{"FixedPoint"}>, Warp::Parsing::TypeTreeTerm<Warp::Runtime::Compiler::NumericTypeTag::Whole, Warp::Parsing::NonTerminalTerm, Warp::Runtime::Compiler::NumericType<Warp::Runtime::Compiler::NumericTypeTag::Whole, long unsigned int>, Warp::Utilities::FixedString<6>{"Whole"}>, Warp::Parsing::TypeTreeTerm<Warp::Runtime::Compiler::NumericTypeTag::Integer, Warp::Parsing::NonTerminalTerm, Warp::Runtime::Compiler::NumericType<Warp::Runtime::Compiler::NumericTypeTag::Integer, long long int>, Warp::Utilities::FixedString<8>{"Integer"}>, Warp::Parsing::TypeTreeTerm<Warp::Runtime::Compiler::NumericTypeTag::FixedPoint, Warp::Parsing::NonTerminalTerm, Warp::Runtime::Compiler::NumericType<Warp::Runtime::Compiler::NumericTypeTag::FixedPoint, numeric::fixed<16, 16> >, Warp::Utilities::FixedString<11>{"FixedPoint"}>, Warp::Parsing::TypeTreeTerm<Warp::Runtime::Compiler::NumericTypeTag::Character, Warp::Parsing::NonTerminalTerm, Warp::Runtime::Compiler::NumericType<Warp::Runtime::Compiler::NumericTypeTag::Character, char>, Warp::Utilities::FixedString<10>{"Character"}>, Warp::Parsing::TypeTreeTerm<Warp::Runtime::Compiler::NumericTypeTag::Bool, Warp::Parsing::NonTerminalTerm, Warp::Runtime::Compiler::NumericType<Warp::Runtime::Compiler::NumericTypeTag::Bool, Warp::Runtime::Compiler::WarpBool>, Warp::Utilities::FixedString<5>{"Bool"}>, Warp::Parsing::TreeTerm<Warp::Parsing::NumericLiteral::Minus, Warp::Parsing::CharTerm, '-', ctpg::associativity::no_assoc>, Warp::Parsing::TreeTerm<Warp::Parsing::NumericLiteral::Dot, Warp::Parsing::CharTerm, '.', ctpg::associativity::no_assoc>, Warp::Parsing::TreeTerm<Warp::Parsing::NumericLiteral::IntegerMark, Warp::Parsing::CharTerm, 'i', ctpg::associativity::no_assoc>, Warp::Parsing::TreeTerm<Warp::Parsing::NumericLiteral::UnsignedMark, Warp::Parsing::CharTerm, 'u', ctpg::associativity::no_assoc>, Warp::Parsing::TreeTerm<Warp::Parsing::NumericLiteral::CharacterMark, Warp::Parsing::CharTerm, 'c', ctpg::associativity::no_assoc>, Warp::Parsing::TreeTerm<Warp::Parsing::NumericLiteral::FixedMark, Warp::Parsing::StringTerm, Warp::Utilities::FixedString<3>{"xp"}, ctpg::associativity::no_assoc>, Warp::Parsing::TreeTerm<Warp::Parsing::NumericLiteral::BoolMark, Warp::Parsing::StringTerm, Warp::Utilities::FixedString<3>{"bl"}, ctpg::associativity::no_assoc>, Warp::Parsing::TypeTreeTerm<Warp::Parsing::NumericLiteral::Digits, Warp::Parsing::NonTerminalTerm, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, Warp::Utilities::FixedString<7>{"Digits"}>, Warp::Parsing::TypeTreeTerm<Warp::Parsing::NumericLiteral::AnyDecimalDigitsReduction, Warp::Parsing::NonTerminalTerm, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, Warp::Utilities::FixedString<26>{"AnyDecimalDigitsReduction"}>, Warp::Parsing::TreeTerm<Warp::Parsing::NumericLiteral::Base10Digits, Warp::Parsing::RegexTerm, Warp::Utilities::FixedString<20>{"([0-9]+)|(0d[0-9]+)"}, Warp::Utilities::FixedString<13>{"Base10Digits"}, ctpg::associativity::no_assoc>, Warp::Parsing::TreeTerm<Warp::Parsing::NumericLiteral::Base2Digits, Warp::Parsing::RegexTerm, Warp::Utilities::FixedString<9>{"0b[0-1]+"}, Warp::Utilities::FixedString<12>{"Base2Digits"}, ctpg::associativity::no_assoc>, Warp::Parsing::TreeTerm<Warp::Parsing::NumericLiteral::Base16Digits, Warp::Parsing::RegexTerm, Warp::Utilities::FixedString<15>{"0x[0-9A-Fa-f]+"}, Warp::Utilities::FixedString<13>{"Base16Digits"}, ctpg::associativity::no_assoc>, Warp::Parsing::TreeTerm<Warp::Parsing::NumericLiteral::Base8Digits, Warp::Parsing::RegexTerm, Warp::Utilities::FixedString<9>{"0o[0-7]+"}, Warp::Utilities::FixedString<12>{"Base8Digits"}, ctpg::associativity::no_assoc>, Warp::Parsing::TreeTerm<Warp::Parsing::NumericLiteral::CharacterLiteral, Warp::Parsing::RegexTerm, Warp::Utilities::FixedString<48>{"(\'[a-zA-Z~`!@#$%^&*()-=_+<>,\\.\"/?;:|{}]\')|(\' \')"}, Warp::Utilities::FixedString<17>{"CharacterLiteral"}, ctpg::associativity::no_assoc>, Warp::Parsing::TreeTerm<Warp::Parsing::NumericLiteral::BooleanLiteral, Warp::Parsing::RegexTerm, Warp::Utilities::FixedString<15>{"(true)|(false)"}, Warp::Utilities::FixedString<15>{"BooleanLiteral"}, ctpg::associativity::no_assoc>, Warp::Parsing::TreeTerm<Warp::Parsing::NumericLiteral::EscapeCharacterLiteral, Warp::Parsing::RegexTerm, Warp::Utilities::FixedString<13>{"\'\\\\[0nt\'\\\\]\'"}, Warp::Utilities::FixedString<17>{"CharacterLiteral"}, ctpg::associativity::no_assoc>, Warp::Parsing::TreeTerm<Warp::Parsing::NumericLiteral::NumericalDelinator, Warp::Parsing::CharTerm, '_', ctpg::associativity::no_assoc>, Warp::Parsing::TreeTerm<Warp::Parsing::NumericLiteral::AnyDecimalDigits, Warp::Parsing::RegexTerm, Warp::Utilities::FixedString<15>{"\\.[0-9A-Fa-f]+"}, Warp::Utilities::FixedString<17>{"AnyDecimalDigits"}, ctpg::associativity::no_assoc> >, 3, Warp::Parsing::TreeTerm<Warp::Parsing::Brackets::OpenParenthesis, Warp::Parsing::CharTerm, '(', ctpg::associativity::no_assoc>, Warp::Parsing::TreeTerm<Warp::Parsing::Brackets::CloseParenthesis, Warp::Parsing::CharTerm, ')', ctpg::associativity::no_assoc> >, 4, Warp::Parsing::TreeTerm<Warp::Parsing::MultiPurposeOperator::Equal, Warp::Parsing::CharTerm, '=', ctpg::associativity::no_assoc> >, 5, Warp::Parsing::TreeTerm<Warp::Parsing::Identifier::Identifier, Warp::Parsing::RegexTerm, Warp::Utilities::FixedString<23>{"[a-zA-Z_][a-zA-Z0-9_]+"}, Warp::Utilities::FixedString<11>{"Identifier"}, ctpg::associativity::no_assoc> >, 6, Warp::Parsing::TreeTerm<Warp::Parsing::Keyword::Let, Warp::Parsing::StringTerm, Warp::Utilities::FixedString<4>{"let"}, ctpg::associativity::no_assoc> >, 7, Warp::Parsing::TreeTerm<Warp::Parsing::Declaration::SemiColon, Warp::Parsing::CharTerm, ';', ctpg::associativity::no_assoc> >, 8, Warp::Parsing::TypeTreeTerm<Warp::Parsing::Declaration::Constant, Warp::Parsing::NonTerminalTerm, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, Warp::Utilities::FixedString<20>{"ConstantDeclaration"}> >, 9, Warp::Parsing::TypeTreeTerm<Warp::Parsing::Construct::Constant, Warp::Parsing::NonTerminalTerm, Warp::Parsing::Constant<Warp::SyntaxAnalysis::SyntaxTree::SyntaxNode, Warp::Runtime::Compiler::NumericTypeTag>, Warp::Utilities::FixedString<9>{"Constant"}> >, Warp::Runtime::Compiler::NumericTypeResolver, Warp::Runtime::Compiler::NumericTypeTag::Whole, Warp::Runtime::Compiler::NumericTypeTag::Whole>::Expression>, ctpg::char_term> >โ€™
 2004 |     static const size_t max_rule_element_count = meta::max_v<1, Rules::n...>;
      |                                                                        ^

full log

I have a fair number of rules, I have ~30 rules to parse literals, probably about 15 to parse mathematical expressions, and I just introduced another one. I also instantiate multiple different parsers. However it could be someting like (5 * 30)^(5*15) because there are 5 types and the parsers may be gettting instantiated in a exponential way somewhere, though I dont think so, especially since the compiler has not overflowed on constexpr ops or anything.

But still, maybe I am instantiating more than I thought?

Context:
trouble commit
most recent feature (with correct commit hash)
most recent file I have been working on (with correct commit hash)

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

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.

Constexpr parsing of an array of ints

Hello!... Hope you're doing great!

I am having some difficulty parsing arrays/lists at compile time. As a minimal example, suppose we have a string literal "1, 1, 2, 3, 3, 6..." with N numbers and we're trying to parse the given list into an std::array<int, N>. At the moment, I do not how to specify grammar rules since nterm requires a full type as its value type.

Stuff like this is possible with hand-written parser since we can always statically count the numbers and put them in the array. But here it seems that we need a production rule from std::array to std::array...

It'll be great if you could give me a pointer on how to do this.

All the best.

clang is not supported?

When I try to use ctpg with clang13, clang fails to build.
It works correctly in gcc11.
Is clang not supported?

include/ctpg.hpp:1466:18: error: function 'create_regex_parser<ctpg::regex::dfa_size_analyzer>' with deduced return type cannot be used before it is defined
        auto p = create_regex_parser(a);
                 ^
include/ctpg.hpp:1460:20: note: 'create_regex_parser<ctpg::regex::dfa_size_analyzer>' declared here
    constexpr auto create_regex_parser(Builder& b);
                   ^
include/ctpg.hpp:1463:24: error: no return statement in constexpr function
    constexpr size32_t analyze_dfa_size(const char (&pattern)[N])
                       ^
include/ctpg.hpp:1612:25: error: function 'create_regex_parser<ctpg::regex::dfa_size_analyzer>' with deduced return type cannot be used before it is defined
        auto p = regex::create_regex_parser(a);
                        ^
include/ctpg.hpp:1460:20: note: 'create_regex_parser<ctpg::regex::dfa_size_analyzer>' declared here
    constexpr auto create_regex_parser(Builder& b);
                   ^
include/ctpg.hpp:1641:29: error: function 'create_regex_parser<ctpg::regex::dfa_size_analyzer>' with deduced return type cannot be used before it is defined
            auto p = regex::create_regex_parser(a);
                            ^
include/ctpg.hpp:1460:20: note: 'create_regex_parser<ctpg::regex::dfa_size_analyzer>' declared here
    constexpr auto create_regex_parser(Builder& b);
                   ^
include/ctpg.hpp:831:36: error: in-class initializer for static data member is not a constant expression
    static const size_t dfa_size = regex::analyze_dfa_size(Pattern);
                                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Parsing exponent notation in json-parser

I just saw that the to_js_number() does not work when the exponent does not have a sign (like 1.0e8).
A quick look into the JSON schema tells me that it is allowed.

image

Was this missed or is support for these not required?

Here is a simple fix anyway. I am happy to provide a pull request if this is necessary.
Just confused right now.

https://godbolt.org/z/7bo3d41K6

Ignore all whitespaces but newlines

First of all I really like your library and am very curious to learn about the implementation details and tinker around with it. I just had one question:

Is there a way to ignore all whitespaces but newlines to define a language where newlines are a syntax element yet? Like e.g. the HTTP protocol?

[Question] Is it applicable to parsing markdown?

I want to convert between 2 similar formats (DokuWiki -> Obsidian).
But I fail to describe a term "arbitrary text that is not matched by any terms, but surrounded by any recognizable terms". Like, ** any such text // and another one//**, where "**" and "//" are terms properly described to the parser generator.

Invoking undefined behaviour when using an rvalue in the constructor of stdex::cvector

This is my first pull request ๐ŸŽ†, so yeah..., but here you're invoking an undefined behaviour(for count larger then 1) by moving an rvalue into the emplace_back function count times. It'd be fine if you were to move only once, but because you're moving it more than once you can't really expect any other element after the first to be in the valid state inside the the_data member field.

ctpg/ctpg.hpp

Lines 114 to 119 in 99af8d2

constexpr cvector(T&& arg, size_t count):
the_data{}, current_size(0)
{
for (size_t i = 0; i < count; ++i)
emplace_back(std::move(arg));
}

[question] Trouble Making Argument Lists

Hello,

I don't know if this is an appropriate forum for this but I am kinda at the end of my rope here. Im at the end of the semester and need to get this in, I have been struggling for the last few days to implement function calls into my language.

I want them to be "factors" and usable in mathematical expressions (functions are just simple arithmetic expressions in my language with, argument lists (which have comparisons and logical operators).

The way I get factors right now is something like this:

////////////////////////////////  "Literals" ////////////////////////////////

non_terminal_term< Factor >( term< FunctionResult > )  //`@` is a special variable used for a contracts, nothing really to do with call syntax. //
        >= []( auto token ) {
                return std::move( Warp::Utilities::allocate_node< FunctionResult >() );
        }, 
non_terminal_term< Factor >( term< Identifier > ) 
        >= []( auto token ) {
                return std::move( Warp::Utilities::allocate_node< 
                                Warp::AbstractSyntaxTree::NodeType::Identifier 
                        >( Warp::Utilities::hash_string( token ) ) );
        }, 
non_terminal_term< Factor >( term< NaturalNumber > ) 
        >= []( auto token )
        {
                return std::move( Warp::Utilities::allocate_integral_literal_node< 
                        ResolvedType< NaturalNumber > 
                    >( token ) );
        }, 
////////////////////////////////  Multiplication/Division ////////////////////////////////

non_terminal_term< Factor >( non_terminal_term< Factor >, term< FactorMultiply >, term< NaturalNumber > ) 
        >= []( auto current_factor, auto, const auto& next_token )
            {
                return Warp::Utilities::allocate_node< FactorMultiply >( 
                        current_factor, 
                        Warp::Utilities::allocate_integral_literal_node< 
                                ResolvedType< NaturalNumber > 
                            >( next_token )
                    );
            }, 
non_terminal_term< Factor >( non_terminal_term< Factor >, term< FactorDivide >, term< NaturalNumber > ) 
        >= []( auto current_factor, auto, const auto& next_token )
            {
                return Warp::Utilities::allocate_node< FactorDivide >( 
                        current_factor, 
                        Warp::Utilities::allocate_integral_literal_node< 
                                ResolvedType< NaturalNumber > 
                            >( next_token )
                    );
            }, 
non_terminal_term< Factor >( non_terminal_term< Factor >, term< FactorMultiply >, term< Identifier > ) 
        >= []( auto current_factor, auto, const auto& next_token )
            {
                return Warp::Utilities::allocate_node< FactorMultiply >( 
                        current_factor, 
                        Warp::Utilities::allocate_node< 
                                Warp::AbstractSyntaxTree::NodeType::Identifier 
                            >( Warp::Utilities::hash_string( next_token ) )
                    );
            }, 
non_terminal_term< Factor >( non_terminal_term< Factor >, term< FactorDivide >, term< Identifier > ) 
        >= []( auto current_factor, auto, const auto& next_token )
            {
                return Warp::Utilities::allocate_node< FactorDivide >( 
                        current_factor, 
                        Warp::Utilities::allocate_node< 
                                Warp::AbstractSyntaxTree::NodeType::Identifier 
                            >( Warp::Utilities::hash_string( next_token ) )
                    );
            }, 

////////////////////////////////  Parenthesis ////////////////////////////////

non_terminal_term< ParenthesisScope >( term< OpenParenthesis >, non_terminal_term< Factor >, term< CloseParenthesis > )
        >= [] ( auto, auto factor, auto ) { return factor; }, 
non_terminal_term< Factor >( non_terminal_term< ParenthesisScope > ) 
        >= []( auto parenthesis_scope ) { return parenthesis_scope; }, 
non_terminal_term< Factor >( non_terminal_term< Factor >, term< FactorMultiply >, non_terminal_term< ParenthesisScope > ) 
        >= []( auto factor, auto, auto parenthesis_scope ) 
            {
                return Warp::Utilities::allocate_node< FactorMultiply >( 
                        factor, 
                        parenthesis_scope 
                    );
            }, 
non_terminal_term< Factor >( non_terminal_term< Factor >, term< FactorDivide >, non_terminal_term< ParenthesisScope > ) 
        >= []( auto factor, auto, auto parenthesis_scope ) 
            {
                return Warp::Utilities::allocate_node< FactorDivide >( 
                        factor, 
                        parenthesis_scope 
                    );
            }, 
////////////////////////////////  Addition/Subtraction ////////////////////////////////
non_terminal_term< Factor >( non_terminal_term< Sum > ) 
        >= []( auto sum ) {
            return sum;
        }, 
non_terminal_term< Sum >( non_terminal_term< Factor >, term< SumAdd >, non_terminal_term< Factor > ) 
        >= []( auto current_sum, auto, const auto& next_token ) 
            {
                return Warp::Utilities::allocate_node< SumAdd >( 
                        current_sum, 
                        next_token 
                    );
            }, 
non_terminal_term< Sum >( non_terminal_term< Factor >, term< SumSubtract >, non_terminal_term< Factor > ) 
        >= []( auto current_sum, auto, const auto& next_token )
            {
                return Warp::Utilities::allocate_node< SumSubtract >( 
                        current_sum, 
                        next_token 
                    );
            }, 
non_terminal_term< Expression >( non_terminal_term< Factor > ) 
        >= []( auto factor ) {
            return factor;
        }, 
//...

If I am just trying to reduce factors the following works perfectly

non_terminal_term< Call >( term< Identifier >, term< OpenParenthesis > ) 
        >= []( auto identifier, auto ) // function, auto identifier, auto )
            {
                std::cout << "Call found!\n";
                return Warp::CompilerRuntime::CallType{ 
                        Warp::Utilities::hash_string( identifier ), 
                        Warp::Utilities::VectorType< Warp::AbstractSyntaxTree::NodeVariantType >{} 
                    };
            }, 
non_terminal_term< Call >( non_terminal_term< Call >, non_terminal_term< Factor >, term< FunctionParameterNextParameter > ) 
        >= [](auto call, auto argument, auto )
            {
                std::cout << "Argument buffered!\n";
                return Warp::CompilerRuntime::CallType{ 
                        call.identifier, 
                        Warp::Utilities::VectorType< Warp::AbstractSyntaxTree::NodeVariantType >{ 
                                call.arguments, 
                                argument 
                            } 
                    };
            }, 
non_terminal_term< Factor >( non_terminal_term< Call >, non_terminal_term< Factor >, term< CloseParenthesis > ) 
        >= []( auto call, auto argument, auto )
            {
                std::cout << "Call end 0!\n";
                return Warp::Utilities::allocate_node< Warp::AbstractSyntaxTree::NodeType::FunctionCall >( 
                        call.identifier, 
                        Warp::Utilities::VectorType< Warp::AbstractSyntaxTree::NodeVariantType >{ 
                                call.arguments, 
                                argument 
                            } 
                    );
            }, 
non_terminal_term< Factor >( non_terminal_term< Call >, term< CloseParenthesis > ) 
        >= []( auto call, auto )
            {
                std::cout << "Call end 1!\n";
                return Warp::Utilities::allocate_node< Warp::AbstractSyntaxTree::NodeType::FunctionCall >( 
                        call.identifier, 
                        call.arguments 
                    );
            }

Here are the test cases

static TestSuiteType factor_calls{
        WarpTest{ true, "test( 1 )" }, 
        WarpTest{ true, "test( a )" }, 
        WarpTest{ true, "20 * test( a )" }, 
        WarpTest{ true, "20 + test( a )" }, 
        WarpTest{ true, "test( a ) * 20" }, 
        WarpTest{ true, "test( a ) + 10" }, 
        WarpTest{ true, "test( a * a )" }, 
        WarpTest{ true, "test( a(), b( q, 4, 5646, 345345 * 445656 + 34 ), rdfg * 34534 )" }, 
        WarpTest{ true, "test( a, q, 4, 5646, 345345 * 445656 + 34, rdfg * 34534 )" }, 
        WarpTest{ true, "test( ttt(), q, 4, 5646, 345345 * 445656 + 34, rdfg * 34534 )" } 
    };

But when I try to put it in the context of reducing a function the compiler seems to get into an infinite loop and wont compile the parser. To get an idea of the test cases I am working with for a whole function:

static TestSuiteType function_alternative_calls{
        WarpTest{ true, "let test( a : a < 64 ) :: test( 1 );" }, 
        WarpTest{ true, "let test( a : a < 64 ) :: test( a );" }, 
        WarpTest{ true, "let test( a : a < 64 ) :: 20 * test( a );" }, 
        WarpTest{ true, "let test( a : a < 64 ) :: 20 + test( a );" }, 
        WarpTest{ true, "let test( a : a < 64 ) :: test( a ) * 20;" }, 
        WarpTest{ true, "let test( a : a < 64 ) :: test( a ) + 10;" }, 
        WarpTest{ true, "let test( a : a < 64 ) :: test( a * a );" }, 
        WarpTest{ true, "let test( a : a < 64 ) :: test( a(), b( q, 4, 5646, 345345 * 445656 + 34 ), rdfg * 34534 );" }, 
        WarpTest{ true, "let test( a : a < 64 ) :: test( a, q, 4, 5646, 345345 * 445656 + 34, rdfg * 34534 );" }, 
        WarpTest{ true, "let test( a : a < 64 ) :: test( ttt(), q, 4, 5646, 345345 * 445656 + 34, rdfg * 34534 );" } 
    };

Its crucial I make this work so my language can be Turing complete and I can use recursion.

I am able to get all these tests with the exception of 3, here are those results:

Pass: let test( a : a < 64 ) :: test( 1 );
Pass: let test( a : a < 64 ) :: test( a );
[1:36] PARSE: Syntax error: Unexpected '('
Fail: let test( a : a < 64 ) :: 20 * test( a );
[1:38] PARSE: Syntax error: Unexpected 'Identifier'
Fail: let test( a : a < 64 ) :: 20 + test( a );
Pass: let test( a : a < 64 ) :: test( a ) * 20;
[1:37] PARSE: Syntax error: Unexpected '+'
Fail: let test( a : a < 64 ) :: test( a ) + 10;
Pass: let test( a : a < 64 ) :: test( a * a );
Pass: let test( a : a < 64 ) :: test( a(), b( q, 4, 5646, 345345 * 445656 + 34 ), rdfg * 34534 );
Pass: let test( a : a < 64 ) :: test( a, q, 4, 5646, 345345 * 445656 + 34, rdfg * 34534 );
Pass: let test( a : a < 64 ) :: test( ttt(), q, 4, 5646, 345345 * 445656 + 34, rdfg * 34534 );

Here is the code that makes that work:

//... code that analyzes function parameters tries to buffer the expression after the `::` operator
non_terminal_term< ExpressionEater >( non_terminal_term< ExpressionEater >, term< FactorMultiply >, non_terminal_term< Expression > ) 
        >= []( auto function, auto, auto factor ) {
                return subsume_function_alternative_expression< FactorMultiply >( function, factor );
            }, 
non_terminal_term< ExpressionEater >( non_terminal_term< ExpressionEater >, term< FactorDivide >, non_terminal_term< Expression > ) 
        >= []( auto function, auto, auto factor ) {
                return subsume_function_alternative_expression< FactorDivide >( function, factor );
            }, 
non_terminal_term< Call >( term< Identifier >, term< OpenParenthesis > ) 
        >= []( auto identifier, auto ) 
            {
                return Warp::CompilerRuntime::CallType{ 
                        Warp::Utilities::hash_string( identifier ), 
                        std::vector< Warp::AbstractSyntaxTree::NodeVariantType >{}
                        //Warp::Utilities::VectorType< Warp::AbstractSyntaxTree::NodeVariantType >{} 
                    };
            }, 
non_terminal_term< Call >( non_terminal_term< Call >, non_terminal_term< Factor >, term< FunctionParameterNextParameter > ) 
        >= [](auto call, auto argument, auto ) {
                call.arguments.push_back( argument );
                return call;
            }, 
non_terminal_term< CallNode >( non_terminal_term< Call >, non_terminal_term< Factor >, term< CloseParenthesis > ) 
        >= []( auto call, auto argument, auto )
            {
                call.arguments.push_back( argument );
                return Warp::Utilities::allocate_node< Warp::AbstractSyntaxTree::NodeType::FunctionCall >( 
                        call.identifier, 
                        call.arguments 
                    );
            }, 
non_terminal_term< Call >( non_terminal_term< Call >, non_terminal_term< CallNode >, term< FunctionParameterNextParameter > ) 
        >= [](auto call, auto argument, auto ) {
                call.arguments.push_back( argument );
                return call;
            }, 
non_terminal_term< CallNode >( non_terminal_term< Call >, non_terminal_term< CallNode >, term< CloseParenthesis > ) 
        >= []( auto call, auto argument, auto )
            {
                return Warp::Utilities::allocate_node< Warp::AbstractSyntaxTree::NodeType::FunctionCall >( 
                        call.identifier, 
                        call.arguments 
                    );
            }, 
non_terminal_term< CallNode >( non_terminal_term< Call >, term< CloseParenthesis > ) 
        >= []( auto call, auto )
            {
                return Warp::Utilities::allocate_node< Warp::AbstractSyntaxTree::NodeType::FunctionCall >( 
                        call.identifier, 
                        call.arguments 
                    );
            }, 
non_terminal_term< Expression >( non_terminal_term< CallNode > )
        >= []( auto call ) {
                return call;
            }

As you may be able to see this is a bit of a "hack" partially re-implementing factors towards the top there.
It cant do sums and it cant take into account any products before the function call.

I have tried everything you can see some of the changes I have made in detail on this branch but to summarize, the main problem is though if I try to make this "complete" in any sense where it loops back to a factor or its equivalent and treats the call like a factor (as I want it too) the compiler infinitely loops, even though it works just fine when reducing just a factor. It doesent seem to matter where I put the terminal terms, non-terminal-terms, etc.

One thing I have also tried is never "leaving" factor evaluation.

non_terminal_term< Factor >( non_terminal_term< Factor >, term< FactorMultiply >, term< Identifier >, term< OpenParenthesis > ) 
        >= []( auto factor, auto, auto identifier, auto ) 
            {
                return Warp::Utilities::allocate_node< FactorMultiply >( 
                        factor, 
                        Warp::Utilities::allocate_node< Warp::AbstractSyntaxTree::NodeType::FunctionCall >( 
                                Warp::Utilities::hash_string( identifier ), 
                                std::vector< Warp::AbstractSyntaxTree::NodeVariantType >{} 
                                // Warp::Utilities::VectorType< Warp::AbstractSyntaxTree::NodeVariantType >{} 
                            ) 
                    );
            }, 
non_terminal_term< Factor >( non_terminal_term< Factor >, non_terminal_term< Factor >, term< FunctionParameterNextParameter > ) 
        >= []( auto operation_call, auto argument, auto )
            {
                if( Warp::Utilities::is_bi_node( operation_call ) == false ) 
                {
                    std::cerr << "ERROR!!!: Attempt to parse function call failed! "
                            << "Bi-Node not found where expected (Factor, Factor, NextParmaeterToken(Comma))! "
                            << "Returning first factor.\n";
                }
                auto proxy = Warp::Utilities::bi_node_proxy( operation_call ).value();
                if( Warp::Utilities::tag_is< Warp::AbstractSyntaxTree::NodeType::FunctionCall >( proxy.right ) == true )
                {
                    std::cerr << "ERROR!!!: Attempt to parse function call failed! "
                            << "FunctionCall not found where expected (Factor (left: Factor, right: FunctionCall), "
                            << "Factor, NextParmaeterToken(Comma))! Returning first factor.\n";
                }
                auto call = static_cast< Warp::CompilerRuntime::CallType* >( proxy.right->get_data() );
                call->arguments.push_back( argument );
                return operation_call;
            }, 
non_terminal_term< Factor >( non_terminal_term< Factor >, non_terminal_term< Factor >, term< CloseParenthesis > ) 
        >= []( auto operation_call, auto argument, auto )
            {
                if( Warp::Utilities::is_bi_node( operation_call ) == false ) 
                {
                    std::cerr << "ERROR!!!: Attempt to parse function call failed! "
                            << "Bi-Node not found where expected (Factor, Factor, CloseParenthesis)! "
                            << "Returning first factor.\n";
                }
                auto proxy = Warp::Utilities::bi_node_proxy( operation_call ).value();
                if( Warp::Utilities::tag_is< Warp::AbstractSyntaxTree::NodeType::FunctionCall >( proxy.right ) == true )
                {
                    std::cerr << "ERROR!!!: Attempt to parse function call failed! "
                            << "FunctionCall not found where expected (Factor (left: Factor, right: FunctionCall), "
                            << "Factor, CloseParenthesis)! Returning first factor.\n";
                }
                auto call = static_cast< Warp::CompilerRuntime::CallType* >( proxy.right->get_data() );
                call->arguments.push_back( argument );
                return operation_call;
            } 

Unfortunately its the same result :(

An attempt at some pseudo - BNF's I have tried

call := 
            | <identifier > (
            | <call> <factor> , 
            | <complete-call> , 
complete-call = 
            | <call> < factor > )
            | <call> )
factor/expression = complete-call
call := 
            | <identifier > (
            | <call> <argument-list> )
            | <call> )
argument-list = 
            | <factor> ,
            | <argument-list> <factor>, 
factor := 
            | <factor> * <literal>
            | <factor> / <literal>
            | <factor> * <identifier> (
            | <factor>, 
            | <factor> )

All these in various permutations and versions (again you can look at my changes on this branch

Again I don't know if this is an appropriate forum I apologize if its not, any help would really be appreciated, I'm really under the wire.

Lifetime Warning from VC++

Not sure if this is a valid warning, but here it is:

Severity	Code	Description	Project	File	Line	Suppression State
Warning	C26800	Use of a moved from object: ''(*start)'' (lifetime.1).	scratchpad	D:\Ben\Dev\ctpg-master\include\ctpg.hpp	2503	

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.