public ConfiguredModel( ParsedJewelryModel model, List <string> configIds, ExpressionTerms expressionTerms) { _model = model; _expressionTerms = expressionTerms; if (configIds.Count != _model.Configurations.Count) { throw new ApplicationException( $"Could not parse model configuration values of configIDs '{string.Join(_expressionTerms.SkuSeparator, configIds)}'. Actual model config number: {model.Configurations.Count}!"); } model.Configurations = model.Configurations.OrderBy(c => c.Order).ToList(); Configs = new List <SpecificModelConfig>(); for (var i = 0; i < model.Configurations.Count; ++i) { Configs.Add(new SpecificModelConfig(model.Configurations[i], configIds[i])); } }
public CodeGrammar() { Func <IList <char>, string> bs = hit => new string(hit.ToArray()); Func <IList <string>, string> js = hit => string.Concat(hit.ToArray()); var escapeSequence = Ch('\\').And(Ch(c => true)).Build(hit => "\\" + hit.Down); var quotHunks = Rep1(ChNot('\"', '\\')).Build(bs) .Or(escapeSequence); var quotStringLiteral = Snip(Ch('\"').And(Rep(quotHunks)).And(Ch('\"')), hit => "\"" + js(hit.Left.Down) + "\""); var quotVerbatimPiece = Ch("\"\"").Or(ChNot('\"').Build(ch => new string(ch, 1))); var quotVerbatimLiteral = Snip(Ch("@\"").And(Rep(quotVerbatimPiece)).And(Ch('"')), hit => "@\"" + js(hit.Left.Down) + "\""); var aposHunks = Snip(Rep1(ChNot('\'', '\\', '\"'))) .Or(Snip(escapeSequence)) .Or(Swap(Ch('\"'), "\\\"")); var aposStringLiteral = Snip(Swap(Ch('\''), "\"").And(Snip(Rep(aposHunks))).And(Swap(Ch('\''), "\""))); // @' " '' ' becomes @" "" ' " var aposVerbatimPiece = Swap(Ch("''"), "'") .Or(Swap(Ch('\"'), "\"\"")) .Or(Snip(ChNot('\''))); var aposVerbatimLiteral = Snip(Swap(Ch("@'"), "@\"").And(Snip(Rep(aposVerbatimPiece))).And(Swap(Ch('\''), "\""))); var stringLiteral = TkStr(quotStringLiteral.Or(quotVerbatimLiteral).Or(aposStringLiteral).Or(aposVerbatimLiteral)); _stringLiteral = stringLiteral; var SpecialCharCast = Snip(Ch("(char)'").And(ChNot('\'', '\\').Build(ch => ch.ToString()).Or(escapeSequence)).And(Ch('\'')), hit => "(char)'" + hit.Left.Down + "'"); var oneLineComment = Snip(Ch("//").And(Rep(ChNot('\r', '\n'))), hit => "//" + bs(hit.Down)); var multiLineComment = Snip(Ch("/*").And(Rep(Ch(c => true).Unless(Ch("*/")))).And(Ch("*/")), hit => "/*" + bs(hit.Left.Down) + "*/"); // A Unicode character of the class Pc var connectingCharacter = Ch(c => char.GetUnicodeCategory(c) == UnicodeCategory.ConnectorPunctuation); // A Unicode character of classes Mn or Mc var combiningCharacter = Ch(c => char.GetUnicodeCategory(c) == UnicodeCategory.NonSpacingMark || char.GetUnicodeCategory(c) == UnicodeCategory.SpacingCombiningMark); // A Unicode character of the class Cf var formattingCharacter = Ch(c => char.GetUnicodeCategory(c) == UnicodeCategory.Format); var identifierStartCharacter = Ch(char.IsLetter).Or(Ch('_')); var identifierPartCharacter = Ch(char.IsLetterOrDigit).Or(connectingCharacter).Or(combiningCharacter).Or(formattingCharacter); var identifierOrKeyword = identifierStartCharacter.And(Rep(identifierPartCharacter)) .Build(hit => hit.Left + new string(hit.Down.ToArray())); var keyword = Snip(Ch("abstract").Or(Ch("as")).Or(Ch("base")).Or(Ch("bool")).Or(Ch("break")) .Or(Ch("byte")).Or(Ch("case")).Or(Ch("catch")).Or(Ch("char")).Or(Ch("checked")) .Or(Ch("class")).Or(Ch("const")).Or(Ch("continue")).Or(Ch("decimal")).Or(Ch("default")) .Or(Ch("delegate")).Or(Ch("double")).Or(Ch("do")).Or(Ch("else")).Or(Ch("enum")) .Or(Ch("event")).Or(Ch("explicit")).Or(Ch("extern")).Or(Ch("false")).Or(Ch("finally")) .Or(Ch("fixed")).Or(Ch("float")).Or(Ch("foreach")).Or(Ch("for")).Or(Ch("goto")) .Or(Ch("if")).Or(Ch("implicit")).Or(Ch("int")).Or(Ch("in")).Or(Ch("interface")) .Or(Ch("internal")).Or(Ch("is")).Or(Ch("lock")).Or(Ch("long")).Or(Ch("namespace")) .Or(Ch("new")).Or(Ch("null")).Or(Ch("object")).Or(Ch("operator")).Or(Ch("out")) .Or(Ch("override")).Or(Ch("params")).Or(Ch("private")).Or(Ch("protected")).Or(Ch("public")) .Or(Ch("readonly")).Or(Ch("ref")).Or(Ch("return")).Or(Ch("sbyte")).Or(Ch("sealed")) .Or(Ch("short")).Or(Ch("sizeof")).Or(Ch("stackalloc")).Or(Ch("static")).Or(Ch("string")) .Or(Ch("struct")).Or(Ch("switch")).Or(Ch("this")).Or(Ch("throw")).Or(Ch("true")) .Or(Ch("try")).Or(Ch("typeof")).Or(Ch("uint")).Or(Ch("ulong")).Or(Ch("unchecked")) .Or(Ch("unsafe")).Or(Ch("ushort")).Or(Ch("using")).Or(Ch("virtual")).Or(Ch("void")) .Or(Ch("volatile")).Or(Ch("while"))).NotNext(identifierPartCharacter); var availableIdentifier = Snip(identifierOrKeyword.Unless(keyword)) .Or(Swap(Ch("class"), "@class")); var identifier = availableIdentifier .Or(Snip(Ch('@').And(identifierOrKeyword), hit => "@" + hit.Down)); // parsing late bound properties #a.b.c into Eval("a.b.c") var dotProperty = Snip(Ch('.').And(identifierOrKeyword), hit => hit.Left + hit.Down); var formatAppendage = Swap(Opt(Rep(Ch(' ', '\t'))) .And(Ch('\"').And(Rep1(ChNot('\"'))).And(Ch('\"')) .Or(Ch('\'').And(Rep1(ChNot('\''))).And(Ch('\'')))), hit => ", \"{0:" + new string(hit.Down.Left.Down.ToArray()) + "}\""); var lateBound = Ch('#') .And(Snip(identifierOrKeyword)) .And(Snip(Rep(dotProperty))) .And(Opt(formatAppendage)) .Build(hit => (IList <Snippet>) new Snippets("Eval(\"") .Concat(hit.Left.Left.Down) .Concat(hit.Left.Down) .Concat(new Snippets("\"")) .Concat(hit.Down ?? new Snippet[0]) .Concat(new Snippets(")")) .ToList()); var codeStretch = Snip(Rep1( Swap(Ch("[["), "<") .Or(Swap(Ch("]]"), ">")) .Or(lateBound) .Or(Snip(ChNot('\"', '\'', '{', '}', '(', ')'))) .Unless(identifier.Or(keyword).Or(SpecialCharCast)) .Unless(Ch("%>").Or(Ch("@\"")).Or(Ch("@'")).Or(Ch("//")).Or(Ch("/*"))))); Func <ParseAction <string>, ParseAction <IList <Snippet> > > limitedCodeStretch = limit => Snip(Rep1( Swap(Ch("[["), "<") .Or(Swap(Ch("]]"), ">")) .Or(lateBound) .Or(Snip(ChNot('\"', '\'', '{', '}', '(', ')'))) .Unless(identifier.Or(keyword).Or(SpecialCharCast)) .Unless(limit.Or(Ch("@\"")).Or(Ch("@'")).Or(Ch("//")).Or(Ch("/*"))))); // braced ::= '{' + terms + '}' var braced = Snip(Snip(Ch('{')).And((ParseAction <IList <Snippet> >)FnTerms).And(Snip(Ch('}')))); // parens ::= '(' + terms + ')' var parens = Snip(Snip(Ch('(')).And((ParseAction <IList <Snippet> >)FnTerms).And(Snip(Ch(')')))).Unless(SpecialCharCast); // ExpressionTerms ::= (dquot | aquot | braced | codeStretch | specialCharCast)* ExpressionTerms = Snip(Rep1( stringLiteral .Or(braced) .Or(parens) .Or(codeStretch) .Or(identifier) .Or(keyword) .Or(SpecialCharCast) .Or(oneLineComment) .Or(multiLineComment) )).Or(EmptySnip()); LimitedExpressionTerms = limit => Snip(Rep1( stringLiteral .Or(braced) .Or(parens) .Or(limitedCodeStretch(limit)) .Or(identifier) .Or(keyword) .Or(SpecialCharCast) .Or(oneLineComment) .Or(multiLineComment) )).Or(EmptySnip()); Expression = ExpressionTerms.Build(hit => new Snippets(hit)); LimitedExpression = limit => LimitedExpressionTerms(limit).Build(hit => new Snippets(hit)); var statementPiece = Swap(Ch("[["), "<") .Or(Swap(Ch("]]"), ">")) .Or(lateBound) .Or(Snip(ChNot('\"', '\''))) .Unless(SpecialCharCast) .Unless(Ch("@\"").Or(Ch("@'")).Or(Ch("//")).Or(Ch("/*"))); var statement1Stretch = Snip(Rep1(statementPiece.Unless(Ch('\r', '\n')))); var statement2Stretch = Snip(Rep1(statementPiece.Unless(Ch("%>")))); // Statement1 ::= (dquot | aquot | statement1Stretch | specialCharCast)* Statement1 = Snip(Rep( stringLiteral .Or(statement1Stretch) .Or(SpecialCharCast) .Or(oneLineComment) .Or(multiLineComment))); // Statement2 ::= (dquot | aquot | statement2Stretch | specialCharCast)* Statement2 = Snip(Rep( stringLiteral .Or(statement2Stretch) .Or(SpecialCharCast) .Or(oneLineComment) .Or(multiLineComment))); }
public VariablesEvaluator( AppSettings appSettings) { _expressionTerms = appSettings.ExpressionTerms; }