コード例 #1
0
 private void EnqueOperation(ExpressionOperation operation)
 {
     while (operatorStack.Count > 0 && operation.Precedence <= operatorStack.Peek().Precedence)
     {
         outputQueue.Enqueue(operatorStack.Pop());
     }
     operatorStack.Push(operation);
 }
コード例 #2
0
        public override void EndNode(ParserContext context)
        {
            switch (context.NodeKind)
            {
                case SyntaxNodeKind.Expression:
                    while (operatorStack.Count > 0)
                    {
                        var op = operatorStack.Pop();
                        if (op.Kind == ExpressionOperationKind.Expression)
                            break;
                        outputQueue.Enqueue(op);
                    }
                    break;
                case SyntaxNodeKind.UnaryOperator:
                    var unaryOp = new ExpressionOperation(ConvertUnaryToOperationKind(context.Span));
                    EnqueOperation(unaryOp);
                    break;
                case SyntaxNodeKind.Operator:
                    var op1 = new ExpressionOperation(ConvertToOperationKind(context.Span));
                    EnqueOperation(op1);
                    break;
                case SyntaxNodeKind.Constant:
                    outputQueue.Enqueue(
                        new ExpressionOperation(ExpressionOperationKind.Number, ToNumber(context.Span.Text)));
                    break;
                case SyntaxNodeKind.ExpressionIdentifier:
                    Label label;
                    var labelName = context.Span.Text;
                    var found = labelStore.TryGetLabel(labelName, out label);

                    var topOperatorKind = operatorStack.Peek().Kind;

                    switch (topOperatorKind)
                    {
                        case ExpressionOperationKind.Def:
                            labelStore.AddReferencedLabel(labelName, lineNumber);
                            operatorStack.Pop();
                            outputQueue.Enqueue(new ExpressionOperation(ExpressionOperationKind.Number, found ? 1 : 0));
                            break;
                        case ExpressionOperationKind.Ref:
                            operatorStack.Pop();
                            ISet<int> referencingLines;
                            
                            bool anyReference = labelStore.TryGetReferencingLines(labelName, out referencingLines);
                            int refOperatorResult = (anyReference &&
                                                (referencingLines.Count != 1 || !referencingLines.Contains(lineNumber)))
                                ? 1
                                : 0;
                            outputQueue.Enqueue(new ExpressionOperation(ExpressionOperationKind.Number, refOperatorResult));
                            break;
                        default:
                            labelStore.AddReferencedLabel(labelName, lineNumber);
                            outputQueue.Enqueue(
                                found
                                    ? new ExpressionOperation(ExpressionOperationKind.Number, label.Value)
                                    : new ExpressionOperation(ExpressionOperationKind.Number, 0));
                            break;
                    }
                    break;
            }
        }