⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 totac.y

📁 一个用C++实现的C的Compiler。 代码风格良好。 原作者自己写了这个编译器
💻 Y
字号:
%{

#include <string>
#include <cstdlib>
#include <cstdio>
#include <iostream>
#include <memory>

#include "common.cpp"
#include "TACsupport.cpp"
#include "symtable.cpp"
#include "TACPrintSupport.cpp"

#define TACFile "IR.tac"
#define TACFile_FOREXE "IRE.tac"
#define STFile "IR.st"

using namespace std;

struct __yystype {
	int intval;
	double dblval;
	string str;
	TExpr expr;
	TInstructionList ins;
	list <int> int_list;
	TSymbolListVariableEntry Ventry;
	TSymbolListTypeEntry Tentry;
	list <TExpr> expr_list;
	list <TSymbolListVariableEntry> Ventry_list;
};

#define YYSTYPE __yystype

int yyerror(string msg)
{
	cout << "Error encountered: " << msg << endl;
	return 0;
}

int yylex();


const			int				NoBelongingStruct			=			-1;

int BelongingStruct = NoBelongingStruct;
int InFuncLevel = -1;

int PROGRAM_RANGECHECK = 0;
int PROGRAM_POINTERCHECK = 0;
int PROGRAM_FOREXE = 0;

%}

%token NIL
%token <intval> IDENT TRUE FALSE INT SYMNULL CHAR
%token <dblval> DOUBLE
%token <str> STRING
%token IF ELSE FOR WHILE BREAK RETURN
%token PRINT READINT READDBL READLINE NEW
%token LPAREN RPAREN LBRACKET RBRACKET LSQUARE RSQUARE DOT COMMA SEMICOLON
%token TYPEINT TYPEDOUBLE TYPEBOOL TYPESTRING TYPEVOID TYPECHAR CLASS EXTENDS THIS
%token STRUCT CONST
%token READREG WRITEREG ASM

%right LET
%left LOGICOR
%left LOGICAND
%left LES GTR LEQ GEQ EQL NEQ
%left OR
%left AND XOR SHL SHR
%left CALCNOT
%left ADD MINUS
%left MUL DIV MOD
%left STAR REF FORCE
%left UMINUS NOT 

%left DOT LSQUARE RSQUARE
%left PPLUS MMINUS
%left LPAREN RPAREN

%type <intval> basictype 
%type <expr> expr arraysub call
%type <Ventry_list> funcvars formals types
%type <Ventry> funcvar
%type <ins> stmtblock stmts stmtstar stmt simplestmt 
%type <ins> ifstmt forstmt whilestmt breakstmt returnstmt
%type <ins> asm asms asmstar
%type <Tentry> fields fieldblock
%type <int_list> varlist ints intblock
%type <expr_list> exprs actuals

%nonassoc IFX
%nonassoc ELSE

%start program

%%

program		:	decls											{	}
			;

decls		:	decls decl										{	}
			|	decl											{	}
			;

decl		:	vardecl											{	TACAddVariableDecls($1.intval, $1.int_list);		}
			|	funcdef											{	TACFunctionInsAddEXIT($1.ins);
																	TAC_Program_Instruction[$1.intval] = $1.ins;
																	SymbolListFunctionList.push_back($1.intval);
																	SymbolListFunction[$1.intval].end_line = PROGRAM_LineNumber;
																}
			|	funcdecl										{	}
			|	structdef										{	}
			;

varlist		:	IDENT											{	$$.clear();	$$.push_back($1);						}
			|	varlist COMMA IDENT								{	$$ = $1; $$.push_back($3);							}
			;

vardecl		:	var SEMICOLON									{	$$ = $1;											}
			|	var COMMA varlist SEMICOLON						{	$$.intval = $1.intval;
																	$$.int_list = $3;
																	$$.int_list.push_front(*$1.int_list.begin());		}
			|	CONST type IDENT LET expr SEMICOLON				{	TACAddConstVariable(SymbolListTypeADDArrayList($2.intval, $2.int_list), $3, $5.res_oprd.data.cint);
																														}
			;

arraysub	:	LSQUARE expr RSQUARE							{	$$ = $2;											}
			;

var			:	type IDENT										{	$$.intval = SymbolListTypeADDArrayList($1.intval, $1.int_list);
																	$$.int_list.clear(); $$.int_list.push_back($2);		}
			;

types		:	type											{	$$.clear(); 
																	TSymbolListVariableEntry Ventry;
																	Ventry.var_type = SymbolListTypeADDArrayList($1.intval, $1.int_list);
																	$$.push_back(Ventry);								}
			|	types COMMA type								{	$$ = $1;
																	TSymbolListVariableEntry Ventry;
																	Ventry.var_type = SymbolListTypeADDArrayList($3.intval, $3.int_list);
																	$$.push_back(Ventry);								}
			;

