📄 grammer.y
字号:
}
;
T :T '*' F {int temp=0;
$$.sym_off=sym_off++;
if((symtab[$1.sym_off].type==INT)&&(symtab[$3.sym_off].type==INT))
{
symtab[$$.sym_off].type=INT;
symtab[$$.sym_off].place = mem_off++;
emitCode(op_mult,symtab[$1.sym_off].place,symtab[$3.sym_off].place,symtab[$$.sym_off].place);
}
else if((symtab[$1.sym_off].type==INT)&&(symtab[$3.sym_off].type==REAL))
{
symtab[$$.sym_off].type=REAL;
symtab[$$.sym_off].place = mem_off++;
//symtab[$1.sym_off].type=REAL; /*如果存储是常量或变量被以后用到,为避免再次转换,所以要设置类型,否则生成代码产生错误结果*/
temp=mem_off;
emitCode(op_mov,symtab[$1.sym_off].place,-1,temp);
emitCode(op_inttoreal,temp,-1,temp);
emitCode(op_fmult,temp,symtab[$3.sym_off].place,symtab[$$.sym_off].place);
}
else if((symtab[$1.sym_off].type==REAL)&&(symtab[$3.sym_off].type==INT))
{
symtab[$$.sym_off].type=REAL;
symtab[$$.sym_off].place = mem_off++;
//symtab[$1.sym_off].type=REAL; /*如果存储是常量或变量被以后用到,为避免再次转换,所以要设置类型,否则生成代码产生错误结果*/
temp=mem_off;
emitCode(op_mov,symtab[$1.sym_off].place,-1,temp);
emitCode(op_inttoreal,temp,-1,temp);
emitCode(op_fmult,temp,symtab[$3.sym_off].place,symtab[$$.sym_off].place);
}
else if((symtab[$1.sym_off].type==REAL)&&(symtab[$3.sym_off].type==REAL))
{
symtab[$$.sym_off].type=REAL;
symtab[$$.sym_off].place = mem_off++;
emitCode(op_fmult,symtab[$1.sym_off].place,symtab[$3.sym_off].place,symtab[$$.sym_off].place);
}
else
{
type_error();
}
}
|T '/' F {int temp=0;
$$.sym_off=sym_off++;
if((symtab[$1.sym_off].type==INT)&&(symtab[$3.sym_off].type==INT))
{
symtab[$$.sym_off].type=INT;
symtab[$$.sym_off].place = mem_off++;
emitCode(op_div,symtab[$1.sym_off].place,symtab[$3.sym_off].place,symtab[$$.sym_off].place);
}
else if((symtab[$1.sym_off].type==INT)&&(symtab[$3.sym_off].type==REAL))
{
symtab[$$.sym_off].type=REAL;
symtab[$$.sym_off].place = mem_off++;
//symtab[$1.sym_off].type=REAL; /*如果存储是常量或变量被以后用到,为避免再次转换,所以要设置类型,否则生成代码产生错误结果*/
temp=mem_off;
emitCode(op_mov,symtab[$1.sym_off].place,-1,temp);
emitCode(op_inttoreal,temp,-1,temp);
emitCode(op_fdiv,temp,symtab[$3.sym_off].place,symtab[$$.sym_off].place);
}
else if((symtab[$1.sym_off].type==REAL)&&(symtab[$3.sym_off].type==INT))
{
symtab[$$.sym_off].type=REAL;
symtab[$$.sym_off].place = mem_off++;
//symtab[$1.sym_off].type=REAL; /*如果存储是常量或变量被以后用到,为避免再次转换,所以要设置类型,否则生成代码产生错误结果*/
temp=mem_off;
emitCode(op_mov,symtab[$1.sym_off].place,-1,temp);
emitCode(op_inttoreal,temp,-1,temp);
emitCode(op_fdiv,temp,symtab[$3.sym_off].place,symtab[$$.sym_off].place);
}
else if((symtab[$1.sym_off].type==REAL)&&(symtab[$3.sym_off].type==REAL))
{
symtab[$$.sym_off].type=REAL;
symtab[$$.sym_off].place = mem_off++;
emitCode(op_fdiv,symtab[$1.sym_off].place,symtab[$3.sym_off].place,symtab[$$.sym_off].place);
}
else
{
type_error();
}
}
|F {
$$.sym_off=$1.sym_off;
}
;
F :'(' E ')' {$$.sym_off=$1.sym_off;}
|integerConst {$$.sym_off=sym_off++;
symtab[$$.sym_off].type=INT;
symtab[$$.sym_off].place=mem_off++;
emitCode(op_cmov,$1.ival,-1,symtab[$$.sym_off].place);
}
|realConst {$$.sym_off=sym_off++;
symtab[$$.sym_off].type=REAL;
symtab[$$.sym_off].place=mem_off++;
emitFCode(op_fcmov,$1.dval,-1,symtab[$$.sym_off].place);
}
|identifier {int p=lookup($1.idname);
if(p==-1){printf("ERROR:line %d variable %s is undefined.",yylineno,name+$1.idname);exit(1);}
$$.sym_off=p;
}
;
BE :AndBE {$$.sym_off=$1.sym_off;}
|AndBE OR M1 BE {$$.sym_off=sym_off++;
if((symtab[$1.sym_off].type==BOOL)&&(symtab[$3.sym_off].type==BOOL))
{
backpatch(symtab[$1.sym_off].falselist,symtab[$3.sym_off].place);
symtab[$$.sym_off].truelist=merge(symtab[$1.sym_off].truelist,symtab[$4.sym_off].truelist);
symtab[$$.sym_off].falselist=symtab[$4.sym_off].falselist;
//symtab[$$.sym_off].place=mem_off++;
//emitCode(op_or,symtab[$1.sym_off],place,symtab[$3.sym_off].place,symtab[$$.symtab].place);
}
else
{
type_error();
}
}
|AndBE XOR M1 BE {$$.sym_off=sym_off++;
if((symtab[$1.sym_off].type==BOOL)&&(symtab[$4.sym_off].type==BOOL))
{
backpatch(symtab[$1.sym_off].truelist,symtab[$3.sym_off].place);
backpatch(symtab[$1.sym_off].falselist,symtab[$3.sym_off].place);
backpatch(symtab[$4.sym_off].truelist,code_off);
backpatch(symtab[$4.sym_off].falselist,code_off);
symtab[$$.sym_off].place=mem_off++;
emitCode(op_xor,symtab[$1.sym_off].place,symtab[$3.sym_off].place,symtab[$$.sym_off].place);
symtab[$$.sym_off].truelist=symtab[$$.sym_off].falselist=NULL; /*不需要回填*/
}
else
{
type_error();
}
}
;
AndBE :NotBE {$$.sym_off=$1.sym_off;}
|NotBE AND M1 AndBE {$$.sym_off=sym_off++;
if((symtab[$1.sym_off].type==BOOL)&&(symtab[$4.sym_off].type==BOOL))
{
backpatch(symtab[$1.sym_off].truelist,symtab[$2.sym_off].place);
symtab[$$.sym_off].truelist=symtab[$3.sym_off].truelist;
symtab[$$.sym_off].falselist=merge(symtab[$1.sym_off].falselist,symtab[$4.sym_off].falselist);
symtab[$$.sym_off].place=mem_off++;
emitCode(op_and,symtab[$1.sym_off].place,symtab[$3.sym_off].place,symtab[$$.sym_off].place);
}
else
{
type_error();
}
}
;
NotBE :RelBE {$$.sym_off=$1.sym_off;}
|NOT '(' BE ')' {$$.sym_off=sym_off++;
if(symtab[$3.sym_off].type==BOOL)
{
symtab[$$.sym_off].place=mem_off++;
symtab[$$.sym_off].truelist=symtab[$3.sym_off].falselist;
symtab[$$.sym_off].falselist=symtab[$3.sym_off].truelist;
//emitCode(op_neg,symtab[$3.sym_off].place,-1,symtab[$$.sym_off],place);
}
}
RelBE :E RelOP E {$$.sym_off=sym_off++;
symtab[$$.sym_off].place=mem_off++;
symtab[$$.sym_off].type=BOOL;
symtab[$$.sym_off].truelist=makelist(code_off+2);
symtab[$$.sym_off].falselist=makelist(code_off+1);
switch($2.relop)
{
case RA:operator=op_a;break;
case RAE:operator=op_ae;break;
case RE:operator=op_e;break;
case RB:operator=op_b;break;
case RBE:operator=op_be;break;
}/*经过试验,关系操作操作数可以是不同类型,不用转换*/
emitCode(operator,symtab[$1.sym_off].place,symtab[$3.sym_off].place,symtab[$$.sym_off].place);
emitCode(op_zjmp,symtab[$$.sym_off].place,-1,-1);/*不成立时为0跳转*/
emitCode(op_jmp,-1,-1,-1);
}
;
%%
int lookup(int nameoff) /*查找标识符表*/
{
int i,rel;
for(i=0;i<sym_off;i++)
{
if(symtab[i].class==identifier)
{
rel=strcmp(name+symtab[i].idname,name+nameoff);
if(rel==0){return i;}
}
}
return -1;
}
void enterID(int offset,int nameoff,int type)
{
symtab[offset].idname=nameoff;
symtab[offset].type=type;
symtab[offset].class=identifier;
}
void addType(int sym_off,int type)
{
//symtab[sym_off].type = type;
symtab[sym_off].place = mem_off++;
//attrib[i].place = offset;
//return TRUE;
}
void emitCode( enum code_ops operation, int src1 ,int src2 , int dest )
{
code[code_off].op = operation;
code[code_off].src1.isrc1 = src1;
code[code_off].src2 = src2;
code[code_off].dest = dest;
code_off++;
}
void emitFCode( enum code_ops operation, double src1 ,int src2 , int dest )
{
code[code_off].op = operation;
code[code_off].src1.fsrc1 = src1;
code[code_off].src2 = src2;
code[code_off].dest = dest;
code_off++;
}
void backpatch( struct Jmplist * list, int jmp_dest) /*把指令序号i所相应的指令地址回填到由指针p指向的转移指令中*/
{
struct Jmplist * temp=list; /*回填后释放内存,*/
while(list!=NULL)
{
code[list->index].dest = jmp_dest;
list=list->next;
free(temp); /*释放内存*/
temp=list;
}
}
struct Jmplist * merge(struct Jmplist * list1,struct Jmplist * list2)
{
list1->next = list2;
return list1;
}
struct Jmplist * makelist(int i) /*建立仅含有指令诒i的新转移指令表,回头该表的指针*/
{
struct Jmplist * list = (struct Jmplist *)malloc(sizeof(struct Jmplist));
list->index = i;
list->next = NULL;
return list;
}
void yyerror(char * s)
{
fflush(stdout);
printf("ERROR:line %d",yylineno);
}
void type_error()
{
printf("ERROR: line %d type error",yylineno);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -