Library: implementation of syntax-branching

...is now easy and follows entirely the scheme established thus far
This commit is contained in:
Fischlurch 2025-01-22 02:21:39 +01:00
parent e3fe8fe380
commit 1a3781bbc0
3 changed files with 194 additions and 31 deletions

View file

@ -320,6 +320,41 @@ namespace util {
}
/** accept sequence of two parse functions */
template<class C1, class C2>
auto
branchedConnex (C1&& connex1, C2&& connex2)
{
using R1 = typename decay_t<C1>::Result;
using R2 = typename decay_t<C2>::Result;
using SumResult = typename _Join<AltModel, R1, R2>::Result;
using SumEval = Eval<SumResult>;
return Connex{[conL = forward<C1>(connex1)
,conR = forward<C2>(connex2)
]
(StrView toParse) -> SumEval
{
auto eval1 = conL.parse (toParse);
if (eval1.result)
{
uint endBranch1 = eval1.consumed;
return SumEval{SumResult::mark_left (move(*eval1.result))
,endBranch1
};
}
auto eval2 = conR.parse (toParse);
if (eval2.result)
{
uint endBranch2 = eval2.consumed;
return SumEval{SumResult::mark_right (move(*eval2.result))
,endBranch2
};
}
return SumEval{std::nullopt};
}};
}
template<class PAR>
class Syntax;
@ -427,6 +462,15 @@ using Sigi = typename _Fun<PFun>::Sig;
,Parser{forward<SPEC> (clauseDef)}));
}
template<typename SPEC>
auto
alt (SPEC&& clauseDef)
{
return accept(
branchedConnex (move(parse_)
,Parser{forward<SPEC> (clauseDef)}));
}
private:
Eval<Result>&
eval()

View file

@ -135,10 +135,17 @@ namespace test {
}
/** @test define a sequence of syntax structures to match by parse. */
/** @test define a sequence of syntax structures to match by parse.
* - first demonstrate explicitly how the consecutive parsing works
* and how both models are combined into a product model (tuple)
* - demonstrate how leading whitespace is skipped automatically
* - then perform the same parse with a Syntax clause build with
* the `seq()` builder-DSL
* - extend this Syntax by adding a further sequential clause.
*/
void
acceptSequential()
{
{ //_______________________________________________
// Demonstration: how sequence combinator works....
auto term1 = buildConnex ("hello");
auto term2 = buildConnex ("world");
@ -185,6 +192,7 @@ namespace test {
CHECK (not term2.parse(" old ").result);
//___________________________________________________
// DSL parse clause builder: a sequence of terminals...
auto syntax = accept("hello").seq("world");
@ -213,9 +221,12 @@ namespace test {
}
/** @test TODO WIP define alternative syntax structures to match by parse.
* - first demonstrate how a model with alternative branches can be
* populated and gradually extended while searching for a match.
* - then show explicitly the logic to check and select branches
* and construct the corresponding sum-model