Library: implementation of syntax-branching
...is now easy and follows entirely the scheme established thus far
This commit is contained in:
parent
e3fe8fe380
commit
1a3781bbc0
3 changed files with 194 additions and 31 deletions
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue