lab6的语义分析要求能够识别出3种C语言错误即可,本次实验选择的是0_var_not_defined,1_var_defined_again,2_break_not_in_loop三种错误。
lab7的中间代码生成是将AST树翻译成四元式,对于变量的寄存器分配方法选择的是不进行分配,统一设置为全局变量。
实验思路在BITMINICC——lab6+lab7_寒士°、的博客-CSDN博客中,本篇给出详细代码,可以结合起来看。
1.在BIT-MiniCC-master\src\bit\minisys\minicc\semantic中创建FuncTable.java和VarTable.java
维护函数表和变量表,目的是检测var_not_defined和var_defined_again两种错误
//FuncTable.java
package bit.minisys.minicc.semantic;
import java.util.List;
public class FuncTable {
public List VariableTable;
public String funcName;
public String specifiers;
public String type;
}
//VarTable.java
package bit.minisys.minicc.semantic;
import bit.minisys.minicc.parser.ast.ASTExpression;
public class VarTable {
public String name;
public String type;
public String specifiers;
public ASTExpression value;
public int dimension;
public int length;
}
2.在BIT-MiniCC-master\src\bit\minisys\minicc\icgen中
LabelGenrator.java
//LabelGenerator.java
package bit.minisys.minicc.icgen;
import bit.minisys.minicc.parser.ast.ASTNode;
import bit.minisys.minicc.parser.ast.ASTVisitor;
public class LabelGenerator extends ASTNode {
private Integer id;
public String Type;
public Integer num;
public String name() {
if(id==0){
return "@"+Type;
}
else return "@"+id+Type;
}
@Override
public void accept(ASTVisitor visitor) throws Exception {
}
public LabelGenerator(Integer id,String Type,Integer num) {
super("TemporaryValue");
this.id = id;
this.Type=Type;
this.num=num;
}
public LabelGenerator(String type) {
super(type);
}
}
Quat.java
package bit.minisys.minicc.icgen;
import bit.minisys.minicc.parser.ast.ASTNode;
public class Quat {
private String op;
private ASTNode res;
private ASTNode opnd1;
private ASTNode opnd2;
public Quat(String op, ASTNode res, ASTNode opnd1, ASTNode opnd2) {
this.op = op;
this.res = res;
this.opnd1 = opnd1;
this.opnd2 = opnd2;
}
public String getOp() {
return op;
}
public ASTNode getOpnd1() {
return opnd1;
}
public ASTNode getOpnd2() {
return opnd2;
}
public ASTNode getRes() {
return res;
}
}
TemporaryValue.java
package bit.minisys.minicc.icgen;
import bit.minisys.minicc.parser.ast.ASTNode;
import bit.minisys.minicc.parser.ast.ASTVisitor;
// ��ʱ����
public class TemporaryValue extends ASTNode{
private Integer id;
public String name() {
return "@"+id;
}
@Override
public void accept(ASTVisitor visitor) throws Exception {
}
public TemporaryValue(Integer id) {
super("TemporaryValue");
this.id = id;
}
public TemporaryValue(String type) {
super(type);
}
}
MyICBuilder.java
package bit.minisys.minicc.icgen;
import bit.minisys.minicc.parser.ast.*;
import bit.minisys.minicc.semantic.FuncTable;
import bit.minisys.minicc.semantic.VarTable;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;
import java.util.*;
public class MyICBuilder {
public String Errorfilename;
public String Icfilename;
public String Symbolname;
public static List ProcTable = new LinkedList<>();
public static List GlobalVarTable = new LinkedList<>();
public static List ErrorTable = new LinkedList<>();
public static int tmpRegID=0;
public static int tmpLabelID=1;
public static int IfLabelID=0;
public static Map map;
public static List quats;
private static ASTNode loopStartLabel=null;
private static ASTNode loopNextLabel=null;
private static ASTNode loopEndLabel=null;
private static Map Label;
public static List Scope=new LinkedList<>();
public static Stack> Var = new Stack<>();
public MyICBuilder() {
map = new HashMap();
Label=new HashMap();
quats = new LinkedList();
tmpRegID = 0;
}
public static void visit(ASTCompilationUnit astCompilationUnit){
for(ASTNode child : astCompilationUnit.items){
if(child instanceof ASTDeclaration){
visit((ASTDeclaration) child);
}
else if(child instanceof ASTFunctionDefine){
visit((ASTFunctionDefine) child);
}
}
}
public static void GetfuncDeclara(FuncTable funcTable,ASTFunctionDeclarator declarator){
ASTVariableDeclarator variableDeclarator = (ASTVariableDeclarator) declarator.declarator;
ASTIdentifier identifier=variableDeclarator.identifier;
funcTable.funcName=identifier.value;
funcTable.type=declarator.getType();
}
public static void GetVarTable(VarTable varTable,ASTInitList node){
ASTNode child = node.declarator;
if(child.getClass()==ASTVariableDeclarator.class){
ASTIdentifier identifier=((ASTVariableDeclarator) child).identifier;
varTable.name=identifier.value;
varTable.dimension=1;
varTable.length=1;
varTable.type=child.getType();
if(node.exprs!=null){
varTable.value = node.exprs.get(0);
visit(varTable.value);
ASTNode opnd=map.get(varTable.value);
Quat quat = new Quat("=",identifier,opnd,null);
quats.add(quat);
}
}
else if(child.getClass()==ASTArrayDeclarator.class){
varTable.type=child.getType();
int dim=0;
int length=1;
while (child.getClass()!=ASTVariableDeclarator.class){
ASTNode integer=((ASTArrayDeclarator) child).expr;
length=length*((ASTIntegerConstant) integer).value;
dim=dim+1;
child=((ASTArrayDeclarator) child).declarator;
}
ASTIdentifier identifier=((ASTVariableDeclarator) child).identifier;
varTable.name=identifier.value;
varTable.dimension=dim;
varTable.length=length;
}
}
public static void visit(ASTDeclaration astDeclaration){
if(astDeclaration.parent.getClass()==ASTCompilationUnit.class){
ASTToken astToken = astDeclaration.specifiers.get(0);
for(ASTInitList astInitList : astDeclaration.initLists){
ASTDeclarator declarator = astInitList.declarator;
if(declarator.getClass()==ASTFunctionDeclarator.class){
FuncTable funcTable = new FuncTable();
funcTable.VariableTable=new LinkedList<>();
funcTable.specifiers=astDeclaration.specifiers.get(0).value;
GetfuncDeclara(funcTable,(ASTFunctionDeclarator) declarator);
ProcTable.add(funcTable);
}
else{
VarTable varTable = new VarTable();
varTable.specifiers=astToken.value;
GetVarTable(varTable,astInitList);
boolean flag=true;
for (VarTable var:GlobalVarTable){
if(var.name.equals(varTable.name)){
flag=false;
break;
}
}
if(!flag){
String Error="ES02: var_"+varTable.name+"_defined_again\n";
ErrorTable.add(Error);
}
GlobalVarTable.add(varTable);
}
}
}
else if(astDeclaration.parent.getClass()==ASTIterationDeclaredStatement.class){
ASTToken astToken = astDeclaration.specifiers.get(0);
for(ASTInitList astInitList : astDeclaration.initLists){
ASTDeclarator declarator = astInitList.declarator;
VarTable varTable = new VarTable();
varTable.specifiers=astToken.value;
GetVarTable(varTable,astInitList);
boolean flag=true;
for (VarTable var:Scope){
if(var.name.equals(varTable.name)){
flag=false;
break;
}
}
if(!flag){
String Error="ES02: var_"+varTable.name+"_defined_again\n";
ErrorTable.add(Error);
}
Scope.add(varTable);
}
}
else if(astDeclaration.parent.getClass()==ASTCompoundStatement.class){
ASTToken astToken = astDeclaration.specifiers.get(0);
for(ASTInitList astInitList : astDeclaration.initLists){
ASTDeclarator declarator = astInitList.declarator;
VarTable varTable = new VarTable();
varTable.specifiers=astToken.value;
GetVarTable(varTable,astInitList);
boolean flag=true;
for (VarTable var:Scope){
if(var.name.equals(varTable.name)){
flag=false;
break;
}
}
if(!flag){
String Error="ES02: var_"+varTable.name+"_defined_again\n";
ErrorTable.add(Error);
}
Scope.add(varTable);
}
}
else{
ASTCompoundStatement astCompoundStatement = (ASTCompoundStatement) astDeclaration.parent;
ASTFunctionDefine astFunctionDefine = (ASTFunctionDefine) astCompoundStatement.parent;
ASTFunctionDeclarator astFunctionDeclarator = (ASTFunctionDeclarator) astFunctionDefine.declarator;
ASTVariableDeclarator astVariableDeclarator = (ASTVariableDeclarator) astFunctionDeclarator.declarator;
ASTIdentifier astIdentifier = astVariableDeclarator.identifier;
for(ASTInitList astInitList : astDeclaration.initLists){
VarTable varTable = new VarTable();
varTable.specifiers=astDeclaration.specifiers.get(0).value;
GetVarTable(varTable,astInitList);
for(FuncTable funcTable : ProcTable){
if(funcTable.funcName.equals(astIdentifier.value)){
funcTable.VariableTable.add(varTable);
}
}
}
}
}
public static void visit(ASTFunctionDefine astFunctionDefine){
FuncTable funcTable = new FuncTable();
funcTable.VariableTable=new LinkedList<>();
funcTable.type=astFunctionDefine.getType();
ASTFunctionDeclarator astFunctionDeclarator = (ASTFunctionDeclarator) astFunctionDefine.declarator;
ASTVariableDeclarator astVariableDeclarator = (ASTVariableDeclarator) astFunctionDeclarator.declarator;
for(int i=0;i>=") ||op.equals("&=") ||op.equals("^=") ||op.equals("|=")) {
visit(astBinaryExpression.expr1);
res = map.get(astBinaryExpression.expr1);
if (astBinaryExpression.expr2 instanceof ASTIdentifier) {
opnd1 = astBinaryExpression.expr2;
}
else if(astBinaryExpression.expr2 instanceof ASTIntegerConstant) {
opnd1 = astBinaryExpression.expr2;
}
else if(astBinaryExpression.expr2 instanceof ASTStringConstant) {
opnd1 = astBinaryExpression.expr2;
}
else if(astBinaryExpression.expr2 instanceof ASTBinaryExpression) {
ASTBinaryExpression value = (ASTBinaryExpression) astBinaryExpression.expr2;
op = value.op.value;
visit(value.expr1);
opnd1 = map.get(value.expr1);
visit(value.expr2);
opnd2 = map.get(value.expr2);
}
else if(astBinaryExpression.expr2 instanceof ASTUnaryExpression){
ASTUnaryExpression value = (ASTUnaryExpression) astBinaryExpression.expr2;
op = value.op.value;
visit(value);
opnd1 = map.get(value.expr);
}
else if(astBinaryExpression.expr2 instanceof ASTPostfixExpression){
ASTPostfixExpression value = (ASTPostfixExpression) astBinaryExpression.expr2;
op = value.op.value;
visit(value);
opnd2 = map.get(value.expr);
}
else {
visit(astBinaryExpression.expr2);
opnd1=map.get(astBinaryExpression.expr2);
// else ...
}
}
else {
res = new TemporaryValue(++tmpRegID);
VarTable varTable = new VarTable();
varTable.name=((TemporaryValue) res).name();
varTable.type="VariableDeclarator";
Scope.add(varTable);
visit(astBinaryExpression.expr1);
opnd1 = map.get(astBinaryExpression.expr1);
visit(astBinaryExpression.expr2);
opnd2 = map.get(astBinaryExpression.expr2);
}
// build quat
Quat quat = new Quat(op, res, opnd1, opnd2);
quats.add(quat);
map.put(astBinaryExpression, res);
}
public static void visit(ASTIdentifier astIdentifier){
boolean flag=false;
if(Scope.size()>0){
for(VarTable varTable:Scope){
if(astIdentifier.value.equals(varTable.name)){
flag=true;
break;
}
}
}
FuncTable funcTable=ProcTable.get(ProcTable.size()-1);
if(funcTable.VariableTable.size()>0&&(!flag)){
for(VarTable varTable : funcTable.VariableTable){
if(astIdentifier.value.equals(varTable.name)){
flag=true;
break;
}
}
}
if(GlobalVarTable.size()>0&&(!flag)){
for(VarTable varTable:GlobalVarTable){
if(astIdentifier.value.equals(varTable.name)){
flag=true;
break;
}
}
}
if(!flag){
String ERROR="ES01: "+astIdentifier.value+"_is_not_defined\n";
ErrorTable.add(ERROR);
}
map.put(astIdentifier, astIdentifier);
}
public static void visit(ASTIntegerConstant astIntegerConstant){
map.put(astIntegerConstant,astIntegerConstant);
}
public static void visit(ASTStringConstant astStringConstant){
map.put(astStringConstant,astStringConstant);
}
public static void visit(ASTFunctionCall astFunctionCall){
String type="";
String name="";
if(astFunctionCall.argList!=null){
for(int i =0;i0){
for(VarTable varTable:Scope){
if(((ASTIdentifier) astExpression).value.equals(varTable.name)){
flag=true;
break;
}
}
}
FuncTable funcTable=ProcTable.get(ProcTable.size()-1);
if(funcTable.VariableTable.size()>0&&(!flag)){
for(VarTable varTable : funcTable.VariableTable){
if(((ASTIdentifier) astExpression).value.equals(varTable.name)){
flag=true;
break;
}
}
}
if(GlobalVarTable.size()>0&&(!flag)){
for(VarTable varTable:GlobalVarTable){
if(((ASTIdentifier) astExpression).value.equals(varTable.name)){
flag=true;
break;
}
}
}
if(!flag){
String ERROR="ES01: "+((ASTIdentifier) astExpression).value+"_is_not_defined\n";
ErrorTable.add(ERROR);
}
opnd1=astExpression;
map.put(astArrayAccess.arrayName,astExpression);
}
else{
visit(astExpression);
opnd1=map.get(astExpression);
}
res = new TemporaryValue(++tmpRegID);
VarTable varTable = new VarTable();
varTable.name=((TemporaryValue) res).name();
varTable.type="VariableDeclarator";
Scope.add(varTable);
map.put(astArrayAccess,res);
Quat quat = new Quat("[]",res,opnd1,opnd2);
quats.add(quat);
}
/**
* Statement
* @JsonSubTypes.Type(value = ASTBreakStatement.class,name = "BreakStatement"),
* @JsonSubTypes.Type(value = ASTCompoundStatement.class,name = "CompoundStatement"),
* @JsonSubTypes.Type(value = ASTContinueStatement.class,name="ContinueStatement"),
* @JsonSubTypes.Type(value = ASTExpressionStatement.class,name = "ExpressionStatement"),
* @JsonSubTypes.Type(value = ASTGotoStatement.class,name = "GotoStatement"),
* @JsonSubTypes.Type(value = ASTIterationDeclaredStatement.class,name = "IterationDeclaredStatement"),
* @JsonSubTypes.Type(value = ASTIterationStatement.class,name = "IterationStatement"),
* @JsonSubTypes.Type(value = ASTLabeledStatement.class,name = "LabeledStatement"),
* @JsonSubTypes.Type(value = ASTReturnStatement.class,name = "ReturnStatement"),
* @JsonSubTypes.Type(value = ASTSelectionStatement.class,name = "SelectionStatement")
*/
public static void visit(ASTStatement statement) {
if(statement instanceof ASTIterationDeclaredStatement) {
visit((ASTIterationDeclaredStatement)statement);
}else if(statement instanceof ASTIterationStatement) {
visit((ASTIterationStatement)statement);
}else if(statement instanceof ASTCompoundStatement) {
visit((ASTCompoundStatement)statement);
}else if(statement instanceof ASTSelectionStatement) {
visit((ASTSelectionStatement)statement);
}else if(statement instanceof ASTExpressionStatement) {
visit((ASTExpressionStatement)statement);
}else if(statement instanceof ASTBreakStatement) {
visit((ASTBreakStatement)statement);
}else if(statement instanceof ASTContinueStatement) {
visit((ASTContinueStatement)statement);
}else if(statement instanceof ASTReturnStatement) {
visit((ASTReturnStatement)statement);
}else if(statement instanceof ASTGotoStatement) {
visit((ASTGotoStatement)statement);
}else if(statement instanceof ASTLabeledStatement) {
visit((ASTLabeledStatement)statement);
}
}
public static void visit(ASTSelectionStatement astSelectionStatement){
IfLabelID++;
ASTNode StartCheckIfLabel=new LabelGenerator(IfLabelID,"If",0);
quats.add(new Quat("Label",StartCheckIfLabel,null,null));
for(ASTExpression astExpression:astSelectionStatement.cond){
visit(astExpression);
}
ASTNode res = map.get(astSelectionStatement.cond.get(0));
ASTNode OtherwiseLabel=new LabelGenerator(IfLabelID,"Else",0);
ASTNode EndifLabel=new LabelGenerator(IfLabelID,"Endif",0);
if(astSelectionStatement.otherwise!=null)
{
quats.add(new Quat("JF",OtherwiseLabel,res,null));
}
else{
quats.add(new Quat("JF",EndifLabel,null,null));
}
visit(astSelectionStatement.then);
//ASTNode EndifLabel=new LabelGenerator(IfLabelID,"Endif",0);
if(astSelectionStatement.otherwise!=null){
quats.add(new Quat("JMP",EndifLabel,null,null));
quats.add(new Quat("Label",OtherwiseLabel,null,null));
visit(astSelectionStatement.otherwise);
}
quats.add(new Quat("Label",EndifLabel,null,null));
}
public static void visit(ASTCompoundStatement astCompoundStatement){
boolean flag=false;
if(astCompoundStatement.parent.getClass()==ASTFunctionDefine.class){
flag=true;
}
Var.push(new LinkedList<>());
for(ASTNode blockItem : astCompoundStatement.blockItems){
if(blockItem instanceof ASTDeclaration){
Scope=Var.peek();
visit((ASTDeclaration) blockItem);
}
else if(blockItem instanceof ASTStatement){
visit((ASTStatement) blockItem);
}
}
if(flag){
FuncTable funcTable=ProcTable.get(ProcTable.size()-1);
Scope=Var.peek();
if(Scope.size()!=0){
for(int i = 0;i
MyICPrinter.java
package bit.minisys.minicc.icgen;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;
import bit.minisys.minicc.parser.ast.ASTIdentifier;
import bit.minisys.minicc.parser.ast.ASTIntegerConstant;
import bit.minisys.minicc.parser.ast.ASTNode;
import bit.minisys.minicc.parser.ast.ASTStringConstant;
public class MyICPrinter {
private List quats;
public MyICPrinter(List quats) {
this.quats = quats;
}
public void print(String filename) {
StringBuilder sb = new StringBuilder();
for (Quat quat : quats) {
String op = quat.getOp();
String res = astStr(quat.getRes());
String opnd1 = astStr(quat.getOpnd1());
String opnd2 = astStr(quat.getOpnd2());
sb.append("("+op+","+ opnd1+","+opnd2 +"," + res+")\n");
}
// write
try {
FileWriter fileWriter = new FileWriter(new File(filename));
fileWriter.write(sb.toString());
fileWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private String astStr(ASTNode node) {
if (node == null) {
return "";
}else if (node instanceof ASTIdentifier) {
return ((ASTIdentifier)node).value;
}else if (node instanceof ASTIntegerConstant) {
return ((ASTIntegerConstant)node).value+"";
}else if (node instanceof TemporaryValue) {
return ((TemporaryValue)node).name();
}
else if(node instanceof ASTStringConstant){
return ((ASTStringConstant) node).value;
}
else if(node instanceof LabelGenerator){
return ((LabelGenerator) node).name();
}
else {
return "";
}
}
}
SymbolPrinter.java
package bit.minisys.minicc.icgen;
import bit.minisys.minicc.parser.ast.ASTIdentifier;
import bit.minisys.minicc.parser.ast.ASTIntegerConstant;
import bit.minisys.minicc.parser.ast.ASTNode;
import bit.minisys.minicc.parser.ast.ASTStringConstant;
import bit.minisys.minicc.pp.internal.G;
import bit.minisys.minicc.semantic.FuncTable;
import bit.minisys.minicc.semantic.VarTable;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
public class SymbolPrinter {
private List ProcTable;
private List GlobalVarTable;
private List Scope;
public SymbolPrinter() {
ProcTable = new LinkedList<>();
GlobalVarTable = new LinkedList<>();
Scope=new LinkedList<>();
}
public void SetProcTable(List procTable){
this.ProcTable=procTable;
}
public void SetGlobalVarTable(List GlobalVarTable){
this.GlobalVarTable= GlobalVarTable;
}
public void SetScope(List Scope){
this.GlobalVarTable= Scope;
}
public void PrintProcTable(String filename){
StringBuilder sb = new StringBuilder();
sb.append("ProcTable\n");
for(FuncTable funcTable:this.ProcTable){
sb.append("FuncTable\n");
sb.append(funcTable.specifiers+" | "+funcTable.funcName+" | "+funcTable.type+"\n");
if(funcTable.VariableTable.size()!=0){
sb.append(funcTable.funcName+"'s"+" VariableTable\n");
for(VarTable varTable:funcTable.VariableTable){
sb.append(varTable.specifiers+" | "+varTable.name+" | "+varTable.type+"\n");
}
}
}
if(GlobalVarTable.size()!=0){
sb.append("GlobalVarTable\n");
for(VarTable varTable:GlobalVarTable){
sb.append(varTable.specifiers+" | "+varTable.name+" | "+varTable.type+"\n");
}
}
try {
FileWriter fileWriter = new FileWriter(new File(filename));
fileWriter.write(sb.toString());
fileWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
3.修改BIT-MiniCC-master\src\bit\minisys\minicc\MyMiniCompiler.java
package bit.minisys.minicc;
import MyCGrammer.MyCGrammerLexer;
import MyCGrammer.MyCGrammerParser;
import bit.minisys.minicc.icgen.MyICBuilder;
import bit.minisys.minicc.parser.MyListener;
import bit.minisys.minicc.parser.ast.ASTNode;
import bit.minisys.minicc.scanner.MyScanner;
import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.ParseTreeWalker;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
public class MyMiniCompiler {
public static void main(String[] args)throws IOException {
String inputFile = "输入文件路径";
InputStream is = System.in;
is = new FileInputStream(inputFile);
ANTLRInputStream input = new ANTLRInputStream(is);
MyCGrammerLexer lexer = new MyCGrammerLexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);
MyCGrammerParser parser = new MyCGrammerParser(tokens);
ParseTree tree = parser.compilationUnit();
String fName = inputFile.trim();
String temp[] = fName.split("\\\\");
String tokenFileName =temp[temp.length - 1] + ".tokens";
MyScanner myScanner = new MyScanner(tokenFileName,tokens);
String jsonFileName = temp[temp.length - 1] + ".json";
ParseTreeWalker walker = new ParseTreeWalker();
MyListener listener = new MyListener();
listener.oFile=jsonFileName;
walker.walk(listener, tree);
String icfileName = temp[temp.length - 1] + ".ic";
String errorfileName = temp[temp.length - 1] + ".error";
String symbolName = temp[temp.length - 1] + ".symbol";
MyICBuilder icBuilder = new MyICBuilder();
icBuilder.Errorfilename=errorfileName;
icBuilder.Icfilename=icfileName;
icBuilder.Symbolname=symbolName;
ASTNode node = listener.NodeStack.peek();
icBuilder.test(node);
}
}
4.结果展示
1_Fibonacci.c.ic
(param,num,,0)
(func,,,fibonacci)
(Label,,,@1If)
(<,num,1,@1)
(JF,@1,,@1Else)
(=,0,,res)
(JMP,,,@1Endif)
(Label,,,@1Else)
(Label,,,@2If)
(<=,num,2,@2)
(JF,@2,,@2Else)
(=,1,,res)
(JMP,,,@2Endif)
(Label,,,@2Else)
(-,num,1,@3)
(param,@3,,0)
(call,,,fibonacci)
(return,,,@4)
(-,num,2,@5)
(param,@5,,0)
(call,,,fibonacci)
(return,,,@6)
(+,@4,@6,res)
(Label,,,@2Endif)
(Label,,,@1Endif)
(RET,,,res)
(func,,,main)
(param,"Please input a number:\n",,0)
(call,,,Mars_PrintStr)
(call,,,Mars_GetInt)
(return,,,@7)
(=,@7,,n)
(param,n,,0)
(call,,,fibonacci)
(return,,,@8)
(=,@8,,res)
(param,"This number's fibonacci value is :\n",,0)
(call,,,Mars_PrintStr)
(param,res,,0)
(call,,,Mars_PrintInt)
(RET,,,0)
1_Fibonacci.c.error
ES01: Mars_PrintStr_is_not_defined
ES01: Mars_GetInt_is_not_defined
ES01: Mars_PrintStr_is_not_defined
ES01: Mars_PrintInt_is_not_defined
//这几个函数是Mars中自带的函数,所以会被程序识别为未定义,但影响不大
1_Fibonacci.c.symbol
ProcTable
FuncTable
int | fibonacci | FunctionDefine
fibonacci's VariableTable
int | num | ParamsDeclarator
int | res | VariableDeclarator
null | @1 | VariableDeclarator
null | @2 | VariableDeclarator
null | @3 | VariableDeclarator
null | @4 | VariableDeclarator
null | @5 | VariableDeclarator
null | @6 | VariableDeclarator
FuncTable
int | main | FunctionDefine
main's VariableTable
null | @7 | VariableDeclarator
int | n | VariableDeclarator
null | @8 | VariableDeclarator
int | res | VariableDeclarator