ZoneCodeGenerator: Add always to CommandFile condition and allow multiple conditions linked together in a chain

This commit is contained in:
Jan 2019-10-02 16:26:16 +02:00
parent 785e2c9bfb
commit ac1d426fb2

View File

@ -11,83 +11,109 @@ namespace ZoneCodeGenerator.Parsing.CommandFile.Tests
{ {
private const string TypeNameToken = "typeName"; private const string TypeNameToken = "typeName";
private const string ConditionStatementTag = "conditionStatement"; private const string ConditionStatementTag = "conditionStatement";
private const string ConditionChainTag = "conditionChain"; private const string ConditionTag = "condition";
private const string ConditionChainLinkTag = "conditionChainLink"; private const string ConditionRelationTag = "conditionRelation";
private const string OperationTag = "operation"; private const string OperationTag = "operation";
private const string OperandTag = "operand"; private const string OperandTag = "operand";
private const string ConditionChainLinkTag = "conditionChainLink";
private const string ConditionChainTag = "conditionChain";
// operand ::= <typename> <array>+ | <number> | true | false
private static readonly TokenMatcher operand = new MatcherGroupOr( private static readonly TokenMatcher operand = new MatcherGroupOr(
new MatcherGroupAnd( new MatcherGroupAnd(
new MatcherTypename(), new MatcherTypename(),
new MatcherGroupLoop(MatcherGroupLoop.LoopMode.ZeroOneMultiple, new MatcherArray()) new MatcherGroupLoop(MatcherGroupLoop.LoopMode.ZeroOneMultiple, new MatcherArray())
), ),
new MatcherNumber(), new MatcherNumber(),
new MatcherLiteral("true"), new MatcherLiteral("true"),
new MatcherLiteral("false") new MatcherLiteral("false")
).WithTag(OperandTag); ).WithTag(OperandTag);
// operation ::= + | - | * | / | << | >>
private static readonly TokenMatcher operation = new MatcherGroupOr( private static readonly TokenMatcher operation = new MatcherGroupOr(
new MatcherLiteral("+"), new MatcherLiteral("+"),
new MatcherLiteral("-"), new MatcherLiteral("-"),
new MatcherLiteral("*"), new MatcherLiteral("*"),
new MatcherLiteral("/"), new MatcherLiteral("/"),
new MatcherGroupAnd(new MatcherLiteral("<"), new MatcherLiteral("<")), new MatcherGroupAnd(new MatcherLiteral("<"), new MatcherLiteral("<")),
new MatcherGroupAnd(new MatcherLiteral(">"), new MatcherLiteral(">")) new MatcherGroupAnd(new MatcherLiteral(">"), new MatcherLiteral(">"))
).WithTag(OperationTag); ).WithTag(OperationTag);
// conditionStatement ::= ( <conditionStatement> ) | <operand> [<operation> <operand>]
private static readonly TokenMatcher conditionStatement = new MatcherGroupOr( private static readonly TokenMatcher conditionStatement = new MatcherGroupOr(
new MatcherGroupAnd( new MatcherGroupAnd(
new MatcherLiteral("("), new MatcherLiteral("("),
new MatcherWithTag(ConditionStatementTag), new MatcherWithTag(ConditionStatementTag),
new MatcherLiteral(")") new MatcherLiteral(")")
), ),
new MatcherGroupAnd( new MatcherGroupAnd(
new MatcherWithTag(OperandTag), new MatcherWithTag(OperandTag),
new MatcherGroupOptional(new MatcherGroupAnd( new MatcherGroupOptional(new MatcherGroupAnd(
new MatcherWithTag(OperationTag), new MatcherWithTag(OperationTag),
new MatcherWithTag(OperandTag) new MatcherWithTag(OperandTag)
)) ))
) )
).WithTag(ConditionStatementTag); ).WithTag(ConditionStatementTag);
private static readonly TokenMatcher conditionChainLink = new MatcherGroupOr( // conditionChainLink ::= == | != | <= | >= | < | >
new MatcherGroupAnd(new MatcherLiteral("="), new MatcherLiteral("=")), private static readonly TokenMatcher conditionRelation = new MatcherGroupOr(
new MatcherGroupAnd(new MatcherLiteral("!"), new MatcherLiteral("=")), new MatcherGroupAnd(new MatcherLiteral("="), new MatcherLiteral("=")),
new MatcherGroupAnd(new MatcherLiteral("<"), new MatcherLiteral("=")), new MatcherGroupAnd(new MatcherLiteral("!"), new MatcherLiteral("=")),
new MatcherGroupAnd(new MatcherLiteral(">"), new MatcherLiteral("=")), new MatcherGroupAnd(new MatcherLiteral("<"), new MatcherLiteral("=")),
new MatcherLiteral("<"), new MatcherGroupAnd(new MatcherLiteral(">"), new MatcherLiteral("=")),
new MatcherLiteral(">") new MatcherLiteral("<"),
).WithTag(ConditionChainLinkTag); new MatcherLiteral(">")
).WithTag(ConditionRelationTag);
private static readonly TokenMatcher conditionChain = new MatcherGroupAnd( // condition ::= <conditionStatement> <conditionRelation> <conditionStatement>
private static readonly TokenMatcher condition = new MatcherGroupAnd(
new MatcherWithTag(ConditionStatementTag), new MatcherWithTag(ConditionStatementTag),
new MatcherWithTag(ConditionChainLinkTag), new MatcherWithTag(ConditionRelationTag),
new MatcherWithTag(ConditionStatementTag) new MatcherWithTag(ConditionStatementTag)
).WithTag(ConditionChainTag); ).WithTag(ConditionTag);
private static readonly TokenMatcher[] matchers = { // conditionChainLink ::= && | ||
private static readonly TokenMatcher conditionChainLink = new MatcherGroupOr(
new MatcherGroupAnd(new MatcherLiteral("&"), new MatcherLiteral("&")),
new MatcherGroupAnd(new MatcherLiteral("|"), new MatcherLiteral("|"))
).WithTag(ConditionChainLinkTag);
// conditionChain ::= <condition> (<conditionChainLink> <condition>)*
private static readonly TokenMatcher conditionChain = new MatcherGroupAnd(
new MatcherWithTag(ConditionTag),
new MatcherGroupLoop(MatcherGroupLoop.LoopMode.ZeroOneMultiple, new MatcherGroupAnd(
new MatcherWithTag(ConditionChainLinkTag),
new MatcherWithTag(ConditionTag)
))
).WithTag(ConditionChainTag);
// set condition <typename> (always | never | <conditionChain>);
private static readonly TokenMatcher[] matchers =
{
new MatcherLiteral("set"), new MatcherLiteral("set"),
new MatcherLiteral("condition"), new MatcherLiteral("condition"),
new MatcherTypename().WithName(TypeNameToken), new MatcherTypename().WithName(TypeNameToken),
new MatcherGroupOr( new MatcherGroupOr(
new MatcherLiteral("always"),
new MatcherLiteral("never"), new MatcherLiteral("never"),
new MatcherWithTag(ConditionChainTag) new MatcherWithTag(ConditionChainTag)
), ),
new MatcherLiteral(";") new MatcherLiteral(";")
}; };
public TestCondition() : base(matchers) public TestCondition() : base(matchers)
{ {
AddTaggedMatcher(conditionChain);
AddTaggedMatcher(conditionChainLink);
AddTaggedMatcher(conditionStatement);
AddTaggedMatcher(operation);
AddTaggedMatcher(operand); AddTaggedMatcher(operand);
AddTaggedMatcher(operation);
AddTaggedMatcher(conditionStatement);
AddTaggedMatcher(conditionRelation);
AddTaggedMatcher(condition);
AddTaggedMatcher(conditionChainLink);
AddTaggedMatcher(conditionChain);
} }
protected override void ProcessMatch(ICommandParserState state) protected override void ProcessMatch(ICommandParserState state)
{ {
} }
} }
} }