type		:	basictype										{	$$.intval = $1; $$.int_list.clear();				}
			|	type MUL										{	$$.intval = SymbolListTypeADDArrayList($1.intval, $1.int_list);	
																	$$.intval = SymbolListTypeADDStar($$.intval);
																	$$.int_list.clear();								}
			|	type arraysub									{	$$.intval = $1.intval; $$.int_list = $1.int_list;
																	$$.int_list.push_back($2.res_oprd.data.cint);			}
			|	type LPAREN RPAREN LPAREN types RPAREN			{	$$.intval = SymbolListMakeFunctionType(SymbolListTypeADDArrayList($1.intval, $1.int_list),
																						$5);
																	$$.int_list.clear();								}
			;

basictype	:	TYPEINT											{	$$ = var_type_int;									}
			|	TYPECHAR										{	$$ = var_type_char;									}
			|	TYPEVOID										{	$$ = var_type_void									}
			|	STRUCT IDENT									{	$$ = $2;											}
			;

funcdecl	:	type IDENT LPAREN formals RPAREN SEMICOLON		{	TACAddFunctionDecl(SymbolListTypeADDArrayList($1.intval, $1.int_list), 
																							$2, $4);					}
			;

formals		:	funcvars										{	$$ = $1;											}
			|	/* epsilon */									{	$$.clear();											}
			;

funcvars	:	funcvar											{	$$.clear(); $$.push_back($1);						}
			|	funcvars COMMA funcvar							{	$$ = $1; $$.push_back($3);							}
			;

funcvar		:	var												{	$$.var_type = $1.intval;
																	$$.id = *$1.int_list.begin();						}
			;

funcdef		:	type IDENT LPAREN formals RPAREN				{	TACAddFunctionDecl(SymbolListTypeADDArrayList($1.intval, $1.int_list), $2, $4);
																	SymbolListNowLevel ++;
																	SymbolListScopeStack[SymbolListScopeStackTOP ++] = SymbolListScopeCNT ++;
																	SymbolListScope[SymbolListScopeStack[SymbolListScopeStackTOP - 1]].father
																		= SymbolListScopeStack[SymbolListScopeStackTOP - 2];																

																	for (list <TSymbolListVariableEntry> :: iterator p = $4.begin(); p != $4.end(); p++)
																	{
																		p->level = SymbolListNowLevel;
																		p->var_name_TAC = TACAllocateVar(p->var_type);
																		SymbolListAddVariableEntry(p->id, *p);
																	}
																	SymbolListFunction[$2].arg_list = $4;
																	SymbolListNowLevel --;
																	SymbolListScopeCNT --;
																	SymbolListScopeStackTOP --;							}
					stmtblock									{	$$.intval = $2; $$.ins = $7;						}
			;

structdef	:	STRUCT IDENT fieldblock SEMICOLON				{	SymbolListAddTypeEntry($2, $3);						}
			;

fieldblock	:	LBRACKET fields RBRACKET						{	$$ = $2;											}
			|	LBRACKET RBRACKET								{	SymbolListMakeNewStruct($$);						}
			;

fields		:	vardecl											{	SymbolListMakeNewStruct($$);
																	TACAddVarDeclsToStruct($$, $1.intval, $1.int_list);	}
			|	fields vardecl									{	$$ = $1;
																	TACAddVarDeclsToStruct($$, $2.intval, $2.int_list);	}
			;


stmtblock	:	LBRACKET 										{	SymbolListIncLevel();
																	SymbolListScopeStack[SymbolListScopeStackTOP ++] = SymbolListScopeCNT ++;
																	SymbolListScope[SymbolListScopeStack[SymbolListScopeStackTOP - 1]].father
																		= SymbolListScopeStack[SymbolListScopeStackTOP - 2];				}
					stmtstar RBRACKET							{	$$ = $3;
																	SymbolListDecLevel();
																	SymbolListScopeStackTOP --;												}
			;

stmtstar	:	stmts											{	$$ = $1;											}
			|	/* epsilon */									{	$$.clear(); $$.BreakChain.clear();					}
			;

stmts		:	stmts stmt										{	TACInstructionListJoin($1, $2, $$);					}
			|	stmt											{	$$ = $1;											}
			;

asmstar		:	asms											{	$$ = $1;											}
			|	/* epsilon */									{	$$.clear(); $$.BreakChain.clear();					}
			;

