C 언어 해석기 - 18 문법 분석(3)

표현식 해석에서 중요한 것은 표현식 트리에서 연산자를 삽입하는 것입니다. 우선 순위 비교가 필요합니다.
private bool AddOperatorNode(ref Expression.ExpressionNode expTree, Expression.Operator.Operator op)
        {
            Expression.ExpressionNode node = new Expression.ExpressionNode()
            {
                Token = op
            };

            if (expTree != null && expTree.Token is Expression.Operand.Operand)
            {
                node.LeftNode = expTree;
                expTree = node;
            }
            else
            {
                if (expTree == null)
                {
                    expTree = node;
                }
                else
                {
                    if (node.Token <= expTree.Token)
                    {
                        node.LeftNode = expTree;
                        expTree = node;
                    }
                    else
                    {
                        Expression.ExpressionNode parent = null;
                        Expression.ExpressionNode root = expTree;

                        do
                        {
                            // Operand ?
                            if (root.Token is Expression.Operand.Operand)
                            {
                                if (parent != null)
                                {
                                    parent.RightNode = node;
                                    node.LeftNode = root;
                                    break;
                                }
                                else
                                {
                                    node.LeftNode = root;
                                    root = node;
                                    break;
                                }
                            }

                            // Less priority, new node will be add to right child node
                            if (root.Token <= node.Token)
                            {
                                if (root.RightNode == null)
                                {
                                    root.RightNode = node;
                                    break;
                                }

                                parent = root;
                                root = root.RightNode;
                            }
                            else
                            {
                                // Higher priority
                                if (parent == null)
                                {
                                    node.LeftNode = root;
                                    expTree = node;
                                }
                                else
                                {
                                    parent.RightNode = node;
                                    node.LeftNode = root;
                                }
                                break;
                            }
                        } while (true);
                    }
                }
            }

            m_lastExpNode = node;

            return true;
        } // func

다음은 작업 수를 추가하는 작업이며 유형 일치 확인이 필요합니다.
private bool AddOperandNode(Context ctx, SourceCode src, ref Expression.ExpressionNode expTree, Expression.Operand.Operand op)
        {
            Expression.ExpressionNode node = new Expression.ExpressionNode()
            {
                Token = op
            };

            if (expTree == null)
            {
                expTree = node;
                m_lastExpNode = node;
                return true;
            }

            // Root should be operator.
            if (expTree.Token is Expression.Operand.Operand)
                if (!NotifyError(ctx, src.Location, ParsingErrorType.SyntaxError, "Syntax error.")) 
                    return false;

            Expression.ExpressionNode root = expTree;

            // Add to end of right side
            while (root.RightNode != null)
                root = root.RightNode;

            // Check type
            if (root.LeftNode != null)
            {
                DataTypeInfo leftDti = root.LeftNode.ResultType(ctx);
                DataTypeInfo rightDti = op.GetTypeInfo(ctx);

                if (leftDti != rightDti)
                {
                    // void type has no meaning
                    if (leftDti.BaseType == PrimitiveDataType.VoidType && !leftDti.IsPointer)
                        if (!NotifyError(ctx, src.Location, ParsingErrorType.TypeError, "Incomplete type void")) 
                            return false;

                    if ((leftDti.IsPointer && (!rightDti.IsPointer && rightDti.BaseType == PrimitiveDataType.VoidType || rightDti.BaseType == PrimitiveDataType.FloatType)) ||
                        ((!leftDti.IsPointer && leftDti.BaseType == PrimitiveDataType.VoidType || leftDti.BaseType == PrimitiveDataType.FloatType) && rightDti.IsPointer))
                    {
                        // A warning should be cast.
                        NotifyWarning(ctx, src.Location, rightDti.ToString() + " will be cast to " + leftDti.ToString()); 
                    }
                }
            }

            root.RightNode = node;
            m_lastExpNode = node;
            return true;
        }

 
 
 

좋은 웹페이지 즐겨찾기