/// <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) { }
/// <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)); }
/** * 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); }