asms		:	asms asm										{	TACInstructionListJoin($1, $2, $$);					}
			|	asm												{	$$ = $1;											}
			;

asm			:	READREG LPAREN STRING COMMA IDENT RPAREN SEMICOLON
																{	TACRegOperation(REG_OP_READ, $3, $5, $$);			}
			|	WRITEREG LPAREN STRING COMMA IDENT RPAREN SEMICOLON	
																{	TACRegOperation(REG_OP_WRITE, $3, $5, $$);			}
			|	ASM LPAREN INT RPAREN SEMICOLON					{	TACBinaryASM($3, $$);								}
			|	ASM LPAREN STRING RPAREN SEMICOLON				{	TACASM($$, 0, $3);									}
			|	ASM LPAREN STRING COMMA STRING RPAREN SEMICOLON	{	TACASM($$, 1, $3, $5);								}
			|	ASM LPAREN STRING COMMA STRING COMMA STRING RPAREN SEMICOLON
																{	TACASM($$, 2, $3, $5, $7);							}
			|	ASM LPAREN STRING COMMA STRING COMMA STRING COMMA STRING RPAREN SEMICOLON
																{	TACASM($$, 3, $3, $5, $7, $9);						}
			;


stmt		:	stmtblock										{	$$ = $1;											}
			|	vardecl											{	TACAddVariableDecls($1.intval, $1.int_list);		}
			|	simplestmt SEMICOLON							{	$$ = $1;											}
			|	ifstmt											{	$$ = $1;											}
			|	whilestmt										{	$$ = $1;											}
			|	forstmt											{	$$ = $1;											}
			|	breakstmt SEMICOLON								{	$$ = $1;											}
			|	returnstmt SEMICOLON							{	$$ = $1;											}
			|	ASM LBRACKET asmstar RBRACKET SEMICOLON			{	$$ = $3;											}
			;

simplestmt	:	expr											{	$$ = $1.ins;										}
			|	/* epsilon */									{	$$.clear();											}
			;

call		:	expr LPAREN actuals RPAREN						{	TACMakeICall($1, $3, $$);							}
			;

actuals		:	exprs											{	$$ = $1;											}
			|	/* epsilon */									{	$$.clear();											}
			;

forstmt		:	FOR LPAREN simplestmt SEMICOLON expr 
					SEMICOLON simplestmt RPAREN stmt			{	TACMakeFOR($3, $5, $7, $9, $$);						}
			;

whilestmt	:	WHILE LPAREN expr RPAREN stmt					{	TACMakeWHILE($3, $5, $$);							}
			;

ifstmt		:	IF LPAREN expr RPAREN stmt %prec IFX			{	TACMakeSingleIF($3, $5, $$);						}
			|	IF LPAREN expr RPAREN stmt ELSE stmt			{	TACMakeIFELSE($3, $5, $7, $$);						}
			;

returnstmt	:	RETURN											{	TACMakeEXIT($$);									}
			|	RETURN expr										{	TACMakeRETURN($2, $$);								}
			;

breakstmt	:	BREAK											{	TACMakeBreak($$);									}
			;

exprs		:	expr											{	$$.clear(); $$.push_back($1);						}
			|	exprs COMMA expr								{	$$ = $1; $$.push_back($3);							}
			;

intblock	:	ints GTR										{	$$ = $1;											}
			|	LES GTR											{	$$.clear();											}
			;
	
ints		:	LES INT											{	$$.clear(); $$.push_back($2);						}
			|	ints COMMA INT									{	$$ = $1; $$.push_back($3);							}

