SyntaxTreeNodeCollection GetModifiedSubNodes(SyntaxTreeNode node) { SyntaxTreeNodeCollection modifiedSubNodes = null; //lazy for (int i = 0; i < node.SubNodes.Count; i++) { var subNode = node.SubNodes[i]; var replacement = Visit(subNode); if (replacement != subNode) { if (modifiedSubNodes == null) //lazy init { modifiedSubNodes = new SyntaxTreeNodeCollection(); for (int j = 0; j < i; j++) //copy unmodified nodes modifiedSubNodes.Add(node.SubNodes[j]); } if (replacement != null) //insert replacement modifiedSubNodes.Add(replacement); } else { if (modifiedSubNodes != null) //only insert unmodified subnode if the lazy collection has been initialized modifiedSubNodes.Add(subNode); } } return modifiedSubNodes; }
static void AddSubnodes(BBTag[] allowedTags, SyntaxTreeNode node) { int count = PexChoose.ValueFromRange("count", 0, 3); bool lastWasText = false; for (int i = 0; i < count; i++) { var subNode = CreateNode(allowedTags, !lastWasText); lastWasText = subNode is TextNode; node.SubNodes.Add(subNode); } }
public virtual void Visit(SyntaxTreeNode node) { node.Accept(this); }
public T StartChunkBlock <T>(SyntaxTreeNode association, bool topLevel) where T : ChunkBlock, new() { var chunkBlock = new T(); return(StartChunkBlock <T>(chunkBlock, association, topLevel)); }
/// <summary> /// /// </summary> /// <param name="node"></param> /// <param name="getTextSpansToReplace"></param> /// <param name="tagFilter"></param> /// <exception cref="ArgumentException"></exception> /// <exception cref="ArgumentNullException"></exception> public static SyntaxTreeNode ReplaceTextSpans(SyntaxTreeNode node, Func <string, IList <TextSpanReplaceInfo> > getTextSpansToReplace, Func <TagNode, bool> tagFilter) { if (node == null) { throw new ArgumentNullException(nameof(node)); } if (getTextSpansToReplace == null) { throw new ArgumentNullException(nameof(getTextSpansToReplace)); } if (node is TextNode) { var nodeText = ((TextNode)node).Text; var replacements = getTextSpansToReplace(nodeText); if (replacements == null || replacements.Count == 0) { return(node); } var replacementNodes = new List <SyntaxTreeNode>(replacements.Count * 2 + 1); var lastPos = 0; foreach (var r in replacements) { if (r.Index < lastPos) { throw new ArgumentException("the replacement text spans must be ordered by index and non-overlapping"); } if (r.Index > nodeText.Length - r.Length) { throw new ArgumentException("every replacement text span must reference a range within the text node"); } if (r.Index != lastPos) { replacementNodes.Add(new TextNode(nodeText.Substring(lastPos, r.Index - lastPos))); } if (r.Replacement != null) { replacementNodes.Add(r.Replacement); } lastPos = r.Index + r.Length; } if (lastPos != nodeText.Length) { replacementNodes.Add(new TextNode(nodeText.Substring(lastPos))); } return(new SequenceNode(replacementNodes)); } else { var fixedSubNodes = node.SubNodes.Select(n => { if (n is TagNode && (tagFilter != null && !tagFilter((TagNode)n))) { return(n); //skip filtered tags } var repl = ReplaceTextSpans(n, getTextSpansToReplace, tagFilter); return(repl); }).ToList(); if (fixedSubNodes.SequenceEqual(node.SubNodes, ReferenceEqualityComparer <SyntaxTreeNode> .Instance)) { return(node); } return(node.SetSubNodes(fixedSubNodes)); } }
public static bool TryBindMethodCall(SyntaxTreeNode node, BindingContext bindingContext, TypeDescription expectedType, out Expression boundExpression, out Exception bindingError) { if (node == null) { throw new ArgumentNullException("node"); } if (bindingContext == null) { throw new ArgumentNullException("bindingContext"); } if (expectedType == null) { throw new ArgumentNullException("expectedType"); } // bindingError could return null from this method bindingError = null; boundExpression = null; var methodNameNode = node.GetExpression(throwOnError: true); var methodNameNodeType = methodNameNode.GetExpressionType(throwOnError: true); if (methodNameNodeType != Constants.EXPRESSION_TYPE_PROPERTY_OR_FIELD && methodNameNodeType != Constants.EXPRESSION_TYPE_MEMBER_RESOLVE) { return(false); } var methodTargetNode = methodNameNode.GetExpression(throwOnError: false); var methodTarget = default(Expression); var type = default(Type); var typeReference = default(TypeReference); var isStatic = false; if (methodTargetNode == null && bindingContext.Global != null) { methodTarget = bindingContext.Global; type = methodTarget.Type; isStatic = false; } else if (methodTargetNode == null) { var methodName = methodNameNode.GetMemberName(throwOnError: false); bindingError = new ExpressionParserException(string.Format(Properties.Resources.EXCEPTION_BIND_UNABLETORESOLVENAME, methodName ?? "<unknown>"), node); return(false); } else if (BindingContext.TryGetTypeReference(methodTargetNode, out typeReference) && bindingContext.TryResolveType(typeReference, out type)) { isStatic = true; } else if (AnyBinder.TryBind(methodTargetNode, bindingContext, TypeDescription.ObjectType, out methodTarget, out bindingError)) { Debug.Assert(methodTarget != null, "methodTarget != null"); isStatic = false; type = methodTarget.Type; } else { if (typeReference != null && bindingError == null) { bindingError = new ExpressionParserException(string.Format(Properties.Resources.EXCEPTION_BIND_UNABLETORESOLVETYPE, typeReference), node); } return(false); } var methodRef = default(TypeReference); if (type == null || BindingContext.TryGetMethodReference(methodNameNode, out methodRef) == false) { return(false); } var typeDescription = TypeDescription.GetTypeDescription(type); foreach (var member in typeDescription.GetMembers(methodRef.Name)) { if (member.IsMethod == false || member.IsStatic != isStatic) { continue; } var callNode = new SyntaxTreeNode(new Dictionary <string, object> { { Constants.EXPRESSION_ATTRIBUTE, methodTarget ?? (object)type }, { Constants.ARGUMENTS_ATTRIBUTE, node.GetValueOrDefault(Constants.ARGUMENTS_ATTRIBUTE, default(object)) }, { Constants.METHOD_ATTRIBUTE, methodRef }, { Constants.USE_NULL_PROPAGATION_ATTRIBUTE, methodNameNode.GetValueOrDefault(Constants.USE_NULL_PROPAGATION_ATTRIBUTE, default(object)) }, { Constants.EXPRESSION_POSITION, methodNameNode.GetPosition(throwOnError: false) } }); return(CallBinder.TryBind(callNode, bindingContext, expectedType, out boundExpression, out bindingError)); } return(false); }
public SyntaxTreeNode(Stack<Parser.Item> elements) { Type = elements.Pop(); if (Type is Parser.Operation) { if (Type is Parser.BinaryOperation) RightNode = new SyntaxTreeNode(elements); LeftNode = new SyntaxTreeNode(elements); } }
private static void AddPassedMessage(ErrorCollector collector, SyntaxTreeNode expected) { collector.AddMessage("{0} - PASSED", expected); }
private static void AddMismatchError(ErrorCollector collector, SyntaxTreeNode actual, SyntaxTreeNode expected) { collector.AddError("{0} - FAILED :: Actual: {1}", expected, actual); }
/// <summary> /// Adds a new node to the block /// </summary> /// <param name="node"></param> public void Add(SyntaxTreeNode node) { _nodes.Add(node); }
protected override bool EqualsCore(SyntaxTreeNode b) { var casted = (TextNode)b; return Text == casted.Text && HtmlTemplate == casted.HtmlTemplate; }
static void AssertTextNodesNotSplit(SyntaxTreeNode node) { if (node.SubNodes != null) { SyntaxTreeNode lastNode = null; for (int i = 0; i < node.SubNodes.Count; i++) { AssertTextNodesNotSplit(node.SubNodes[i]); if (lastNode != null) Assert.IsFalse(lastNode is TextNode && node.SubNodes[i] is TextNode); lastNode = node.SubNodes[i]; } } }
/// <summary> /// Determines if the specified node is equivalent to this node /// </summary> /// <param name="node">The node to compare this node with</param> /// <returns> /// true if the provided node has all the same content and metadata, though the specific quantity and type of /// symbols may be different. /// </returns> public abstract bool EquivalentTo(SyntaxTreeNode node);
public SyntaxTreeNode Derivate(Char variable) { SyntaxTreeNode result = new SyntaxTreeNode(new Parser.Number(0.0)); if (Type is Parser.Variable && ((Parser.Variable)Type).Name == variable) result = new SyntaxTreeNode(new Parser.Number(1.0)); else if (Type is Parser.BinaryOperation) { SyntaxTreeNode leftDerivative = LeftNode.Derivate(variable); SyntaxTreeNode rightDerivative = RightNode.Derivate(variable); if (((Parser.BinaryOperation)Type).Type == Parser.BinaryOperation.BinaryOperationType.plus) { result = new SyntaxTreeNode(new Parser.BinaryOperation(Parser.BinaryOperation.BinaryOperationType.plus)); result.LeftNode = leftDerivative; result.RightNode = rightDerivative; } else if (((Parser.BinaryOperation)Type).Type == Parser.BinaryOperation.BinaryOperationType.minus) { result = new SyntaxTreeNode(new Parser.BinaryOperation(Parser.BinaryOperation.BinaryOperationType.minus)); result.LeftNode = leftDerivative; result.RightNode = rightDerivative; } else if (((Parser.BinaryOperation)Type).Type == Parser.BinaryOperation.BinaryOperationType.multiply) { result = new SyntaxTreeNode(new Parser.BinaryOperation(Parser.BinaryOperation.BinaryOperationType.plus)); result.LeftNode = new SyntaxTreeNode(new Parser.BinaryOperation(Parser.BinaryOperation.BinaryOperationType.multiply)); result.RightNode = new SyntaxTreeNode(new Parser.BinaryOperation(Parser.BinaryOperation.BinaryOperationType.multiply)); result.LeftNode.LeftNode = leftDerivative; result.LeftNode.RightNode = RightNode; result.RightNode.LeftNode = LeftNode; result.RightNode.RightNode = rightDerivative; } else if (((Parser.BinaryOperation)Type).Type == Parser.BinaryOperation.BinaryOperationType.divide) { result = new SyntaxTreeNode(new Parser.BinaryOperation(Parser.BinaryOperation.BinaryOperationType.divide)); result.LeftNode = new SyntaxTreeNode(new Parser.BinaryOperation(Parser.BinaryOperation.BinaryOperationType.minus)); result.LeftNode.LeftNode = new SyntaxTreeNode(new Parser.BinaryOperation(Parser.BinaryOperation.BinaryOperationType.multiply)); result.LeftNode.LeftNode.LeftNode = leftDerivative; result.LeftNode.LeftNode.RightNode = RightNode; result.LeftNode.RightNode = new SyntaxTreeNode(new Parser.BinaryOperation(Parser.BinaryOperation.BinaryOperationType.multiply)); result.LeftNode.RightNode.LeftNode = rightDerivative; result.LeftNode.RightNode.RightNode = LeftNode; result.RightNode = new SyntaxTreeNode(new Parser.BinaryOperation(Parser.BinaryOperation.BinaryOperationType.multiply)); result.RightNode.LeftNode = RightNode; result.RightNode.RightNode = RightNode; } else if (((Parser.BinaryOperation)Type).Type == Parser.BinaryOperation.BinaryOperationType.power) { if (RightNode.Type is Parser.Number) { result = new SyntaxTreeNode(new Parser.BinaryOperation(Parser.BinaryOperation.BinaryOperationType.multiply)); result.LeftNode = new SyntaxTreeNode(new Parser.BinaryOperation(Parser.BinaryOperation.BinaryOperationType.multiply)); result.LeftNode.LeftNode = RightNode; result.LeftNode.RightNode = new SyntaxTreeNode(new Parser.BinaryOperation(Parser.BinaryOperation.BinaryOperationType.power)); result.LeftNode.RightNode.LeftNode = LeftNode; result.LeftNode.RightNode.RightNode = new SyntaxTreeNode(new Parser.Number(((Parser.Number)(RightNode.Type)).Value - 1)); result.RightNode = LeftNode.Derivate(variable); } else throw new Exception("Мне не нужна такая производная"); } } else if (Type is Parser.UnaryOperation) { result = new SyntaxTreeNode(new Parser.BinaryOperation(Parser.BinaryOperation.BinaryOperationType.multiply)); result.RightNode = LeftNode.Derivate(variable); if (((Parser.UnaryOperation)Type).Type == Parser.UnaryOperation.UnaryOperationType.cos) { result.LeftNode = new SyntaxTreeNode(new Parser.BinaryOperation(Parser.BinaryOperation.BinaryOperationType.minus)); result.LeftNode.LeftNode = new SyntaxTreeNode(new Parser.Number(0.0)); result.LeftNode.RightNode = new SyntaxTreeNode(new Parser.UnaryOperation(Parser.UnaryOperation.UnaryOperationType.sin)); result.LeftNode.RightNode.LeftNode = LeftNode; } else if (((Parser.UnaryOperation)Type).Type == Parser.UnaryOperation.UnaryOperationType.sin) { result.LeftNode = new SyntaxTreeNode(new Parser.UnaryOperation(Parser.UnaryOperation.UnaryOperationType.cos)); result.LeftNode.LeftNode = LeftNode; } else if (((Parser.UnaryOperation)Type).Type == Parser.UnaryOperation.UnaryOperationType.log) { result.LeftNode = new SyntaxTreeNode(new Parser.BinaryOperation(Parser.BinaryOperation.BinaryOperationType.divide)); result.LeftNode.LeftNode = new SyntaxTreeNode(new Parser.Number(1.0)); result.LeftNode.RightNode = LeftNode; } } return result; }
public static bool TryBind(SyntaxTreeNode node, BindingContext bindingContext, TypeDescription expectedType, out Expression boundExpression, out Exception bindingError) { if (node == null) { throw new ArgumentNullException("node"); } if (bindingContext == null) { throw new ArgumentNullException("bindingContext"); } if (expectedType == null) { throw new ArgumentNullException("expectedType"); } boundExpression = null; bindingError = null; var expressionType = node.GetExpressionType(throwOnError: true); var left = node.GetLeftExpression(throwOnError: true); var right = node.GetRightExpression(throwOnError: true); var methodName = node.GetMethodName(throwOnError: false); var conversion = node.GetConversion(throwOnError: false); var leftOperand = default(Expression); var rightOperand = default(Expression); var conversionLambda = default(Expression); var methodMember = default(MemberDescription); if (AnyBinder.TryBindInNewScope(left, bindingContext, TypeDescription.ObjectType, out leftOperand, out bindingError) == false) { return(false); } if (AnyBinder.TryBindInNewScope(right, bindingContext, TypeDescription.ObjectType, out rightOperand, out bindingError) == false) { return(false); } if (methodName != null) { bindingContext.TryResolveMember(methodName, out methodMember); } if (conversion != null) { AnyBinder.TryBindInNewScope(conversion, bindingContext, TypeDescription.ObjectType, out conversionLambda, out bindingError); bindingError = null; } Debug.Assert(leftOperand != null, "leftOperand != null"); Debug.Assert(rightOperand != null, "rightOperand != null"); switch (expressionType) { case Constants.EXPRESSION_TYPE_ADD: if (leftOperand.Type == typeof(string) || rightOperand.Type == typeof(string)) { boundExpression = Expression.Call ( StringConcat.GetMethodInfo(), Expression.Convert(leftOperand, typeof(object)), Expression.Convert(rightOperand, typeof(object)) ); break; } else { if (ExpressionUtils.TryPromoteBinaryOperation(ref leftOperand, ref rightOperand, ExpressionType.Add, out boundExpression) == false) { boundExpression = Expression.Add(leftOperand, rightOperand); } break; } case Constants.EXPRESSION_TYPE_ADD_CHECKED: if (leftOperand.Type == typeof(string) || rightOperand.Type == typeof(string)) { boundExpression = Expression.Call ( StringConcat.GetMethodInfo(), Expression.Convert(leftOperand, typeof(object)), Expression.Convert(rightOperand, typeof(object)) ); break; } else { if (ExpressionUtils.TryPromoteBinaryOperation(ref leftOperand, ref rightOperand, ExpressionType.AddChecked, out boundExpression) == false) { boundExpression = Expression.AddChecked(leftOperand, rightOperand); } break; } case Constants.EXPRESSION_TYPE_SUBTRACT: if (ExpressionUtils.TryPromoteBinaryOperation(ref leftOperand, ref rightOperand, ExpressionType.Subtract, out boundExpression) == false) { boundExpression = Expression.Subtract(leftOperand, rightOperand, methodMember); } break; case Constants.EXPRESSION_TYPE_SUBTRACT_CHECKED: if (ExpressionUtils.TryPromoteBinaryOperation(ref leftOperand, ref rightOperand, ExpressionType.SubtractChecked, out boundExpression) == false) { boundExpression = Expression.SubtractChecked(leftOperand, rightOperand, methodMember); } break; case Constants.EXPRESSION_TYPE_LEFT_SHIFT: ExpressionUtils.TryPromoteUnaryOperation(ref leftOperand, ExpressionType.LeftShift, out boundExpression); ExpressionUtils.TryPromoteUnaryOperation(ref rightOperand, ExpressionType.LeftShift, out boundExpression); boundExpression = Expression.LeftShift(leftOperand, rightOperand, methodMember); break; case Constants.EXPRESSION_TYPE_RIGHT_SHIFT: ExpressionUtils.TryPromoteUnaryOperation(ref leftOperand, ExpressionType.RightShift, out boundExpression); ExpressionUtils.TryPromoteUnaryOperation(ref rightOperand, ExpressionType.RightShift, out boundExpression); boundExpression = Expression.RightShift(leftOperand, rightOperand, methodMember); break; case Constants.EXPRESSION_TYPE_GREATER_THAN: if (ExpressionUtils.TryPromoteBinaryOperation(ref leftOperand, ref rightOperand, ExpressionType.GreaterThan, out boundExpression) == false) { boundExpression = Expression.GreaterThan(leftOperand, rightOperand); } break; case Constants.EXPRESSION_TYPE_GREATER_THAN_OR_EQUAL: if (ExpressionUtils.TryPromoteBinaryOperation(ref leftOperand, ref rightOperand, ExpressionType.GreaterThanOrEqual, out boundExpression) == false) { boundExpression = Expression.GreaterThanOrEqual(leftOperand, rightOperand); } break; case Constants.EXPRESSION_TYPE_LESS_THAN: if (ExpressionUtils.TryPromoteBinaryOperation(ref leftOperand, ref rightOperand, ExpressionType.LessThan, out boundExpression) == false) { boundExpression = Expression.LessThan(leftOperand, rightOperand); } break; case Constants.EXPRESSION_TYPE_LESS_THAN_OR_EQUAL: if (ExpressionUtils.TryPromoteBinaryOperation(ref leftOperand, ref rightOperand, ExpressionType.LessThanOrEqual, out boundExpression) == false) { boundExpression = Expression.LessThanOrEqual(leftOperand, rightOperand); } break; case Constants.EXPRESSION_TYPE_POWER: var resultType = TypeDescription.GetTypeDescription(leftOperand.Type); var resultTypeUnwrap = resultType.IsNullable ? resultType.UnderlyingType : resultType; if (ExpressionUtils.TryPromoteBinaryOperation(ref leftOperand, ref rightOperand, ExpressionType.Power, out boundExpression) == false) { var operandsType = TypeDescription.GetTypeDescription(leftOperand.Type); var operandTypeUnwrap = operandsType.IsNullable ? operandsType.UnderlyingType : operandsType; var promoteToNullable = resultType.IsNullable || operandsType.IsNullable; if (operandTypeUnwrap != typeof(double) && leftOperand.Type == rightOperand.Type) { leftOperand = Expression.ConvertChecked(leftOperand, promoteToNullable ? typeof(double?) : typeof(double)); rightOperand = Expression.ConvertChecked(rightOperand, promoteToNullable ? typeof(double?) : typeof(double)); } boundExpression = Expression.Power(leftOperand, rightOperand, methodMember); if (resultType != typeof(double)) { boundExpression = Expression.ConvertChecked(boundExpression, promoteToNullable ? resultTypeUnwrap.GetNullableType() : resultTypeUnwrap); } } break; case Constants.EXPRESSION_TYPE_DIVIDE: if (ExpressionUtils.TryPromoteBinaryOperation(ref leftOperand, ref rightOperand, ExpressionType.Divide, out boundExpression) == false) { boundExpression = Expression.Divide(leftOperand, rightOperand, methodMember); } break; case Constants.EXPRESSION_TYPE_MULTIPLY: if (ExpressionUtils.TryPromoteBinaryOperation(ref leftOperand, ref rightOperand, ExpressionType.Multiply, out boundExpression) == false) { boundExpression = Expression.Multiply(leftOperand, rightOperand, methodMember); } break; case Constants.EXPRESSION_TYPE_MULTIPLY_CHECKED: if (ExpressionUtils.TryPromoteBinaryOperation(ref leftOperand, ref rightOperand, ExpressionType.MultiplyChecked, out boundExpression) == false) { boundExpression = Expression.MultiplyChecked(leftOperand, rightOperand, methodMember); } break; case Constants.EXPRESSION_TYPE_MODULO: if (ExpressionUtils.TryPromoteBinaryOperation(ref leftOperand, ref rightOperand, ExpressionType.Modulo, out boundExpression) == false) { boundExpression = Expression.Modulo(leftOperand, rightOperand, methodMember); } break; case Constants.EXPRESSION_TYPE_EQUAL: if (ExpressionUtils.TryPromoteBinaryOperation(ref leftOperand, ref rightOperand, ExpressionType.Equal, out boundExpression) == false) { boundExpression = Expression.Equal(leftOperand, rightOperand); } break; case Constants.EXPRESSION_TYPE_NOT_EQUAL: if (ExpressionUtils.TryPromoteBinaryOperation(ref leftOperand, ref rightOperand, ExpressionType.NotEqual, out boundExpression) == false) { boundExpression = Expression.NotEqual(leftOperand, rightOperand); } break; case Constants.EXPRESSION_TYPE_AND: if (ExpressionUtils.TryPromoteBinaryOperation(ref leftOperand, ref rightOperand, ExpressionType.And, out boundExpression) == false) { boundExpression = Expression.And(leftOperand, rightOperand, methodMember); } break; case Constants.EXPRESSION_TYPE_OR: if (ExpressionUtils.TryPromoteBinaryOperation(ref leftOperand, ref rightOperand, ExpressionType.Or, out boundExpression) == false) { boundExpression = Expression.Or(leftOperand, rightOperand, methodMember); } break; case Constants.EXPRESSION_TYPE_EXCLUSIVE_OR: if (ExpressionUtils.TryPromoteBinaryOperation(ref leftOperand, ref rightOperand, ExpressionType.ExclusiveOr, out boundExpression) == false) { boundExpression = Expression.ExclusiveOr(leftOperand, rightOperand, methodMember); } break; case Constants.EXPRESSION_TYPE_AND_ALSO: boundExpression = Expression.AndAlso(leftOperand, rightOperand, methodMember); break; case Constants.EXPRESSION_TYPE_OR_ELSE: boundExpression = Expression.OrElse(leftOperand, rightOperand, methodMember); break; case Constants.EXPRESSION_TYPE_COALESCE: if (ExpressionUtils.TryPromoteBinaryOperation(ref leftOperand, ref rightOperand, ExpressionType.Coalesce, out boundExpression) == false) { boundExpression = Expression.Coalesce(leftOperand, rightOperand, conversionLambda as LambdaExpression); } break; default: bindingError = new ExpressionParserException(string.Format(Properties.Resources.EXCEPTION_BIND_UNKNOWNEXPRTYPE, expressionType), node); return(false); } return(true); }
/// <summary> /// Determines if the specified node is equivalent to this node /// </summary> /// <param name="node">The node to compare this node with</param> /// <returns> /// true if the provided node has all the same content and metadata, though the specific quantity and type of /// tokens may be different. /// </returns> public abstract bool EquivalentTo(SyntaxTreeNode node);
public static bool TryBind(SyntaxTreeNode node, BindingContext bindingContext, TypeDescription expectedType, out Expression boundExpression, out Exception bindingError) { if (node == null) { throw new ArgumentNullException("node"); } if (bindingContext == null) { throw new ArgumentNullException("bindingContext"); } if (expectedType == null) { throw new ArgumentNullException("expectedType"); } boundExpression = null; bindingError = null; var expressionType = node.GetExpressionType(throwOnError: true); var operandNode = node.GetExpression(throwOnError: true); var operand = default(Expression); if (AnyBinder.TryBindInNewScope(operandNode, bindingContext, TypeDescription.ObjectType, out operand, out bindingError) == false) { return(false); } Debug.Assert(operand != null, "operand != null"); switch (expressionType) { case Constants.EXPRESSION_TYPE_NEGATE: if (ExpressionUtils.TryPromoteUnaryOperation(ref operand, ExpressionType.Negate, out boundExpression) == false) { // fixing b_u_g in mono expression compiler: Negate on float or double = exception if (operand.Type == typeof(double) || operand.Type == typeof(float)) { boundExpression = Expression.Multiply(operand, operand.Type == typeof(float) ? ExpressionUtils.NegativeSingle : ExpressionUtils.NegativeDouble); } else { boundExpression = Expression.Negate(operand); } } break; case Constants.EXPRESSION_TYPE_NEGATE_CHECKED: if (ExpressionUtils.TryPromoteUnaryOperation(ref operand, ExpressionType.NegateChecked, out boundExpression) == false) { // fixing b_u_g in mono expression compiler: Negate on float or double = exception if (operand.Type == typeof(double) || operand.Type == typeof(float)) { boundExpression = Expression.Multiply(operand, operand.Type == typeof(float) ? ExpressionUtils.NegativeSingle : ExpressionUtils.NegativeDouble); } else { boundExpression = Expression.NegateChecked(operand); } } break; case Constants.EXPRESSION_TYPE_COMPLEMENT: case Constants.EXPRESSION_TYPE_NOT: if (ExpressionUtils.TryPromoteUnaryOperation(ref operand, ExpressionType.Not, out boundExpression) == false) { boundExpression = Expression.Not(operand); } break; case Constants.EXPRESSION_TYPE_UNARYPLUS: if (ExpressionUtils.TryPromoteUnaryOperation(ref operand, ExpressionType.UnaryPlus, out boundExpression) == false) { boundExpression = Expression.UnaryPlus(operand); } break; default: bindingError = new ExpressionParserException(string.Format(Properties.Resources.EXCEPTION_BIND_UNKNOWNEXPRTYPE, expressionType), node); return(false); } return(true); }
public static void Replace(SyntaxTreeNode parent, SyntaxTreeNode replaceThis, SyntaxTreeNode addThis) { for (int i = 0; i < parent.Childs.Count; i++) { if (parent.Childs[i] == replaceThis) { parent.Childs[i] = addThis; } } switch (parent.NodeKind) { case NodeType.MethodInvokation: for (int i = 0; i < parent.Childs.Count; i++) { if (((MethodInvokationExpression)parent).Parameters[i] == replaceThis) { ((MethodInvokationExpression)parent).Parameters[i] = new ParameterDeclaration((Expression)addThis) { Parent = parent } } } ; break; case NodeType.MethodInvokationAsStatement: for (int i = 0; i < parent.Childs.Count; i++) { if (((MethodInvokationExpression)((MethodInvokationStatement)parent).Instance).Parameters[i] == replaceThis) { ((MethodInvokationExpression)((MethodInvokationStatement)parent).Instance).Parameters[i] = new ParameterDeclaration((Expression)addThis) { Parent = parent } } } ; break; } }
public override int?GetDesiredIndentation(RazorSyntaxTree syntaxTree, int previousLineEndIndex, Func <int, string> getLineContent, int indentSize, int tabSize) { if (syntaxTree == null) { throw new ArgumentNullException(nameof(syntaxTree)); } if (previousLineEndIndex < 0) { throw new ArgumentOutOfRangeException(nameof(previousLineEndIndex)); } if (getLineContent == null) { throw new ArgumentNullException(nameof(getLineContent)); } if (indentSize < 0) { throw new ArgumentOutOfRangeException(nameof(indentSize)); } if (tabSize < 0) { throw new ArgumentOutOfRangeException(nameof(tabSize)); } var simulatedChange = new SourceChange(previousLineEndIndex, 0, string.Empty); var owningSpan = LocateOwner(syntaxTree.Root, simulatedChange); if (owningSpan.Kind == SpanKindInternal.Code) { // Example, // @{\n // ^ - The newline here is a code span and we should just let the default c# editor take care of indentation. return(null); } int?desiredIndentation = null; SyntaxTreeNode owningChild = owningSpan; while ((owningChild.Parent != null) && !desiredIndentation.HasValue) { var owningParent = owningChild.Parent; var children = new List <SyntaxTreeNode>(owningParent.Children); for (var i = 0; i < children.Count; i++) { var currentChild = children[i]; if (!currentChild.IsBlock) { var currentSpan = currentChild as Span; if (currentSpan.Symbols.Count == 1 && currentSpan.Symbols[0] is CSharpSymbol symbol && symbol.Type == CSharpSymbolType.LeftBrace) { var extraIndent = 0; // Dev11 337312: Only indent one level deeper if the item after the open curly brace is a markup block if (i < children.Count - 1) { var nextChild = children[i + 1]; if (nextChild.IsBlock && ((nextChild as Block).Type == BlockKindInternal.Markup)) { extraIndent = indentSize; } } // We can't rely on the syntax trees representation of the source document because partial parses may have mutated // the underlying SyntaxTree text buffer. Because of this, if we want to provide accurate indentations we need to // operate on the current line representation as indicated by the provider. var line = getLineContent(currentSpan.Start.LineIndex); desiredIndentation = GetIndentLevelOfLine(line, tabSize) + indentSize; } } if (currentChild == owningChild) { break; } } owningChild = owningParent; } return(desiredIndentation); }
protected override bool EqualsCore(SyntaxTreeNode b) { var casted = (TagNode)b; return Tag == casted.Tag && AttributeValues.All(attr => casted.AttributeValues[attr.Key] == attr.Value) && casted.AttributeValues.All(attr => AttributeValues[attr.Key] == attr.Value); }
public NavigateCodeIssueEventArgs(SyntaxTreeNode node) { _node = node; }
public MarkupNode(NodeKind kind, SyntaxTreeNode syntaxTreeNode, string contentPart) : base(kind, syntaxTreeNode, contentPart) { }
public static bool TryBind(SyntaxTreeNode node, BindingContext bindingContext, TypeDescription expectedType, out Expression boundExpression, out Exception bindingError) { if (node == null) { throw new ArgumentNullException("node"); } if (bindingContext == null) { throw new ArgumentNullException("bindingContext"); } if (expectedType == null) { throw new ArgumentNullException("expectedType"); } boundExpression = null; bindingError = null; var target = default(Expression); var arguments = node.GetArguments(throwOnError: false); var methodName = node.GetMethodName(throwOnError: true); var useNullPropagation = node.GetUseNullPropagation(throwOnError: false); var methodRef = default(TypeReference); if (BindingContext.TryGetMethodReference(methodName, out methodRef) == false) { bindingError = new ExpressionParserException(string.Format(Properties.Resources.EXCEPTION_BIND_UNABLETORESOLVENAME, methodName), node); return(false); } var targetType = default(Type); if (TryBindTarget(node, bindingContext, out target, out targetType, out bindingError) == false) { return(false); } var isStatic = target == null; var selectedMethodQuality = MemberDescription.QUALITY_INCOMPATIBLE; var hasGenericParameters = methodRef.TypeArguments.Count > 0; var genericArguments = default(Type[]); if (hasGenericParameters) { genericArguments = new Type[methodRef.TypeArguments.Count]; for (var i = 0; i < genericArguments.Length; i++) { var typeArgument = methodRef.TypeArguments[i]; if (bindingContext.TryResolveType(typeArgument, out genericArguments[i]) == false) { bindingError = new ExpressionParserException(string.Format(Properties.Resources.EXCEPTION_BIND_UNABLETORESOLVETYPE, typeArgument), node); return(false); } } } var targetTypeDescription = TypeDescription.GetTypeDescription(targetType); foreach (var memberDescription in targetTypeDescription.GetMembers(methodRef.Name)) { if (memberDescription.IsMethod == false) { continue; } var methodDescription = memberDescription; var method = (MethodInfo)memberDescription; if (method == null || method.IsStatic != isStatic || method.IsGenericMethod != hasGenericParameters) { continue; } if (hasGenericParameters && memberDescription.GenericArgumentsCount != methodRef.TypeArguments.Count) { continue; } if (hasGenericParameters) { try { methodDescription = methodDescription.MakeGenericMethod(genericArguments); method = methodDescription; } catch (ArgumentException exception) { bindingError = exception; continue; /* An element of typeArguments does not satisfy the constraints specified for the corresponding type parameter of the current generic method definition. */ } } var methodQuality = 0.0f; var methodCallExpression = default(Expression); if (methodDescription.TryMakeCall(target, arguments, bindingContext, out methodCallExpression, out methodQuality) == false) { continue; } if (float.IsNaN(methodQuality) || methodQuality <= selectedMethodQuality) { continue; } boundExpression = methodCallExpression; selectedMethodQuality = methodQuality; if (Math.Abs(methodQuality - MemberDescription.QUALITY_EXACT_MATCH) < float.Epsilon) { break; // best match } } if (bindingError != null) { return(false); } if (boundExpression == null) { bindingError = new ExpressionParserException(string.Format(Properties.Resources.EXCEPTION_BIND_UNABLETOBINDCALL, methodRef.Name, targetType, arguments.Count), node); return(false); } if (useNullPropagation && target == null) { bindingError = new ExpressionParserException(string.Format(Properties.Resources.EXCEPTION_BIND_UNABLETOAPPLYNULLCONDITIONALOPERATORONTYPEREF, targetType)); return(false); } if (useNullPropagation && targetTypeDescription.CanBeNull) { bindingContext.RegisterNullPropagationTarget(target); } if (targetTypeDescription.IsAssignableFrom(typeof(Type)) && bindingContext.IsKnownType(typeof(Type)) == false && bindingContext.IsKnownType(targetType) == false) { bindingError = new ExpressionParserException(string.Format(Properties.Resources.EXCEPTION_BIND_RESTRICTED_MEMBER_INVOCATION, methodName, targetType, typeof(ITypeResolver)), node); return(false); } return(true); }
private static void ProcessNode(Span parent, SyntaxTreeNode node, ref List <Image> images) { foreach (SyntaxTreeNode child in node.SubNodes) { if (child is TextNode) { string text = child.ToText(); string newText = ReplaceSmileys(text); newText = ReplaceLinks(newText); if (newText != text) { Span span = new Span(); parent.Inlines.Add(span); var rootNode = ParserInstance.ParseSyntaxTree(newText); ProcessNode(span, rootNode, ref images); } else { parent.Inlines.Add(new Run(text)); } continue; } string tagName = ((TagNode)child).Tag.Name.ToLower(); switch (tagName) { case "br": parent.Inlines.Add(new LineBreak()); break; case "url": // Попытаемся отобразить ссылку try { string hyperlinkText = child.ToText(); if (string.IsNullOrEmpty(hyperlinkText)) { break; } Hyperlink hyperlink = new Hyperlink(); hyperlink.Inlines.Add(new Run(hyperlinkText)); hyperlink.NavigateUri = new Uri(hyperlinkText); Interaction.GetBehaviors(hyperlink).Add(new HyperlinkBehavior()); parent.Inlines.Add(hyperlink); } catch { // Молча продолжаем } break; case "link": // Попытаемся отобразить ссылку try { string hyperlinkLink = GetAttr((TagNode)child, ""); Hyperlink hyperlink = new Hyperlink(); ProcessNode(hyperlink, child, ref images); hyperlink.NavigateUri = new Uri(hyperlinkLink); Interaction.GetBehaviors(hyperlink).Add(new HyperlinkBehavior()); parent.Inlines.Add(hyperlink); } catch { // Молча продолжаем } break; case "smile": // Попытаемся отобразить смайл try { string imageText = child.ToText(); if (!string.IsNullOrEmpty(imageText)) { Image image = new Image(); image.Stretch = Stretch.None; // Зарезервируем место под изображения, но потратим время на дополнительную предварительную загрузку var bitmap = BitmapFrame.Create(new Uri(Path.Combine(Settings.SmileysLocation, imageText)), BitmapCreateOptions.None, BitmapCacheOption.OnLoad); image.Width = bitmap.Width; image.Height = bitmap.Height; XamlAnimatedGif.AnimationBehavior.SetAutoStart(image, Settings.Instance.EnableAnimation); XamlAnimatedGif.AnimationBehavior.SetSourceUri(image, new Uri(Path.Combine(Settings.SmileysLocation, imageText))); parent.Inlines.Add(image); images.Add(image); } } catch { // Молча продолжаем } break; case "img": // Попытаемся отобразить картинку try { string imageText = child.ToText(); if (!string.IsNullOrEmpty(imageText)) { // Добавим обработку кастомных относительных адресов // В будущем желательно вынести в плагин imageText = HttpUtility.UrlDecode(imageText); imageText = imageText.Replace("robochat://", "file:///" + Settings.Directory.Replace('\\', '/')); Image image = new Image(); image.StretchDirection = StretchDirection.DownOnly; image.Source = BitmapFrame.Create(new Uri(imageText, UriKind.RelativeOrAbsolute), BitmapCreateOptions.None, BitmapCacheOption.OnLoad); parent.Inlines.Add(image); images.Add(image); } } catch { // Молча продолжаем } break; case "b": case "i": case "u": var inlineSpan = ProcessTag(tagName); ProcessNode(inlineSpan, child, ref images); parent.Inlines.Add(inlineSpan); break; case "color": var colorSpan = new Span(); ProcessNode(colorSpan, child, ref images); // Попытаемся преобразовать цвет try { string attrText = GetAttr((TagNode)child, ""); var color = (Color)ColorConverter.ConvertFromString(attrText); var brush = new SolidColorBrush(color); colorSpan.Foreground = brush; } catch { // Молча продолжаем } parent.Inlines.Add(colorSpan); break; case "quote": var quotedSpan = new Span(); ProcessNode(quotedSpan, child, ref images); string quotedInfo = GetAttr((TagNode)child, ""); if (quotedInfo == null) { break; } // Блок Figure может идти только со второй строчки parent.Inlines.Add(new Run(quotedInfo + ":") { FontSize = Settings.Instance.FontSize - 2 }); parent.Inlines.Add(new Figure(new Paragraph(quotedSpan)) { BorderBrush = new SolidColorBrush(Colors.Black), BorderThickness = new Thickness(2, 0, 0, 0), HorizontalAnchor = FigureHorizontalAnchor.ContentLeft, Padding = new Thickness(5, 2, 0, 5), Margin = new Thickness(0), WrapDirection = WrapDirection.Left }); parent.Inlines.Add(new LineBreak()); break; } } }
public TagHelperAttributeNode(string name, SyntaxTreeNode value, HtmlAttributeValueStyle valueStyle) { Name = name; Value = value; ValueStyle = valueStyle; }
public T StartChunkBlock <T>(SyntaxTreeNode association) where T : ChunkBlock, new() { return(StartChunkBlock <T>(association, topLevel: false)); }
// Internal for testing internal TagHelperAttributeNode(string name, SyntaxTreeNode value) : this(name, value, HtmlAttributeValueStyle.DoubleQuotes) { }
protected void RegisterTemplate(string name, SyntaxTreeNode syntaxTree) { templates.Add(name, syntaxTree); }
public Generator(SyntaxTreeNode treeRoot) { this.treeRoot = treeRoot; outputText = new List <string>(); }
public static bool TryBind(SyntaxTreeNode node, BindingContext bindingContext, TypeDescription expectedType, out Expression boundExpression, out Exception bindingError) { boundExpression = null; bindingError = null; var useNullPropagation = node.GetUseNullPropagation(throwOnError: false); var arguments = node.GetArguments(throwOnError: true); var targetNode = node.GetExpression(throwOnError: true); var target = default(Expression); if (AnyBinder.TryBind(targetNode, bindingContext, TypeDescription.ObjectType, out target, out bindingError) == false) { return(false); } Debug.Assert(target != null, "target != null"); var targetTypeDescription = TypeDescription.GetTypeDescription(target.Type); if (target.Type.IsArray) { var indexType = TypeDescription.Int32Type; var indexingExpressions = new Expression[arguments.Count]; for (var i = 0; i < indexingExpressions.Length; i++) { var argument = default(SyntaxTreeNode); if (arguments.TryGetValue(i, out argument) == false) { bindingError = new ExpressionParserException(string.Format(Resources.EXCEPTION_BIND_MISSINGMETHODPARAMETER, i), node); return(false); } if (AnyBinder.TryBindInNewScope(argument, bindingContext, indexType, out indexingExpressions[i], out bindingError) == false) { return(false); } Debug.Assert(indexingExpressions[i] != null, "indexingExpressions[i] != null"); } try { if (indexingExpressions.Length == 1) { boundExpression = Expression.ArrayIndex(target, indexingExpressions[0]); } else { boundExpression = Expression.ArrayIndex(target, indexingExpressions); } } catch (Exception exception) { bindingError = new ExpressionParserException(exception.Message, exception, node); return(false); } } else { var selectedIndexerQuality = MemberDescription.QUALITY_INCOMPATIBLE; foreach (var indexer in targetTypeDescription.Indexers) { var indexerQuality = MemberDescription.QUALITY_INCOMPATIBLE; var indexerCall = default(Expression); if (indexer.TryMakeCall(target, arguments, bindingContext, out indexerCall, out indexerQuality) == false) { continue; } if (indexerQuality <= selectedIndexerQuality) { continue; } boundExpression = indexerCall; selectedIndexerQuality = indexerQuality; } } if (boundExpression == null) { bindingError = new ExpressionParserException(string.Format(Resources.EXCEPTION_BIND_UNABLETOBINDINDEXER, target.Type), node); return(false); } if (useNullPropagation && targetTypeDescription.CanBeNull) { bindingContext.RegisterNullPropagationTarget(target); } return(true); }
public static bool TryBind(SyntaxTreeNode node, BindingContext bindingContext, TypeDescription expectedType, out Expression boundExpression, out Exception bindingError) { if (node == null) { throw new ArgumentNullException("node"); } if (bindingContext == null) { throw new ArgumentNullException("bindingContext"); } if (expectedType == null) { throw new ArgumentNullException("expectedType"); } try { var expressionType = node.GetExpressionType(throwOnError: true); switch (expressionType) { case Constants.EXPRESSION_TYPE_PROPERTY_OR_FIELD: return(PropertyOrFieldBinder.TryBind(node, bindingContext, expectedType, out boundExpression, out bindingError)); case Constants.EXPRESSION_TYPE_CONSTANT: return(ConstantBinder.TryBind(node, bindingContext, expectedType, out boundExpression, out bindingError)); case Constants.EXPRESSION_TYPE_CALL: return(CallBinder.TryBind(node, bindingContext, expectedType, out boundExpression, out bindingError)); case "Enclose": case Constants.EXPRESSION_TYPE_UNCHECKED_SCOPE: case Constants.EXPRESSION_TYPE_CHECKED_SCOPE: case Constants.EXPRESSION_TYPE_GROUP: return(GroupBinder.TryBind(node, bindingContext, expectedType, out boundExpression, out bindingError)); case Constants.EXPRESSION_TYPE_INVOKE: return(InvokeBinder.TryBind(node, bindingContext, expectedType, out boundExpression, out bindingError)); case Constants.EXPRESSION_TYPE_LAMBDA: return(LambdaBinder.TryBind(node, bindingContext, expectedType, out boundExpression, out bindingError)); case Constants.EXPRESSION_TYPE_INDEX: return(IndexBinder.TryBind(node, bindingContext, expectedType, out boundExpression, out bindingError)); case Constants.EXPRESSION_TYPE_TYPEOF: return(TypeOfBinder.TryBind(node, bindingContext, expectedType, out boundExpression, out bindingError)); case Constants.EXPRESSION_TYPE_CONVERT: case Constants.EXPRESSION_TYPE_CONVERTCHECKED: case Constants.EXPRESSION_TYPE_TYPEIS: case Constants.EXPRESSION_TYPE_TYPEAS: return(TypeBinaryBinder.TryBind(node, bindingContext, expectedType, out boundExpression, out bindingError)); case Constants.EXPRESSION_TYPE_DEFAULT: return(DefaultBinder.TryBind(node, bindingContext, expectedType, out boundExpression, out bindingError)); case Constants.EXPRESSION_TYPE_NEW: return(NewBinder.TryBind(node, bindingContext, expectedType, out boundExpression, out bindingError)); case Constants.EXPRESSION_TYPE_NEW_ARRAY_BOUNDS: return(NewArrayBoundsBinder.TryBind(node, bindingContext, expectedType, out boundExpression, out bindingError)); case Constants.EXPRESSION_TYPE_ADD: case Constants.EXPRESSION_TYPE_ADD_CHECKED: case Constants.EXPRESSION_TYPE_SUBTRACT: case Constants.EXPRESSION_TYPE_SUBTRACT_CHECKED: case Constants.EXPRESSION_TYPE_LEFTSHIFT: case Constants.EXPRESSION_TYPE_RIGHTSHIFT: case Constants.EXPRESSION_TYPE_GREATERTHAN: case Constants.EXPRESSION_TYPE_GREATERTHAN_OR_EQUAL: case Constants.EXPRESSION_TYPE_LESSTHAN: case Constants.EXPRESSION_TYPE_LESSTHAN_OR_EQUAL: case Constants.EXPRESSION_TYPE_POWER: case Constants.EXPRESSION_TYPE_DIVIDE: case Constants.EXPRESSION_TYPE_MULTIPLY: case Constants.EXPRESSION_TYPE_MULTIPLY_CHECKED: case Constants.EXPRESSION_TYPE_MODULO: case Constants.EXPRESSION_TYPE_EQUAL: case Constants.EXPRESSION_TYPE_NOTEQUAL: case Constants.EXPRESSION_TYPE_AND: case Constants.EXPRESSION_TYPE_OR: case Constants.EXPRESSION_TYPE_EXCLUSIVEOR: case Constants.EXPRESSION_TYPE_ANDALSO: case Constants.EXPRESSION_TYPE_ORELSE: case Constants.EXPRESSION_TYPE_COALESCE: return(BinaryBinder.TryBind(node, bindingContext, expectedType, out boundExpression, out bindingError)); case Constants.EXPRESSION_TYPE_NEGATE: case Constants.EXPRESSION_TYPE_NEGATE_CHECKED: case Constants.EXPRESSION_TYPE_COMPLEMENT: case Constants.EXPRESSION_TYPE_NOT: case Constants.EXPRESSION_TYPE_UNARYPLUS: return(UnaryBinder.TryBind(node, bindingContext, expectedType, out boundExpression, out bindingError)); case Constants.EXPRESSION_TYPE_CONDITION: return(ConditionBinder.TryBind(node, bindingContext, expectedType, out boundExpression, out bindingError)); default: boundExpression = null; bindingError = new ExpressionParserException(string.Format(Properties.Resources.EXCEPTION_BIND_UNKNOWNEXPRTYPE, expressionType), node); return(false); } } catch (ExpressionParserException error) { boundExpression = null; bindingError = error; return(false); } catch (Exception error) { boundExpression = null; bindingError = new ExpressionParserException(string.Format(Properties.Resources.EXCEPTION_BIND_FAILEDTOBIND, node.GetExpressionType(throwOnError: false) ?? "<unknown>", error.Message), error, node); return(false); } }
public void PushExpression(SyntaxTreeNode node) => builder.AddInstruction(CompileNode(node) as InterInst);
public bool IsMatch(string publicScope, string localScope, Instruction instruction, out SyntaxTreeNode node) { node = Parse(publicScope, localScope, instruction); return(node != null); }
public void CompilePropertyDecleration(SyntaxTreeNode node) { var decHeader = node[0]; string access = decHeader[0].ValueString; var type = TypeNameFromNode(decHeader[2]); List <string> keywords = new List <string>(); foreach (var c in decHeader[1].Children) { keywords.Add(c.ValueString); } string name = node[1].ValueString; InterMethod getMethod = null, setMethod = null; bool auto = false; InterProperty property = builder.AddProperty(name, type, access, keywords); InterField backingField = null; foreach (var dec in node[2].Children) { if (!auto && dec.Op == "AutoAccessorDec") { auto = true; backingField = builder.AddField(name + "__backingField", type, access, keywords); } bool get = dec[0].ValueString == "get"; List <string> funcKeywords = new List <string>(keywords); funcKeywords.Add(dec[1].ValueString); PushNewTable(); if (get) { getMethod = builder.AddMethod("get_" + name, type, new ArgumentSymbol[] { }, funcKeywords); } else { var arg = new ArgumentSymbol("value", type, 0); setMethod = builder.AddMethod("set_" + name, new BasicTypeName("void"), new ArgumentSymbol[] { arg }, funcKeywords); } if (!auto) { CompileNode(dec[2]); } else { if (get) { var resolver = new LateReferenceResolver(builder.CurrentNamespaceContext, backingField.Name); resolver.SetOwner(builder.CurrentMethod); builder.AddInstruction(new InterRet(new InterOpValue(resolver))); } else { builder.AddInstruction(new InterCopy(backingField.Symbol, GetFirst("value"))); } } Tables.Pop(); } if (auto && node[3].Children.Length > 0) { backingField.Initializer = ToIntermediateExpression(node[3][0]); } if (getMethod != null) { property.SetGet(getMethod); } if (setMethod != null) { property.SetSet(setMethod); } }
public SyntaxTreeNode Visit(SyntaxTreeNode node) { if (node == null) return null; return node.AcceptVisitor(this); }
private static void AddNullActualError(ErrorCollector collector, SyntaxTreeNode actual, SyntaxTreeNode expected) { collector.AddError("{0} - FAILED :: Actual: << Null >>", expected); }
// 生成中间代码,也就是获取四元式集合 private void GenerateIntermediateCode(SyntaxTreeNode node) { string t1 = ""; string t2 = ""; String op = ""; switch (node.Type) { //case "Statement": case "ReadStatement": for (int i = 0; i < node.ChildTreeNodeList.Count; i++) { GenerateIntermediateCode(node.ChildTreeNodeList[i]); } t1 = argumentStack.Pop(); fourCodeList.Add(new FourCode(FourCode.READ, FourCode.EMPTY, FourCode.EMPTY, t1, level)); break; case "WriteStatement": for (int i = 0; i < node.ChildTreeNodeList.Count; i++) { GenerateIntermediateCode(node.ChildTreeNodeList[i]); } t1 = argumentStack.Pop(); fourCodeList.Add(new FourCode(FourCode.WRITE, FourCode.EMPTY, FourCode.EMPTY, t1, level)); break; case "WhileStatement": for (int i = 0; i < node.ChildTreeNodeList.Count && node.ChildTreeNodeList[i].Name != ")"; i++) { GenerateIntermediateCode(node.ChildTreeNodeList[i]); } t1 = argumentStack.Pop(); fourCodeList.Add(new FourCode(FourCode.IFFALSEJUMP, FourCode.EMPTY, FourCode.EMPTY, "result", level)); int whileIF_F = fourCodeList.Count - 1; GenerateIntermediateCode(node.ChildTreeNodeList[4]); fourCodeList.Add(new FourCode(FourCode.JUMP, FourCode.EMPTY, FourCode.EMPTY, (whileIF_F - 1) + "", level)); int whileGoto = fourCodeList.Count; fourCodeList[whileIF_F].FirstArgument = whileGoto + ""; //跳出while语句 GenerateIntermediateCode(node.ChildTreeNodeList[node.ChildTreeNodeList.Count - 1].ChildTreeNodeList[node.ChildTreeNodeList[node.ChildTreeNodeList.Count - 1].ChildTreeNodeList.Count - 1]); break; case "IfStatement": for (int i = 0; i < node.ChildTreeNodeList.Count && node.ChildTreeNodeList[i].Name != ")"; i++) { GenerateIntermediateCode(node.ChildTreeNodeList[i]); } t1 = argumentStack.Pop(); fourCodeList.Add(new FourCode(FourCode.IFFALSEJUMP, FourCode.EMPTY, FourCode.EMPTY, "result", level)); int ifJump = fourCodeList.Count - 1; // 记录jump指令的位置 GenerateIntermediateCode(node.ChildTreeNodeList[4]); fourCodeList.Add(new FourCode(FourCode.JUMP, FourCode.EMPTY, FourCode.EMPTY, FourCode.EMPTY, level)); int ifGoto = fourCodeList.Count; fourCodeList[ifJump].FirstArgument = ifGoto + ""; ifJump = ifGoto - 1; if (node.ChildTreeNodeList.Count > 5) { GenerateIntermediateCode(node.ChildTreeNodeList[6]); fourCodeList[ifJump].Result = fourCodeList.Count + ""; } else { fourCodeList[ifJump].Result = fourCodeList.Count + ""; GenerateIntermediateCode(node.ChildTreeNodeList[4].ChildTreeNodeList[node.ChildTreeNodeList[4].ChildTreeNodeList.Count - 1]); } break; case "AssignmentStatement": for (int i = 0; i < node.ChildTreeNodeList.Count; i++) { GenerateIntermediateCode(node.ChildTreeNodeList[i]); } t1 = argumentStack.Pop(); t2 = argumentStack.Pop(); op = operationStack.Pop(); fourCodeList.Add(new FourCode(FourCode.ASIGN, t1, t2, FourCode.EMPTY, level)); break; case "VariableDeclarationStatement": switch (GetDeclarationType(node)) { //==========Integer声明语句========== case "DeclareInt": for (int i = 0; i < node.ChildTreeNodeList.Count; i++) { GenerateIntermediateCode(node.ChildTreeNodeList[i]); } int opNum = operationStack.Count; for (int i = 0; i <= opNum; i++) { //获取op、t1、t2 if (operationStack.Count > 0) { op = operationStack.Pop(); } else { op = FourCode.EMPTY; } if (argumentStack.Count > 0) { t1 = argumentStack.Pop(); } else { t1 = FourCode.EMPTY; } if (argumentStack.Count > 0 && t1 != "separator") { t2 = argumentStack.Pop(); } else { t2 = FourCode.EMPTY; } //判断后添加 if (t2 == "separator" && op == "separator") { fourCodeList.Add(new FourCode(FourCode.DECLARATIONINT, "0", t1, FourCode.EMPTY, level)); } else if (op == "=") { //声明并赋值 fourCodeList.Add(new FourCode(FourCode.DECLARATIONINT, t1, t2, FourCode.EMPTY, level)); } else if (op == FourCode.EMPTY && t1 != FourCode.EMPTY && t2 == FourCode.EMPTY) { fourCodeList.Add(new FourCode(FourCode.DECLARATIONINT, "0", t1, FourCode.EMPTY, level)); } } break; //==========Real声明语句========== case "DeclareReal": for (int i = 0; i < node.ChildTreeNodeList.Count; i++) { GenerateIntermediateCode(node.ChildTreeNodeList[i]); } opNum = operationStack.Count; for (int i = 0; i <= opNum; i++) { //获取op、t1、t2 if (operationStack.Count > 0) { op = operationStack.Pop(); } else { op = FourCode.EMPTY; } if (argumentStack.Count > 0) { t1 = argumentStack.Pop(); } else { t1 = FourCode.EMPTY; } if (argumentStack.Count > 0 && t1 != "separator") { t2 = argumentStack.Pop(); } else { t2 = FourCode.EMPTY; } //添加 if (t2 == "separator" && op == "separator" && t2 != FourCode.EMPTY) { fourCodeList.Add(new FourCode(FourCode.DECLATATIONREAL, "0", t1, FourCode.EMPTY, level)); } else if (op == "=") { // 声明并赋值 fourCodeList.Add(new FourCode(FourCode.DECLATATIONREAL, t1, t2, FourCode.EMPTY, level)); } else if (op == FourCode.EMPTY && t1 != FourCode.EMPTY && t2 == FourCode.EMPTY) { fourCodeList.Add(new FourCode(FourCode.DECLATATIONREAL, "0", t1, FourCode.EMPTY, level)); } } break; } break; //==========块========== case "Block": level++; for (int i = 0; i < node.ChildTreeNodeList.Count; i++) { GenerateIntermediateCode(node.ChildTreeNodeList[i]); } level--; break; //==========条件表达式========== case "Condition": for (int i = 0; i < node.ChildTreeNodeList.Count; i++) { GenerateIntermediateCode(node.ChildTreeNodeList[i]); } t1 = argumentStack.Pop(); t2 = argumentStack.Pop(); op = operationStack.Pop(); try { if (op == "==") { fourCodeList.Add(new FourCode(FourCode.EQUAL, t1, t2, "result", level)); argumentStack.Push("result"); } else if (op == "<>") { fourCodeList.Add(new FourCode(FourCode.NOTEQUAL, t1, t2, "result", level)); argumentStack.Push("result"); } else if (op == ">") { fourCodeList.Add(new FourCode(FourCode.LARGER, t1, t2, "result", level)); argumentStack.Push("result"); } else if (op == "<") { fourCodeList.Add(new FourCode(FourCode.SMALLER, t1, t2, "result", level)); argumentStack.Push("result"); } } catch (FormatException e) { Console.WriteLine("Conversion error."); } break; //==========算术表达式========== case "Expression": for (int i = 0; i < node.ChildTreeNodeList.Count; i++) { GenerateIntermediateCode(node.ChildTreeNodeList[i]); } if (node.ChildTreeNodeList.Count == 1) { // } else { for (int i = 0; i < ((node.ChildTreeNodeList.Count - 1) / 2); i++) { t1 = argumentStack.Pop(); t2 = argumentStack.Pop(); op = operationStack.Pop(); if (op == "+") { fourCodeList.Add(new FourCode(FourCode.ADD, t1, t2, "result", level)); argumentStack.Push("result"); } else if (op == "-") { fourCodeList.Add(new FourCode(FourCode.SUB, t1, t2, "result", level)); argumentStack.Push("result"); } } } if (isArray) { t1 = argumentStack.Pop(); t2 = argumentStack.Pop(); t2 = t2 + "[" + t1 + "]"; argumentStack.Push(t2); isArray = false; } break; //==========项========== case "Term": for (int i = 0; i < node.ChildTreeNodeList.Count; i++) { GenerateIntermediateCode(node.ChildTreeNodeList[i]); } if (node.ChildTreeNodeList.Count == 1) { // } else { for (int i = 0; i < ((node.ChildTreeNodeList.Count - 1) / 2); i++) { t1 = argumentStack.Pop(); t2 = argumentStack.Pop(); op = operationStack.Pop(); if (op == "*") { fourCodeList.Add(new FourCode(FourCode.MUL, t1, t2, "result", level)); argumentStack.Push("result"); } else if (op == "/") { fourCodeList.Add(new FourCode(FourCode.DIV, t1, t2, "result", level)); argumentStack.Push("result"); } } } break; //==========因子========== case "Factor": for (int i = 0; i < node.ChildTreeNodeList.Count; i++) { GenerateIntermediateCode(node.ChildTreeNodeList[i]); } break; //==========算术符========== case "Arithmetic": operationStack.Push(node.Name); break; //==========关系运算符========== case "Comparison": operationStack.Push(node.Name); break; //==========标识符========== case "Identifier": argumentStack.Push(node.Name); break; //==========int========== case "Integer": argumentStack.Push(node.Name); break; //==========real========== case "Real": argumentStack.Push(node.Name); break; //==========分隔符========== case "Comma": argumentStack.Push("separator"); operationStack.Push("separator"); break; //==========等号========== case "Assignment": operationStack.Push("="); break; //==========数组========== case "ArrayLeftDelimiter": this.isArray = true; break; //==========其他标记忽略========== default: for (int i = 0; i < node.ChildTreeNodeList.Count; i++) { GenerateIntermediateCode(node.ChildTreeNodeList[i]); } break; } }
private static void EvaluateSyntaxTreeNode(ErrorCollector collector, SyntaxTreeNode actual, SyntaxTreeNode expected) { if (actual == null) { AddNullActualError(collector, actual, expected); } if (actual.IsBlock != expected.IsBlock) { AddMismatchError(collector, actual, expected); } else { if (expected.IsBlock) { EvaluateBlock(collector, (Block)actual, (Block)expected); } else { EvaluateSpan(collector, (Span)actual, (Span)expected); } } }
/// <summary> /// Formats <see cref="SyntaxTreeNode"/> into string representation. /// </summary> /// <param name="syntaxTree">An valid syntax tree.</param> /// <param name="checkedScope">True to assume all arithmetic and conversion operation is checked for overflows.</param> /// <returns>C# formatted expression.</returns> public static string Format(this SyntaxTreeNode syntaxTree, bool checkedScope = DEFAULT_CHECKED_SCOPE) { return(CSharpSyntaxTreeFormatter.Format(syntaxTree, checkedScope)); }
protected override bool EqualsCore(SyntaxTreeNode b) { return true; }
static void LemmatizeTextFile(string dictionary_xml, string corpus_path, string result_path) { int LanguageID = SolarixGrammarEngineNET.GrammarEngineAPI.RUSSIAN_LANGUAGE; // int Constraints = 60000 | (30 << 22); // 1 минута и 30 альтернатив using (GrammarEngine2 gren = new GrammarEngine2()) { gren.Load(DictionaryXmlPath: dictionary_xml, LazyLexicon: true); Console.WriteLine($"Словарь {dictionary_xml} успешно загружен"); int pronoun_class = gren.FindPartOfSpeech("МЕСТОИМЕНИЕ"); Debug.Assert(pronoun_class != -1); int person_coord = gren.FindCoord("ЛИЦО"); Debug.Assert(person_coord != -1); int person1 = gren.FindState(person_coord, "1"); int person2 = gren.FindState(person_coord, "2"); int person3 = gren.FindState(person_coord, "3"); Dictionary <int, string> id_entry2lemma = new Dictionary <int, string>(); using (System.IO.StreamWriter wrt = new System.IO.StreamWriter(result_path)) { int line_count = 0; using (System.IO.StreamReader rdr = new System.IO.StreamReader(corpus_path)) { while (!rdr.EndOfStream) { string line = rdr.ReadLine(); if (line == null) { break; } line_count++; if ((line_count % 100) == 0) { Console.Write($"{line_count} lines parsed\r"); } List <string> sentences = gren.SplitText(line, LanguageID); List <string> line_lemmas = new List <string>(capacity: line.Length / 5 + 1); foreach (string sentence in sentences) { AnalysisResults anares = gren.AnalyzeMorphology(sentence, LanguageID, SolarixGrammarEngineNET.GrammarEngine.MorphologyFlags.SOL_GREN_MODEL_ONLY); for (int itoken = 1; itoken < anares.Count - 1; ++itoken) { SyntaxTreeNode node = anares[itoken]; string lemma = null; int id_entry = node.GetEntryID(); if (id_entry != -1) { if (pronoun_class == gren.GetEntryClass(id_entry)) { // В словарной базе Solarix местоимения НАС, ВАМИ etc. приводятся к базовой форме Я // Таким образом, словоизменение по лицам устраняется. Такая агрессивная лемматизация // высокочастотных слов может быть нежелательна для семантического анализа, поэтому // сделаем ручную лемматизацию. int person = node.GetCoordState(person_coord); if (person == person1) { lemma = "я"; } else if (person == person2) { lemma = "ты"; } else if (person == person3) { lemma = "он"; } else { Debug.Fail("Unknown person tag"); } } else { if (id_entry2lemma.ContainsKey(id_entry)) { lemma = id_entry2lemma[id_entry]; } else { lemma = gren.GetEntryName(id_entry); if (lemma.Equals("unknownentry", StringComparison.OrdinalIgnoreCase)) { lemma = node.GetWord(); } else if (lemma.Equals("???")) { lemma = node.GetWord(); } else { lemma = lemma.Replace(' ', '_'); // для MWU типа "в конце концов" } } id_entry2lemma[id_entry] = lemma; } } else { lemma = node.GetWord(); } lemma = lemma.ToLower(); line_lemmas.Add(lemma); } } wrt.WriteLine(string.Join(" ", line_lemmas)); } } } } return; }
/// <summary> /// Adds a new node to the block /// </summary> /// <param name="node"></param> public void Add(SyntaxTreeNode node) { this.nodes.Add(node); }
public SyntaxTree(Stack<Parser.Item> items) { Root = new SyntaxTreeNode(items); }