public Grammar(ISettings settings) { var universeSign = settings.UniverseSign; var emptySetSign = settings.EmptySetSign; var isPrefixNegation = settings.IsPrefixNegation; var prefixNegationSign = settings.PrefixNegation; var postfixNegationSign = settings.PostfixNegation; var negationSign = isPrefixNegation ? prefixNegationSign : postfixNegationSign; var unionSign = settings.Union; var intersectionSign = settings.Intersection; var differenceSign = settings.Difference; var symmetricDifferenceSign = settings.SymmetricDifference; Set = Token.EqualTo(TokenType.Set).Select(x => (Expression) new Set(x.ToStringValue())); UniverseSet = Token.EqualTo(TokenType.UniverseSet).Select(_ => (Expression) new Set(universeSign)); EmptySet = Token.EqualTo(TokenType.EmptySet).Select(_ => (Expression) new Set(emptySetSign)); Variable = Token.EqualTo(TokenType.Variable).Select(x => (Expression) new Variable(x.ToStringValue())); ExpressionInParens = from lparen in Token.EqualTo(TokenType.LParen) from expr in Parse.Ref(() => SymmetricDifference) from rparen in Token.EqualTo(TokenType.RParen) select expr; Factor = Set.Try() .Or(UniverseSet).Try() .Or(EmptySet).Try() .Or(Variable).Try() .Or(ExpressionInParens).Try(); PrefixNegation = from tokens in Token.EqualTo(TokenType.PrefixNegation).AtLeastOnce() from expr in Parse.Ref(() => Union) select CreateNegationOperation(negationSign, isPrefixNegation, expr, tokens.Length); PostfixNegation = from factor in Factor from tokens in Token.EqualTo(TokenType.PostfixNegation).AtLeastOnce() select CreateNegationOperation(negationSign, isPrefixNegation, factor, tokens.Length); Term = PostfixNegation.Try().Or(PrefixNegation).Try().Or(Factor); Difference = Parse.Chain( Token.EqualTo(TokenType.Difference).Select(_ => differenceSign), Term, (value, child1, child2) => new Difference(value, child1, child2)); Intersection = Parse.Chain( Token.EqualTo(TokenType.Intersection).Select(_ => intersectionSign), Difference, (value, child1, child2) => new Intersection(value, child1, child2)); Union = Parse.Chain( Token.EqualTo(TokenType.Union).Select(_ => unionSign), Intersection, (value, child1, child2) => new Union(value, child1, child2)); SymmetricDifference = Parse.Chain( Token.EqualTo(TokenType.SymmetricDifference).Select(_ => symmetricDifferenceSign), Union, (value, child1, child2) => new SymmetricDifference(value, child1, child2)); }
public void TokenChainFailWithMultiTokenOperator() { // Addition is represented with operator '++' // If we only have one '+', ensure we get error var nPlusPlusN = Parse.Chain( Token.EqualTo('+').IgnoreThen(Token.EqualTo('+')), Token.EqualTo('1').Value(1), (opr, val1, val2) => val1 + val2); AssertParser.FailsAt(nPlusPlusN, "1+1", 2); }
public void ChainFailWithMultiTokenOperator() { // Addition is represented with operator '++' // If we only have one '+', ensure we get error var nPlusPlusN = Parse.Chain( Character.EqualTo('+').IgnoreThen(Character.EqualTo('+')), Numerics.IntegerInt32, (opr, val1, val2) => val1 + val2); AssertParser.FailsAt(nPlusPlusN, "1+1", 2); }
public void SuccessWithLongChains() { const int chainLength = 5000; string input = string.Join("+", Enumerable.Repeat("1", chainLength)); var chainParser = Parse.Chain( Character.EqualTo('+'), Numerics.IntegerInt32, (opr, val1, val2) => val1 + val2); AssertParser.SucceedsWith(chainParser, input, chainLength); }
public void TokenSuccessWithLongChains() { const int chainLength = 5000; string input = string.Join("+", Enumerable.Repeat("1", chainLength)); var chainParser = Parse.Chain( Token.EqualTo('+'), Token.EqualTo('1').Value(1), (opr, val1, val2) => val1 + val2); AssertParser.SucceedsWith(chainParser, input, chainLength); }