此篇博客是将前面的内容进行整合并进一步提升,真正实现一个简单表达式语法的编译器
如果有不了解的地方请查看下面链接
词法分析
LR(1)分析(一)
LR(1)分析(二)
这里说的程序语言编译器是指将算术表达式部分进行翻译,暂时不包括优化以及目标语言生成部分,只产生四元式,后面部分根据博主的时间安排以及个人能力(担心有余而力不足算术表达式转换成四元式属于相对较为容易的任务,只需要在对表达式进行规范LR(1)分析当遇到归约时执行相应的语义动作即可实现对算术表达式的翻译,因此只需要对先前的规范LR(1)分析中的分析过程稍做改进即可实现,但这样的话难度有些太低了,心里总有些不舒服。因此我计划做一下几方面的调整:
- 将ACTION表与GOTO表存入mysql数据库中这样无需每次启动程序都需要进行预测分析表的获取节省时间,提高效率。
- 插入类型检查与类型转换部分
- 加入数组声明、赋值与计算部分(先挖坑如果计组考完有时间就完善)
- 最后形成一个交互界面
由于前面已经有了一定的基础,下面有些细节我就不再展开,请参考前面的博客。
程序语言特点分析以及翻译模式
这里的语言并不是现存的哪一种只是我构思出的一个程序语言,他的语法规则为:
S->i=E # 对应赋值
E->E+T # 对应加法
E->E-T # 对应减法
E->-T # 对应负数
E->T # 这里设计是因为加减的优先级低于乘除
T->T*F # 乘
T->T/F # 除
T->F # 这里是对应括号
F->(E) # 括号的部分
F->i
S->i:D # 说明
D->int(m) #int 类型
D->real(n) #real类型
这里给出上述语法规则的翻译模式
S->i=E {
p=lookup(i.name);
if(p!=NULL && ((i.type==int&&E.type ==int) || (i.type==real&&E.type ==real)))
emit(p'='E.place)
if(p!=NULL && (i.type==int&&E.type==real)
u=newTemp;
emit(u'=''inttoreal'p);
emit(u'='E.place);
if(p!=NULL && (i.type==real&&E.type==int)
u=newTemp;
emit(u'=''inttoreal'E.place);
emit(p'='u);
}
E->E1+T {
if (T.type == int and E1.type == int)
emit(E.place'='E1.place'int+'T.place)
E.type = int;
if (E.type = real and T.type = int)
u = newTemp;
emit(u'=''inttoreal'T.place);
emit(E.place'='u'real+'E1.place);
E.type = real;
if (T.type = real and E.type = int)
u = newTemp;
emit(u'=''inttoreal'E.place);
emit(u'='E1.place'real+'T.place);
E.type = real;
if(T.type = real and E.type = real)
emit(E.place'='E1.place+'real+'T.place);
E.type = real;}
E->E1-T {
if (T.type == int and E1.type == int)
emit(E.place'='E1.place'int-'T.place);
E.type = int;
if (E1.type = real and T.type = int)
u = newTemp;
emit(u'=''inttoreal'T.place;
emit(E.place'='u'real-'E1.place);
E.type = real;
if (T.type = real and E.type = int)
u = newTemp;
emit(u'=''inttoreal'E1.place);
emit(E'='u'real-'T.place);
E.type = real;
if(T.type = real and E.type = real)
emit(E.place'='E1.place+'real-'T.place);
E.type = real;}
E->-T {
E.place = newTemp; emit(E.place'=''uminus'T.place)
E.type = T.type;}
E->T {
E.place = T.place;E.type = T.type;}
E->T*F {
if (T.type == int and F.type == int)
emit(E.place'='T.place'int*'F.place);
E.type = int;
if (T.type = real and F.type = int)
u = newTemp;
emit(u'=''inttoreal'F.place;
emit(E.place'='u'real*'T.place);
E.type = real;
if (T.type = real and F.type = int)
u = newTemp;
emit(u'=''inttoreal'F.place);
emit(E'='u'real*'T.place);
E.type = real;
if(T.type = real and F.type = real)
emit(E.place'='F.place+'real*'T.place);
E.type = real;}
E->T/F {
if (T.type == int and F.type == int)
emit(E.place'='T.place'int/'F.place);
E.type = int;
if (T.type = real and F.type = int)
u = newTemp;
emit(u'=''inttoreal'F.place;
emit(E.place'='u'real/'T.place);
E.type = real;
if (T.type = real and F.type = int)
u = newTemp;
emit(u'=''inttoreal'F.place);
emit(E'='u'real/'T.place);
E.type = real;
if(T.type = real and F.type = real)
emit(E.place'='F.place+'real/T.place);
E.type = real;}
T->F {
T.place = F.place; T.type = F.type;}
F->(E) {
F.place = E.place;F.type = E.type;}
F->i