예제 #1
0
 /// <summary>
 /// Exit a parse tree produced by <see cref="CMMParser.factor"/>.
 /// <para>The default implementation does nothing.</para>
 /// </summary>
 /// <param name="context">The parse tree.</param>
 public virtual void ExitFactor([NotNull] CMMParser.FactorContext context)
 {
 }
예제 #2
0
 /// <summary>
 /// Visit a parse tree produced by <see cref="CMMParser.factor"/>.
 /// <para>
 /// The default implementation returns the result of calling <see cref="AbstractParseTreeVisitor{Result}.VisitChildren(IRuleNode)"/>
 /// on <paramref name="context"/>.
 /// </para>
 /// </summary>
 /// <param name="context">The parse tree.</param>
 /// <return>The visitor result.</return>
 public virtual Result VisitFactor([NotNull] CMMParser.FactorContext context)
 {
     return(VisitChildren(context));
 }
예제 #3
0
        /**
         * factor 情况比较多
         *
         *
         */

        /*
         * int a = 1;
         * a = a+2;
         * out(a);
         */
        public override object VisitFactor([NotNull] CMMParser.FactorContext context)
        {
            int funcAddr;

            if (context.Identifier() != null)
            {
                switch (context.ChildCount)
                {
                case 1:
                    // 访问局部变量
                    if (!curLocalVariablesTable.TryGetValue(context.Identifier().GetText(), out int addr))
                    {
                        throw new VariableNotFountException(context.Identifier().GetText(), context);
                    }
                    codes.Add(new IntermediateCode(addr, InstructionType.pushv, context.Start.Line));

                    break;

                case 3:
                    // 这是不带参数函数调用的情况
                    functionAddressTable.TryGetValue(context.GetChild(0).GetText(), out funcAddr);
                    codes.Add(new IntermediateCode(funcAddr, InstructionType.call, context.Start.Line));
                    break;

                case 4:

                    if (context.GetChild(1).GetText().Equals("["))
                    {
                        // 这是数组的情况
                        curLocalVariablesTable.TryGetValue(context.GetChild(0).GetText(), out int arrayAddr);
                        // 先计算表达式的值
                        Visit(context.GetChild(2));
                        // 此时栈顶是数组的下标 再压入数组的地址 然后相加得到该元素的地址
                        codes.Add(new IntermediateCode(arrayAddr, InstructionType.push, context.Start.Line));
                        codes.Add(new IntermediateCode(InstructionType.add, context.Start.Line));
                        // pushv指令不带操作数 将当前栈顶的元素作为地址 到局部变量表中把对应地址的元素压栈
                        codes.Add(new IntermediateCode(InstructionType.pushv, context.Start.Line));
                    }
                    else
                    {
                        // 这是带参数函数调用的情况
                        // 首先把参数压栈
                        Visit(context.expressionList());
                        // 然后把参数个数压栈
                        int count = getLen(context.expressionList());
                        codes.Add(new IntermediateCode(count, InstructionType.push, context.Start.Line));
                        functionAddressTable.TryGetValue(context.Identifier().GetText(), out funcAddr);
                        // 添加call指令 不能直接压入函数地址,因为此时函数可能还没定义。先压入函数名,所有代码生成结束后再回填函数地址。
                        codes.Add(new IntermediateCode(context.Identifier().GetText(), InstructionType.call, context.Start.Line));
                    }
                    break;
                }
                return(null);
            }
            if (context.GetChild(0).GetText() == "(")
            {
                // 表达式的情况 直接遍历表达式求值
                Visit(context.GetChild(1));
            }
            if (context.Sub() != null)
            {
                // 取相反数的情况 先visit factor,它的值压栈后加入neg指令
                Visit(context.GetChild(1));
                // 直接把栈顶元素取反
                // Double num = (Double)expStack.Pop();
                // expStack.Push(-num);
                codes.Add(new IntermediateCode(InstructionType.neg, context.Start.Line));
            }
            if (context.IntegerLiteral() != null)
            {
                // 整数直接压栈
                // expStack.Push(Convert.ToDouble(context.IntegerLiteral().GetText()));
                codes.Add(new IntermediateCode(Convert.ToDouble(context.IntegerLiteral().GetText()), InstructionType.push, context.Start.Line));
            }
            if (context.RealLiteral() != null)
            {
                // 实数直接压栈
                // expStack.Push(Convert.ToDouble(context.IntegerLiteral().GetText()));
                codes.Add(new IntermediateCode(Convert.ToDouble(context.IntegerLiteral().GetText()), InstructionType.push, context.Start.Line));
            }
            if (context.True() != null)
            {
                // true压入1
                // expStack.Push(1);
                codes.Add(new IntermediateCode(1, InstructionType.push, context.True().Symbol.Line));
            }
            if (context.False() != null)
            {
                // false压入0
                // expStack.Push(0);
                codes.Add(new IntermediateCode(0, InstructionType.push, context.False().Symbol.Line));
            }


            return(null);
        }