protected virtual string GetMacroName(string typename, AttributeParser att, out string[] args, out string outputname) { var(typea0, macroname) = att.GetArgument(0); switch (typea0) { case ArgumentType.Null: args = new[] { att.GetStrippedArgument(0), att.GetStrippedArgument(1), att.GetStrippedArgument(2) }; macroname = "Any"; break; case ArgumentType.String: args = new[] { att.GetStrippedArgument(1), att.GetStrippedArgument(2), att.GetStrippedArgument(3) }; break; default: args = new[] { att.GetStrippedArgument(0), att.GetStrippedArgument(1), att.GetStrippedArgument(2) }; break; } if (!macroname.EndsWith(".csmacro")) { macroname = $"{AttributeName}.{macroname}.csmacro"; } if (string.IsNullOrEmpty(args[0])) { args[0] = att.Name; } // ReSharper disable once InvokeAsExtensionMethod outputname = RegexHelper.NoInvalidChars($"{typename}.{args[0]}.{Prefix}Auto.cs"); return(macroname); }
public void TestAttributeParser() { var data4 = new ParsableData("base KNZ:varchar(len=\"50\", primary_key=\"true\");"); var p4 = new AttributeParser(data4); var result4 = p4.Parse(); Console.WriteLine($"Result4: {result4.AttributeType} {result4.Name} {result4.Parameters.Count}"); data4 = new ParsableData("base KURZBEZ:varchar ( len = \"100\" ) ; "); p4 = new AttributeParser(data4); result4 = p4.Parse(); Console.WriteLine($"Result4: {result4.AttributeType} {result4.Name} {result4.Parameters.Count}"); data4 = new ParsableData("fact Anzahl_F:decimal(len=\"1,0\",\n\t default=\"1\"); // ein default=\"1\" wäre hier noch nett"); p4 = new AttributeParser(data4); result4 = p4.Parse(); Console.WriteLine($"Result4: {result4.AttributeType} {result4.Name} {result4.Parameters.Count}"); data4 = new ParsableData("ref JaNein.KNZ as Zulassung; // Zulassung_JaNein"); p4 = new AttributeParser(data4); result4 = p4.Parse(); Console.WriteLine($"Result4: {result4.AttributeType} {result4.InterfaceName}.{result4.FieldName} {result4.Alias}"); // Neuer Testfall: ref-Attribute sollen auch Primärschlüssel-Bestandteile sein können! data4 = new ParsableData("ref Tag.KNZ(primary_key=\"true\");"); p4 = new AttributeParser(data4); result4 = p4.Parse(); Console.WriteLine($"Result4: {result4.AttributeType} {result4.InterfaceName}.{result4.FieldName} {result4.Alias}"); }
public ParserState() { _state = new RubberduckParserState(); _attributeParser = new AttributeParser(new ModuleExporter()); _state.StateChanged += _state_StateChanged; }
private static string AppendCreateDictionaryLocalVariable(string dictionary, CodeDomClassBuilder builder) { var parser = new AttributeParser(dictionary); parser.Parse(); var keyValuePairType = new CodeTypeReference(typeof(KeyValuePair<string,object>)); var createDictionaryMethod = new CodeMethodInvokeExpression(); foreach (var attribute in parser.Attributes) { var newKeyValueExpression = new CodeObjectCreateExpression {CreateType = keyValuePairType}; var keyExpression = new CodePrimitiveExpression {Value = attribute.Name}; newKeyValueExpression.Parameters.Add(keyExpression); if (attribute.Type == ParsedAttributeType.String) { AppendStringDictValue(attribute, newKeyValueExpression); } else { newKeyValueExpression.Parameters.Add(new CodeSnippetExpression { Value = attribute.Value }); } createDictionaryMethod.Parameters.Add(newKeyValueExpression); } var getDictionaryMethod = new CodeMethodReferenceExpression { MethodName = "GetDictionaryFromKeyValue", TargetObject = new CodeVariableReferenceExpression { VariableName = "NHamlMonoRailView" } }; createDictionaryMethod.Method = getDictionaryMethod; var variableName = string.Format("nhamlTempDictionary{0}", tempDictionaryCount); tempDictionaryCount++; var dictionaryDecleration = new CodeVariableDeclarationStatement { InitExpression = createDictionaryMethod, Name = variableName, Type = new CodeTypeReference(typeof (IDictionary<string, object>)) }; builder.RenderMethod.Statements.Add(dictionaryDecleration); return variableName; }
public void Empty() { var parser = new AttributeParser(""); parser.Parse(); Assert.AreEqual(0, parser.Attributes.Count); }
protected AbsWalkerTypeWithAttributeResult(TypeDeclarationSyntax typeDeclaration, AttributeSyntax attribute) : base(typeDeclaration) { Attribute = new AttributeParser(attribute); var alist = (AttributeListSyntax)attribute.Parent; AttributeList = alist.Attributes.Select(a => new AttributeParser(a)).ToArray(); }
private static void ParseAndRenderAttributes(TemplateClassBuilder builder, Match tagMatch) { var idAndClasses = tagMatch.Groups[2].Value; var attributesHash = tagMatch.Groups[4].Value.Trim(); var match = _idClassesRegex.Match(idAndClasses); var classes = new List <string>(); foreach (Capture capture in match.Groups[2].Captures) { classes.Add(capture.Value); } if (classes.Count > 0) { attributesHash = PrependAttribute(attributesHash, Class, string.Join(" ", classes.ToArray())); } string id = null; foreach (Capture capture in match.Groups[1].Captures) { id = capture.Value; break; } if (!string.IsNullOrEmpty(id)) { attributesHash = PrependAttribute(attributesHash, Id, id); } if (string.IsNullOrEmpty(attributesHash)) { return; } var attributeParser = new AttributeParser(attributesHash); attributeParser.Parse(); foreach (var attribute in attributeParser.Attributes) { if (attribute.Type == ParsedAttributeType.String) { var expressionStringParser = new ExpressionStringParser(attribute.Value); expressionStringParser.Parse(); builder.AppendAttributeTokens(attribute.Schema, attribute.Name, expressionStringParser.ExpressionStringTokens); } else { var token = new ExpressionStringToken(attribute.Value, true); builder.AppendAttributeTokens(attribute.Schema, attribute.Name, new[] { token }); } } }
public void EmptyValue() { var parser = new AttributeParser(@"a="""""); parser.Parse(); Assert.AreEqual(1, parser.Attributes.Count); AssertAttribute(parser, "a", "", ParsedAttributeType.String); }
public void SingleQuoteOpen() { var parser = new AttributeParser(@" a=text' "); parser.Parse(); Assert.AreEqual(1, parser.Attributes.Count); AssertAttribute(parser, "a", "text'", ParsedAttributeType.Reference); }
public void SimpleSingleQuotes() { var parser = new AttributeParser("a='b'"); parser.Parse(); Assert.AreEqual(1, parser.Attributes.Count); AssertAttribute(parser, "a", "b", ParsedAttributeType.String); }
public void SimpleOnlyReferenceWithSpace() { var parser = new AttributeParser("a "); parser.Parse(); Assert.AreEqual(1, parser.Attributes.Count); AssertAttribute(parser, "a", "a", ParsedAttributeType.String); }
public void SchemaOnly() { var parser = new AttributeParser(" a:b "); parser.Parse(); Assert.AreEqual(1, parser.Attributes.Count); AssertAttribute(parser, "a", "b", "b", ParsedAttributeType.String); }
public void SimpleReference() { var parser = new AttributeParser(" a=bb "); parser.Parse(); Assert.AreEqual(1, parser.Attributes.Count); AssertAttribute(parser, "a", "bb", ParsedAttributeType.Reference); }
public void SimpleSchemaReference() { var parser = new AttributeParser(" xml:lang=en:us "); parser.Parse(); Assert.AreEqual(1, parser.Attributes.Count); AssertAttribute(parser, "xml", "lang", "en:us", ParsedAttributeType.Reference); }
public void CurlyBracesInsideCode() { var parser = new AttributeParser(@"action = #{Convert.ToString(new { ID=5\})}"); parser.Parse(); Assert.AreEqual(1, parser.Attributes.Count); AssertAttribute(parser, "action", "Convert.ToString(new { ID=5\\})", ParsedAttributeType.Expression); }
public void SimpleEncodingIsIgnoredIfItIsUsedAsStopper() { var parser = new AttributeParser(@"c=#{abc\\} "); parser.Parse(); Assert.AreEqual(1, parser.Attributes.Count); AssertAttribute(parser, "c", @"abc\\", ParsedAttributeType.Expression); }
public void ValueEndsWithCurly() { var parser = new AttributeParser(@" a=text} "); parser.Parse(); Assert.AreEqual(1, parser.Attributes.Count); AssertAttribute(parser, "a", "text}", ParsedAttributeType.Reference); }
public void ExpressionWithoutHash() { var parser = new AttributeParser(@"src = Html.Content().AppRoot() "); parser.Parse(); Assert.AreEqual(1, parser.Attributes.Count); AssertAttribute(parser, "src", "Html.Content().AppRoot()", ParsedAttributeType.Reference); }
void DualParse(AttributeParser parser, string line) { Assert.That(parser, Is.Not.Null, "Parser available"); AttributeDefinition def = parser.ParseLine(line); Assert.That(def, Is.Not.Null, "Can parse attribute"); Assert.That(def.Name, Is.EqualTo("TestDescriptionAttribute")); if (parser.SupportsNamespaces) { Assert.That(def.NamespacePrefix, Is.EqualTo("System.Reflection")); } Assert.That(def.Arguments.Count, Is.GreaterThanOrEqualTo(4)); Assert.That(def.NamedArguments.Count, Is.GreaterThanOrEqualTo(2)); Assert.That(def.Arguments[0], Is.EqualTo("1")); Assert.That(def.Arguments[1].Contains("text")); Assert.That(def.Arguments[2].Contains("12") && def.Arguments[2].Contains("3")); Assert.That(def.Arguments[3].Contains("FileMode") && def.Arguments[3].Contains("Read")); Assert.That(def.NamedArguments[0].Name, Is.EqualTo("Number")); Assert.That(def.NamedArguments[0].Value, Is.EqualTo("2")); Assert.That(def.NamedArguments[1].Name, Is.EqualTo("Value")); Assert.That(def.NamedArguments[1].Value.Contains("true")); Assert.That(def, Is.Not.Null, "Can parse attribute with parser {0}", parser.GetType().Name); string newLine = parser.GenerateAttributeLine(def); Assert.That(newLine, Is.Not.Null, "Can regenerate attribute line with parser {0}", parser.GetType().Name); AttributeDefinition def2 = parser.ParseLine(newLine); Assert.That(def2, Is.Not.Null, "Can parse second time"); AssertEquals(def, def2); def2.Comment = newLine; string lineWithComment = parser.GenerateAttributeLine(def2); AttributeDefinition def3 = parser.ParseLine(lineWithComment); Assert.That(def3, Is.Not.Null, "Can parse with comment"); string commentItem = def3.Comment; Assert.That(commentItem, Is.Not.Null, "Retrieved comment"); Assert.That(commentItem, Is.EqualTo(newLine)); //AttributeDefinition def3 = parser.Ge }
public void ExpressionInsideOfDoubleSingleQuotesAndEncodedQuotes() { var parser = new AttributeParser("a='#{\"a\"}' c=\"#{a}\""); parser.Parse(); Assert.AreEqual(2, parser.Attributes.Count); AssertAttribute(parser, "a", "#{\"a\"}", ParsedAttributeType.String); AssertAttribute(parser, "c", "#{a}", ParsedAttributeType.String); }
public void AttributeWithSchemaIsDifferent() { var parser = new AttributeParser("lang='en' xml:lang='en:us'"); parser.Parse(); Assert.AreEqual(2, parser.Attributes.Count); AssertAttribute(parser, null, "lang", "en", ParsedAttributeType.String); AssertAttribute(parser, "xml", "lang", "en:us", ParsedAttributeType.String); }
public void DoubleAndSingleQuotesEncoded() { var parser = new AttributeParser(@"b='a\'b\'' dd=""\""d\""e"""); parser.Parse(); Assert.AreEqual(2, parser.Attributes.Count); AssertAttribute(parser, "b", @"a\'b\'", ParsedAttributeType.String); AssertAttribute(parser, "dd", @"\""d\""e", ParsedAttributeType.String); }
public void ParsingAttributeElsewhereThanInPathOrQueryShouldReturnNull(ParameterLocation parameterLocation) { OpenApiParameter parameter = new OpenApiParameter { In = parameterLocation }; var parsedAttribute = AttributeParser.ParseAttribute(parameter); Assert.IsNull(parsedAttribute); }
public void DoubleQuotes() { var parser = new AttributeParser("a=\"b\" cc=\"d\" eee=\"f\" "); parser.Parse(); Assert.AreEqual(3, parser.Attributes.Count); AssertAttribute(parser, "a", "b", ParsedAttributeType.String); AssertAttribute(parser, "cc", "d", ParsedAttributeType.String); AssertAttribute(parser, "eee", "f", ParsedAttributeType.String); }
public void EncodingIsIgnoredIfItIsUsedAsStopper() { var parser = new AttributeParser(@" a=""abc\\"" b='abc\\' c=#{abc\\} "); parser.Parse(); Assert.AreEqual(3, parser.Attributes.Count); AssertAttribute(parser, "a", @"abc\\", ParsedAttributeType.String); AssertAttribute(parser, "b", @"abc\\", ParsedAttributeType.String); AssertAttribute(parser, "c", @"abc\\", ParsedAttributeType.Expression); }
public void Initialize(VBE vbe) { if (_parser != null) { throw new InvalidOperationException("ParserState is already initialized."); } Func <IVBAPreprocessor> preprocessorFactory = () => new VBAPreprocessor(double.Parse(vbe.Version, CultureInfo.InvariantCulture)); _attributeParser = new AttributeParser(new ModuleExporter(), preprocessorFactory); _parser = new RubberduckParser(vbe, _state, _attributeParser, preprocessorFactory); }
public void SingleQuotes() { var parser = new AttributeParser("a='b' c='d' ee='f'"); parser.Parse(); Assert.AreEqual(3, parser.Attributes.Count); AssertAttribute(parser, "a", "b", ParsedAttributeType.String); AssertAttribute(parser, "c", "d", ParsedAttributeType.String); AssertAttribute(parser, "ee", "f", ParsedAttributeType.String); }
public void OnlyReference() { var parser = new AttributeParser("a cc e"); parser.Parse(); Assert.AreEqual(3, parser.Attributes.Count); AssertAttribute(parser, "a", "a", ParsedAttributeType.String); AssertAttribute(parser, "cc", "cc", ParsedAttributeType.String); AssertAttribute(parser, "e", "e", ParsedAttributeType.String); }
private static void AssertAttribute(AttributeParser parser, string schema, string name, string value, ParsedAttributeType type) { var attribute = parser.Attributes.FirstOrDefault(a => a.Name == name && a.Schema == schema); Assert.IsNotNull(attribute, string.Format("Attribute '{0}' not found.", name)); Assert.AreEqual(schema, attribute.Schema, "Schema"); Assert.AreEqual(value, attribute.Value, "Value"); Assert.AreEqual(type, attribute.Type, "Type"); }
public void Schema() { var parser = new AttributeParser(@" a:b b:ccc='eee' eee:c=e "); parser.Parse(); Assert.AreEqual(3, parser.Attributes.Count); AssertAttribute(parser, "a", "b", "b", ParsedAttributeType.String); AssertAttribute(parser, "b", "ccc", "eee", ParsedAttributeType.String); AssertAttribute(parser, "eee", "c", "e", ParsedAttributeType.Reference); }
public void SpacesBettwenKeyAndValue() { var parser = new AttributeParser("a =a bbb= b c = 'c' dd = #{d} "); parser.Parse(); Assert.AreEqual(4, parser.Attributes.Count); AssertAttribute(parser, "a", "a", ParsedAttributeType.Reference); AssertAttribute(parser, "bbb", "b", ParsedAttributeType.Reference); AssertAttribute(parser, "c", "c", ParsedAttributeType.String); AssertAttribute(parser, "dd", "d", ParsedAttributeType.Expression); }
public override AstNode Process(ParserReader parser) { var reader = parser.Input; var attributeParser = new AttributeParser(parser); var baseIndent = parser.Indent; if(!reader.Read()) return null; var node = ReadTagNode(reader); while(!reader.IsEndOfStream) switch(reader.CurrentChar) { case '/': { reader.Skip("/"); node.AutoClose = true; break; } case '#': { reader.Skip("#"); //Todo: should be a port of output var attribute = node.Attributes.Find(a => a.Name.Equals("id", StringComparison.InvariantCultureIgnoreCase)); if(attribute == null) { attribute = new AttributeNode("id"); node.Attributes.Add(attribute); } attribute.Value = parser.ParseText(reader.ReadNameEscaped(), reader.Index); continue; } case '.': { reader.Skip("."); node.Attributes.Add(new AttributeNode("class") { Value = parser.ParseText(reader.ReadNameEscaped(), reader.Index) }); continue; } case '&': reader.CurrentLine.EscapeLine = true; reader.Skip("&"); break; case '!': reader.CurrentLine.EscapeLine = false; reader.Skip("!"); break; case '=': { reader.Skip("="); reader.SkipWhiteSpaces(); node.Child = new CodeNode(reader.ReadToEndMultiLine(), reader.CurrentLine.EscapeLine); break; } case '(': { node.Attributes.AddRange(attributeParser.ParseHtmlStyle()); break; } case '{': { node.Attributes.AddRange(attributeParser.ParseRubyStyle()); break; } default: { var index = reader.Index; var text = reader.ReadToEndMultiLine(); node.Child = parser.ParseText(text.TrimStart(), index); break; } } if (reader.NextLine != null && reader.NextLine.Indent > reader.CurrentLine.Indent) { node.Child = parser.ParseChildren(baseIndent, node.Child); } node.EndInfo = reader.SourceInfo; return node; }
private static void AssertAttribute(AttributeParser parser, string name, string value, ParsedAttributeType type) { AssertAttribute(parser, null, name, value, type); }
public void ReferenceAsValue() { var parser = new AttributeParser("aa=b c=d eee=f ff=ff.aa ggg=ggg.bb.aa"); parser.Parse(); Assert.AreEqual(5, parser.Attributes.Count); AssertAttribute(parser, "aa", "b", ParsedAttributeType.Reference); AssertAttribute(parser, "c", "d", ParsedAttributeType.Reference); AssertAttribute(parser, "eee", "f", ParsedAttributeType.Reference); AssertAttribute(parser, "ff", "ff.aa", ParsedAttributeType.Reference); AssertAttribute(parser, "ggg", "ggg.bb.aa", ParsedAttributeType.Reference); }
public override AstNode Process(ParserReader parser) { var reader = parser.Input; var attributeParser = new AttributeParser(parser); var baseIndent = parser.Indent; bool isPartial = false; if (!reader.Read()) return null; string name; if (reader.CurrentChar == '_') { reader.Skip("_"); name = "contentplaceholder"; isPartial = true; } else { reader.Skip("@"); name = reader.ReadName(); isPartial = false; } var node = new MetaNode(name); reader.SkipWhiteSpaces(); if (isPartial && (reader.CurrentChar != null)) { node.Name = "partialcontent"; node.Value = reader.ReadWhile(c => !Char.IsWhiteSpace(c) && c != '(' && c != '{'); } else { node.Value = "Main"; } while (!reader.IsEndOfStream) { switch (reader.CurrentChar) { case '=': { if (!isPartial) { reader.Skip("="); reader.SkipWhiteSpaces(); switch (reader.CurrentChar) { case '\'': reader.Skip("'"); node.Value = reader.ReadWhile(c => c != '\''); reader.Skip("'"); break; case '"': reader.Skip("\""); node.Value = reader.ReadWhile(c => c != '"'); reader.Skip("\""); break; default: node.Value = reader.ReadWhile(c => !Char.IsWhiteSpace(c) && c != '(' && c != '{'); break; } } else { throw new ParserException(reader, "'=' is not allowed in partial definitions"); } break; } case '(': { node.Attributes.AddRange(attributeParser.ParseHtmlStyle(false)); break; } case '{': { node.Attributes.AddRange(attributeParser.ParseRubyStyle(false)); break; } default: { var index = reader.Index; var text = reader.ReadToEndMultiLine(); node.Child = parser.ParseText(text.TrimStart(), index); break; } } reader.SkipWhiteSpaces(); } if (reader.NextLine != null && reader.NextLine.Indent > reader.CurrentLine.Indent) { node.Child = parser.ParseChildren(baseIndent, node.Child); } node.EndInfo = reader.SourceInfo; if (!_node.Metadata.ContainsKey(name)) _node.Metadata[name] = new List<MetaNode>(); _node.Metadata[name].Add(node); return node; }
public void ValueEndsWithCurly() { var parser = new AttributeParser(@" a=text} "); parser.Parse(); Assert.AreEqual(1, parser.Attributes.Count); AssertAttribute(parser, "a", "text }
private static string AppendCreateDictionaryLocalVariable(string dictionary, CodeDomClassBuilder builder) { var parser = new AttributeParser(dictionary); parser.Parse(); var keyValuePairType = new CodeTypeReference(typeof(KeyValuePair<string,object>)); var createDictionaryMethod = new CodeMethodInvokeExpression(); foreach (var attribute in parser.Attributes) { var newKeyValueExpression = new CodeObjectCreateExpression {CreateType = keyValuePairType}; var keyExpression = new CodePrimitiveExpression {Value = attribute.Name}; newKeyValueExpression.Parameters.Add(keyExpression); if (attribute.Type == ParsedAttributeType.String) { var expressionStringParser = new ExpressionStringParser(attribute.Value); expressionStringParser.Parse(); var values = expressionStringParser.Tokens; if (values.Count == 1) { var expressionStringToken = values[0]; if (expressionStringToken.IsExpression) { newKeyValueExpression.Parameters.Add(new CodeSnippetExpression { Value = expressionStringToken.Value }); } else { newKeyValueExpression.Parameters.Add(new CodePrimitiveExpression { Value = expressionStringToken.Value }); } } else { var concatExpression = CodeDomClassBuilder.GetConcatExpression(values); newKeyValueExpression.Parameters.Add(concatExpression); } } else { newKeyValueExpression.Parameters.Add(new CodeSnippetExpression { Value = attribute.Value }); } createDictionaryMethod.Parameters.Add(newKeyValueExpression); } var getDictionaryMethod = new CodeMethodReferenceExpression { MethodName = "GetDictionaryFromKeyValue", TargetObject = new CodeVariableReferenceExpression { VariableName = "NHamlMonoRailView" } }; createDictionaryMethod.Method = getDictionaryMethod; var variableName = "nhamlTempDictionary" + tempDictionaryCount; tempDictionaryCount++; var _decl1 = new CodeVariableDeclarationStatement { InitExpression = createDictionaryMethod, Name = variableName, Type = new CodeTypeReference(typeof (IDictionary<string, object>)) }; builder.RenderMethod.Statements.Add(_decl1); return variableName; }
private static void ParseAndRenderAttributes(TemplateClassBuilder builder, Match tagMatch) { var idAndClasses = tagMatch.Groups[2].Value; var attributesHash = tagMatch.Groups[4].Value.Trim(); var match = _idClassesRegex.Match(idAndClasses); var classes = new List<string>(); foreach (Capture capture in match.Groups[2].Captures) { classes.Add(capture.Value); } if (classes.Count > 0) { attributesHash = PrependAttribute(attributesHash, Class, string.Join(" ", classes.ToArray())); } string id = null; foreach (Capture capture in match.Groups[1].Captures) { id = capture.Value; break; } if (!string.IsNullOrEmpty(id)) { attributesHash = PrependAttribute(attributesHash, Id, id); } if (string.IsNullOrEmpty(attributesHash)) { return; } var attributeParser = new AttributeParser(attributesHash); attributeParser.Parse(); foreach (var attribute in attributeParser.Attributes) { if (attribute.Type == ParsedAttributeType.String) { var expressionStringParser = new ExpressionStringParser(attribute.Value); expressionStringParser.Parse(); builder.AppendAttributeTokens(attribute.Schema, attribute.Name, expressionStringParser.ExpressionStringTokens); } else { var token = new ExpressionStringToken(attribute.Value, true); builder.AppendAttributeTokens(attribute.Schema, attribute.Name, new[] { token }); } } }
public void Expressions() { var parser = new AttributeParser("aaa=#{1+1} bb=#{\"t\"} c=#{f.ToString()} d=#{f=>\\{return 1\\}}"); parser.Parse(); Assert.AreEqual(4, parser.Attributes.Count); AssertAttribute(parser, "aaa", "1+1", ParsedAttributeType.Expression); AssertAttribute(parser, "bb", "\"t\"", ParsedAttributeType.Expression); AssertAttribute(parser, "c", "f.ToString()", ParsedAttributeType.Expression); AssertAttribute(parser, "d", @"f=>\{return 1\}", ParsedAttributeType.Expression); }