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.
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:
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 );
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;
}
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:
If I am just trying to reduce factors the following works perfectly
Here are the test cases
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:
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:
Here is the code that makes that work:
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.
Unfortunately its the same result :(
An attempt at some pseudo - BNF's I have tried
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.