expr		:	IDENT											{	TACIdentToExpr($1, $$);								}
			|	LPAREN type RPAREN expr %prec FORCE				{	$$ = $4; 
																	$$.var_type = SymbolListTypeADDArrayList($2.intval, $2.int_list);
																														}
			|	expr DOT IDENT									{	TACFindField($1, $3, $$);							}
			|	expr arraysub									{	TACFindArrayAddr($1, $2, $$);						}
			|	MUL expr %prec STAR								{	$$ = $2; __varADDptr($$);							}
			|	INT												{	TACMakeConstantIntExpr($$, $1, var_type_int);		}
			|	SYMNULL											{	TACMakeConstantIntExpr($$, 0, var_type_int);		}
			|	STRING											{	TACMakeConstString($1, $$);							}
			|	TRUE											{	TACMakeConstantIntExpr($$, 1, var_type_int);		}
			|	FALSE											{	TACMakeConstantIntExpr($$, 0, var_type_int);		}
			|	CHAR											{	TACMakeConstantIntExpr($$, $1, var_type_char);		}
			|	intblock										{	TACKMakeConstantIntblock($1, $$);					}
			|	call											{	$$ = $1;											}
			|	expr LET expr									{	TACMakeLET ($1, $3, $$);							}
			|	LPAREN expr RPAREN								{	$$ = $2;											}
			|	AND expr %prec REF								{	$$ = $2; __varADDref($$);							}
			|	expr LES expr									{	TACCondExprCombine($1, $3, TAC_SRC_relational_LES, $$);				}
			|	expr GTR expr									{	TACCondExprCombine($1, $3, TAC_SRC_relational_GTR, $$);				}
			|	expr LEQ expr									{	TACCondExprCombine($1, $3, TAC_SRC_relational_LEQ, $$);				}
			|	expr GEQ expr									{	TACCondExprCombine($1, $3, TAC_SRC_relational_GEQ, $$);				}
			|	expr EQL expr									{	TACCondExprCombine($1, $3, TAC_SRC_relational_EQL, $$);				}
			|	expr NEQ expr									{	TACCondExprCombine($1, $3, TAC_SRC_relational_NEQ, $$);				}
			|	expr LOGICAND expr								{	TACCondExprCombine($1, $3, TAC_SRC_logical_AND, $$);				}
			|	expr LOGICOR expr								{	TACCondExprCombine($1, $3, TAC_SRC_logical_OR, $$);					}
			|	NOT expr										{	TACCondExprUnary($2, TAC_SRC_logical_NOT, $$);						}
			|	CALCNOT expr									{	TACExprUnary($2, TAC_SRC_calculational_NOT, $$);					}
			|	expr ADD expr									{	TACExprCombine($1, $3, TAC_SRC_calculational_ADD, $$);				}
			|	expr MINUS expr									{	TACExprCombine($1, $3, TAC_SRC_calculational_MINUS, $$);			}
			|	expr MUL expr									{	TACExprCombine($1, $3, TAC_SRC_calculational_MUL, $$);				}
			|	expr DIV expr									{	TACExprCombine($1, $3, TAC_SRC_calculational_DIV, $$);				}
			|	expr MOD expr									{	TACExprCombine($1, $3, TAC_SRC_calculational_MOD, $$);				}
			|	expr AND expr									{	TACExprCombine($1, $3, TAC_SRC_calculational_AND, $$);				}
			|	expr OR expr									{	TACExprCombine($1, $3, TAC_SRC_calculational_OR, $$);				}
			|	expr XOR expr									{	TACExprCombine($1, $3, TAC_SRC_calculational_XOR, $$);				}
			|	expr SHL expr									{	TACExprCombine($1, $3, TAC_SRC_calculational_SHL, $$);				}
			|	expr SHR expr									{	TACExprCombine($1, $3, TAC_SRC_calculational_SHR, $$);				}
			|	MINUS expr %prec UMINUS							{	TACExprUnary($2, TAC_SRC_calculational_MINUS, $$);					}
			|	expr PPLUS										{	TACExprSelfAction($1, TAC_SRC_calculational_ADD, $$);				}
			|	expr MMINUS										{	TACExprSelfAction($1, TAC_SRC_calculational_MINUS, $$);				}
			;

%%

int main(int argc, char* argv[])
{
	int filecnt = -1;
	for (int i = 1; i < argc; i++)
	{
		if (filecnt == -1 && argv[i][0] != '-')
		{
			filecnt = i;
		}

		if (argv[i][0] == '-' && argv[i][1] == 'C')
		{
			for (int j = 2; argv[i][j]; j++)
			{
				if (argv[i][j] == 'r') PROGRAM_RANGECHECK = 1;
				if (argv[i][j] == 'p') PROGRAM_POINTERCHECK = 1;
			}
		}

		if (argv[i][0] == '-' && argv[i][1] == 'E' && argv[i][2] == 0)
		{
			PROGRAM_FOREXE = 1;
		}
	}

	if (filecnt == -1)
	{
		printf("toTAC: no input file\n");
		return 1;
	}

	yyin = fopen(argv[filecnt], "r");
	if (yyin == NULL)
	{
		printf("toTAC: %s: No such file\n", argv[filecnt]);
		return 1;
	}

	SymbolListScopeCNT = 1; SymbolListScopeStackTOP = 1;
	SymbolListScopeStack[SymbolListScopeStackTOP - 1] = SymbolListScopeCNT - 1;
	SymbolListScope[0].father = 0; 
	yyparse();
	if (!PROGRAM_FOREXE)
	{
		TACPrintOut(TACFile);
	}
	else
	{
		TACPrintOut(TACFile_FOREXE);
	}
	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -