📄 totac.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 + -