采用自底向上归约编译器

支持以下文法:

1.if;
2.while;
3.赋值;
4.定义;(idtable部分待完善)
5.布尔;
6.算术;
例子:
begin   if a<b || a + 1<b then begin a = 10 end   else if a>b then begin a = 20 end    else if a >= b thenbegin a = 50 end    else begin a = 32 end   end";

介绍部分

1.我把每个语法的自动机和归约-输出部分分成了不同的函数,解耦;
2.自动机负责检查语法,控制状态变化,每次执行从tpst指针开始遍历语法栈;
3.自动机遍历完后会把需要进行的归约操作传递给归约机;
4.自动机之间会产生互相调用(递归),如果代码中存在嵌套(例如:if套if)

词法部分

不谈

语法部分

之后会以图片的形式传上来

代码部分

有待完善,但传上来的自动机已经完美运行了,归约操作还有瑕疵

#pragma once
#include<stdio.h>
#include <ctype.h>
#include <math.h>#define KEYWORDNUM 12
#define KEYWORDLEN 16char keyword[KEYWORDNUM][KEYWORDLEN] =
{ { "if$" }, { "then$" }, { "else$" },
{ "while$" }, { "do$" }, { "begin$" },
{ "end$" }, { "int$" }, { "double$" } };
enum Symbols
{INT,//0ID,PLUS,SUB,MULT,DIV,L_PARENS,R_PARENS,GT,GE,LT,LE,EQUL,NEGA,//!取反AND,OR,ASSIGN,SEMICOLON,IF=100,//关键词部分THEN,ELSE,WHILE,DO,BEGIN,END,TYPE_INT,TYPE_DOUBLE,JTRUE,//跳转JFALSE,JUMP,EOS,//变元部分NTS_E,NTS_T,NTS_B,NTS_S,NTS_FA,NTS_FB,NTS_FC,NTS_CA,NTS_CBE,NTS_CB,NTS_CE,NTS_W,NTS_WD
};struct _id//标识符表
{char name[32];int isdef;int value;//代表标识符定义的值,或者四元式行号
};
struct _int
{char value[32];
};
struct _token
{int value;int loca;
};
struct _out//四元表
{enum Symbols opr;struct _token value1;struct _token value2;int result; //填对应ID表行号
};struct _id idtable[32] = { 0 };
struct _int inttable[32] = { 0 };
struct _token tokentable[128] = { 0 };
struct _out out4table[128] = { 0 };//int idtable[32][32] = { 0 };
int ctoken = 0;//tokentable尾部
int cid = 0;//idtable尾部
int cint = 0;//inttable尾部
int cout4 = 0;//四元式底部
//-----------------------------------------------------------------------------------
int iskeyword(char *pt)
{int i = 0;int j = 0;int isequ = 1;for (i = 0; i < KEYWORDNUM; i++){isequ = 1;j = -1;do{j++;if ((*(pt + j)) != keyword[i][j] )//有不同位,排除该词{isequ = 0;}else if ((*(pt + j)) == '$' && keyword[i][j] == '$')//成功找到{tokentable[ctoken].value = (i + 100);ctoken++;return j-2;//返回位数}} while ((*(pt + j)) != '$' && keyword[i][j] != '$' && isequ==1);//都未到词尾且暂时相等}return -1;
}
int isininttable(char *pt)
{int i = 0;int j = 0;int isfind = 0;for (i = 0; i < cint; i++){while (inttable[i].value[j] == *(pt + j) && isfind == 0 && inttable[i].value[j] != '$' && *(pt + j) != '$'){j++;if (inttable[i].value[j] == '$' && *(pt + j) == '$'){isfind = 1;}}if (isfind == 1){return i;}j = 0;}return -1;
}
int isinidtable(char *pt)
{int i = 0;int j = 0;int isfind = 0;for (i = 0; i < cid; i++)//查找是否存在{while (idtable[i].name[j] == *(pt + j) && isfind == 0 && idtable[i].name != '$' && *(pt + j) != '$')//继续循环条件,否则单词不相同{j++;if (idtable[i].name[j] == '$' && *(pt + j) == '$')//确定单词相同条件{isfind = 1;}}if (isfind == 1){return i;}j = 0;}return -1;
}int isRight(char * ch)//词法自动机
{char * pt = NULL;pt = ch;int isok = 0;int state = 1;while (isok == 0){switch (state){case 1:if (isdigit(*pt)){state = 2;pt++;}else if (isalpha(*pt)){state = 3;pt++;}else{return 0;}break;case 2:if (isdigit(*pt)){state = 2;pt++;}else if ((*pt) == '$'){state = 4;}else{return 0;}break;case 3:if (isalnum(*pt)){state = 3;pt++;}else if ((*pt) == '$'){state = 4;}else{return 0;}break;case 4:return 1;}}}
int lexer(char *c)
{int i = 1;//取词位数计算char token[32] = { 0 };char *pt = NULL;pt = &token;int j = 0;int a = -1 ;//表中位置,通过is函数返回,不存在返回-1if ((*c) == 32 || (*c) == 13 || (*c) == 10 || (*c) == 9){return i;}else if (isdigit(*c))//是一串数字{token[j] = *c;//遍历至单词结尾,填tokenj++;c++;while (isdigit(*c)){token[j] = *c;c++;j++;i++;}token[j] = '$';if (isRight(pt)!=1)//词法自动机判断正误{return 0;}tokentable[ctoken].value = INT;//填 token表 和 (id或int表)a = isininttable(pt);if (a==-1)//如果不在int表中{j = 0;inttable[cint].value[j] = (int)token[j];j++;while (token[j] != '$'){inttable[cint].value[j] = (int)token[j];j++;}inttable[cint].value[j] = '$';tokentable[ctoken].loca = cint;cint++; }else{tokentable[ctoken].loca = a;}ctoken++;}else if (isalpha(*c))//是定义的变量{int k = -1;token[j] = *c;//遍历至单词结尾,填tokenj++;c++;while (isalnum(*c)){token[j] = *c;c++;j++;i++;}token[j] = '$';if (isRight(pt) != 1)//词法自动机判断正误{return 0;}char *ptoken;ptoken = token;k = iskeyword(ptoken);if (k != -1){return i;}else{tokentable[ctoken].value = ID;//填 token表 和 (id或int表)a = isinidtable(pt);if (a == -1)//如果不在int表中{j = 0;idtable[cid].name[j] = (int)token[j];j++;while (token[j] != '$'){idtable[cid].name[j] = (int)token[j];j++;}idtable[cid].name[j] = '$';tokentable[ctoken].loca = cid;cid++;}else{tokentable[ctoken].loca = a;}ctoken++;}}else{switch (*c)//是其他符号{case'(':tokentable[ctoken].value = L_PARENS;break;case')':tokentable[ctoken].value = R_PARENS;break;case'+':tokentable[ctoken].value = PLUS;break;case'-':tokentable[ctoken].value = SUB;break;case'*':tokentable[ctoken].value = MULT;break;case'/':tokentable[ctoken].value = DIV;break;case'!':tokentable[ctoken].value = NEGA;break;case'<':if ((*(c+1)) == '='){c++;i++;tokentable[ctoken].value = LE;}else{tokentable[ctoken].value = LT;}break;case'>':if ((*(c + 1)) == '='){c++;i++;tokentable[ctoken].value = GE;}else{tokentable[ctoken].value = GT;}break;case'=':if ((*(c + 1)) == '='){c++;i++;tokentable[ctoken].value = EQUL;}else{tokentable[ctoken].value = ASSIGN;}break;case'&':if ((*(c + 1)) == '&'){c++;i++;tokentable[ctoken].value = AND;}else{printf("错误字符!");return 0;}break;case'|':if ((*(c + 1)) == '|'){c++;i++;tokentable[ctoken].value = OR;}else{printf("错误字符!");return 0;}break;case';':tokentable[ctoken].value = SEMICOLON;break;case'$':tokentable[ctoken].value = EOS;break;default:printf("错误字符!");return 0;}c++;ctoken++;}return i;
}
//-----------------------------------------------------------------------------------
int pstack = 0;//语法栈顶
int sstack = 0;//语义栈顶
enum Symbols popP(enum Symbols *stack)//语法栈
{pstack--;enum Symbols a = *(stack + pstack);return a;
}
enum Symbols pushP(enum Symbols *stack, enum Symbols i)
{*(stack + pstack) = i;pstack++;return 0;
}
struct _token* popS(struct _token *stack)//语义栈
{sstack--;struct _token *a = (stack + sstack);return a;
}
int pushS(struct _token *stack,int value,int loca)
{(*(stack + sstack)).value = value;(*(stack + sstack)).loca = loca;sstack++;return 0;
}
int outs(enum Symbols *stack)
{int * p = NULL;p = stack;int i = 0;while (p<(stack+pstack)){i = (*p);switch (i){case INT: printf("INT "); break;case ID: printf("ID "); break;case PLUS: printf("+"); break;case SUB: printf("-"); break;case MULT: printf("*"); break;case DIV: printf("/"); break;case L_PARENS: printf("("); break;case R_PARENS: printf(")"); break;case LT: printf("<"); break;case LE: printf("<="); break;case GT: printf(">"); break;case GE: printf(">="); break;case EQUL: printf("=="); break;case NEGA: printf("!"); break;case AND: printf("&&"); break;case OR: printf("||"); break;case ASSIGN: printf("="); break;case SEMICOLON: printf(";"); break;case IF: printf("IF "); break;case THEN: printf("THEN "); break;case ELSE: printf("ELSE "); break;case WHILE: printf("WHILE "); break;case DO: printf("DO "); break;case BEGIN: printf("BEGIN "); break;case END: printf("END "); break;case TYPE_INT: printf("TYPE_INT "); break;case TYPE_DOUBLE: printf("TYPE_DOUBLE "); break;case EOS: printf("$"); break;case NTS_E: printf("E "); break;case NTS_T: printf("T "); break;case NTS_B: printf("B "); break;case NTS_S: printf("S "); break;case NTS_FA: printf("FA "); break;case NTS_FB: printf("FB "); break;case NTS_FC: printf("FC "); break;case NTS_CA: printf("CA "); break;case NTS_CBE: printf("CBE "); break;case NTS_CB: printf("CB "); break;case NTS_CE: printf("CE "); break;case NTS_W: printf("W "); break;case NTS_WD: printf("WD "); break;default:printf("outerr");return 0;}p++;}//for (int i = 0; i < 16; i++)//{//    printf("%d", idtable[i][0]);//}printf("\n");return 0;
}
//-----------------------------------------------------------------------------------
int gen(enum Symbols opr, struct _token value1, struct _token value2, int result)//不输入result填-1
{out4table[cout4].opr = opr;out4table[cout4].value1 = value1;out4table[cout4].value2 = value2;if (result != -1){out4table[cout4].result = result;}else{idtable[cid].name[0] = '$';//该ID表项为4元式idtable[cid].value = cout4;//ID表值填入4元式位置out4table[cout4].result = cid;//在该4元式result中填入ID表位置cid++;}cout4++;return (cid - 1);//返回填入ID表的位置
}
//-----------------------------------------------------------------------------------
int tchain = 0;
int fchain = 0;//-----------------------------------------------------------------------------------
int ptid = 0;//token表指针,指向 | 后一个元素
int arithredu(enum Symbols *pst, struct _token *sst,int opr)
{int r = -1;//暂存gen()返回的行号struct _token *t;struct _token *s;//暂存popS(),用于gen()switch (opr){case 99://跳过return 0;case -1:printf("算术语法错误!\n");return -1;case 0://不操作,等待入栈pushP(pst, tokentable[ptid].value);pushS(sst, tokentable[ptid].value, tokentable[ptid].loca);ptid++;break;case 1://归约完成,暂时没用return 1;break;case 2://E->TpopP(pst);pushP(pst, NTS_E);break;case 3://E->T+EpopP(pst);popP(pst);popP(pst);pushP(pst, NTS_E);t = popS(sst);popS(sst);s = popS(sst);r = gen(PLUS, (*s), (*t), -1);pushS(sst, ID, r);break;case 4://E->T-EpopP(pst);popP(pst);popP(pst);pushP(pst, NTS_E);t = popS(sst);popS(sst);s = popS(sst);r = gen(SUB, (*s), (*t), -1);pushS(sst, ID, r);break;case 5://T->(E)popP(pst);popP(pst);popP(pst);pushP(pst, NTS_T);popS(sst);t = popS(sst);popS(sst);pushS(sst, (*t).value, (*t).loca);break;case 6://T->INT*TpopP(pst);popP(pst);popP(pst);pushP(pst, NTS_T);t = popS(sst);popS(sst);s= popS(sst);r = gen(MULT, (*s), (*t), -1);pushS(sst, ID, r);break;case 7://T->INT/TpopP(pst);popP(pst);popP(pst);pushP(pst, NTS_T);t = popS(sst);popS(sst);s = popS(sst);r = gen(DIV, (*s), (*t), -1);pushS(sst, ID, r);break;case 8://T->INTpopP(pst);pushP(pst, NTS_T);break;}return 1;
}
int boolredu(enum Symbols *pst, struct _token *sst, int opr)
{int r = -1;//暂存gen()返回的四元式行号struct _token *t;struct _token *s;//暂存popS(),用于gen()switch (opr){case 99://跳过return 0;case -1:printf("布尔语法错误!\n");return -1;case 0://不操作,等待入栈pushP(pst, tokentable[ptid].value);pushS(sst, tokentable[ptid].value, tokentable[ptid].loca);ptid++;break;case 1://归约完成,暂时没用return 1;break;case 2://B->!BpopP(pst);popP(pst);pushP(pst, NTS_B);popS(sst);t=popS(sst);pushS(sst, (*t).value, (*t).loca );break;case 3://B->EpopP(pst);pushP(pst, NTS_B);break;case 4://B->E<EpopP(pst);popP(pst);popP(pst);pushP(pst, NTS_B);t = popS(sst);popS(sst);s = popS(sst);r = gen(LT, (*s), (*t), -1);pushS(sst, ID, r);break;case 5://B->E>EpopP(pst);popP(pst);popP(pst);pushP(pst, NTS_B);t = popS(sst);popS(sst);s = popS(sst);r = gen(GT, (*s), (*t), -1);pushS(sst, ID, r);break;case 6://B->E<=EpopP(pst);popP(pst);popP(pst);pushP(pst, NTS_B);t = popS(sst);popS(sst);s = popS(sst);r = gen(LE, (*s), (*t), -1);pushS(sst, ID, r);break;case 7://B->E>=EpopP(pst);popP(pst);popP(pst);pushP(pst, NTS_B);t = popS(sst);popS(sst);s = popS(sst);r = gen(GE, (*s), (*t), -1);pushS(sst, ID, r);break;case 8://B->E==EpopP(pst);popP(pst);popP(pst);pushP(pst, NTS_B);t = popS(sst);popS(sst);s = popS(sst);r = gen(EQUL, (*s), (*t), -1);pushS(sst, ID, r);break;case 9://B->B||BpopP(pst);popP(pst);popP(pst);pushP(pst, NTS_B);t = popS(sst);popS(sst);s = popS(sst);r = gen(OR, (*s), (*t), -1);pushS(sst, ID, r);break;case 10://B->B&&BpopP(pst);popP(pst);popP(pst);pushP(pst, NTS_B);t = popS(sst);popS(sst);s = popS(sst);r = gen(AND, (*s), (*t), -1);pushS(sst, ID, r);break;case 11://B->(B)popP(pst);popP(pst);popP(pst);pushP(pst, NTS_B);popS(sst);t = popS(sst);popS(sst);pushS(sst, (*t).value, (*t).loca);break;}return 1;
}
int assignredu(enum Symbols *pst, struct _token *sst, int opr)
{int r = -1;//暂存gen()返回的四元式行号struct _token *t;struct _token *s;//暂存popS(),用于gen()int rb = 0;//暂存popP返回的符号switch (opr){case 99://跳过return 0;case -1:printf("赋值语法错误!\n");return -1;case 0://不操作,等待入栈pushP(pst, tokentable[ptid].value);pushS(sst, tokentable[ptid].value, tokentable[ptid].loca);ptid++;break;case 1://归约完成,暂时没用return 1;break;case 2://s->ID = BpopP(pst);popP(pst);popP(pst);pushP(pst, NTS_S);t = popS(sst);popS(sst);s = popS(sst);r = gen(ASSIGN, (*s), (*t), 0);pushS(sst, ID, r);break;}return 1;
}
int defredu(enum Symbols *pst, struct _token *sst, int opr)
{int r = -1;//暂存gen()返回的四元式行号struct _token *t;struct _token *s;//暂存popS(),用于gen()switch (opr){case 99://跳过return 0;case -1:printf("定义语法错误!\n");return -1;case 0://不操作,等待入栈pushP(pst, tokentable[ptid].value);pushS(sst, tokentable[ptid].value, tokentable[ptid].loca);ptid++;break;case 1://归约完成,暂时没用return 1;break;case 2://S->TYPE_INT IDpopP(pst);popP(pst);pushP(pst, NTS_S);popS(sst);t = popS(sst);pushS(sst, (*t).value, (*t).loca);break;case 3://S->TYPE_INT SpopP(pst);popP(pst);pushP(pst, NTS_S);break;}return 1;
}
int whileredu(enum Symbols *pst, struct _token *sst, int opr)
{int r = -1;//暂存gen()返回的四元式行号int i = 0;struct _token *t;struct _token *s;//暂存popS(),用于gen()int rb = 0;//暂存popP返回的符号switch (opr){case 99://跳过return 0;case -1:printf("while语法错误!\n");return -1;case 0://不操作,等待入栈pushP(pst, tokentable[ptid].value);pushS(sst, tokentable[ptid].value, tokentable[ptid].loca);ptid++;break;case 1://归约完成,暂时没用return 1;break;case 2://W->while  ,预存true链跳转行数popP(pst);pushP(pst, NTS_W);tchain = cout4 ;break;case 3://WD>W B do  ,拉false链popP(pst);popP(pst);popP(pst);pushP(pst, NTS_WD);popS(sst);t = popS(sst);popS(sst);pushS(sst, (*t).value, (*t).loca);gen(JFALSE, (*t), (*t), -2);fchain = cout4 - 1;break;case 4://S->WD SpopP(pst);popP(pst);pushP(pst, NTS_S);popS(sst);t = popS(sst);pushS(sst, 0, 0);gen(JUMP, (*t), (*t), tchain);out4table[fchain].result = cout4;break;}return 1;
}
int ifredu(enum Symbols *pst, struct _token *sst, int opr)
{int r = -1;//暂存gen()返回的四元式行号int i = 0;struct _token *t;struct _token *s;//暂存popS(),用于gen()int rb = 0;//暂存popP返回的符号switch (opr){case 99://跳过return 0;case -1:printf("if语法错误!\n");return -1;case 0://不操作,等待入栈pushP(pst, tokentable[ptid].value);pushS(sst, tokentable[ptid].value, tokentable[ptid].loca);ptid++;break;case 1://归约完成,暂时没用return 1;break;case 2://CA->if B then ,有then拉false链popP(pst);popP(pst);popP(pst);pushP(pst, NTS_CA);popS(sst);t = popS(sst);popS(sst);pushS(sst, (*t).value, (*t).loca);gen(JFALSE, (*t), (*t), -2);fchain = cout4-1;break;case 3://FA->CA S  ,第一个S,有S拉true链popP(pst);popP(pst);pushP(pst, NTS_FA);popS(sst);t = popS(sst);pushS(sst, (*t).value, (*t).loca);gen(JUMP, (*t), (*t), -2);tchain = cout4 - 1;break;case 4://CE->ELSEpopP(pst);pushP(pst, NTS_CE);popS(sst);pushS(sst, 0, 0);out4table[fchain].result = cout4;break;case 5://CBE->else if  ,有else回填false链popP(pst);popP(pst);pushP(pst, NTS_CBE);popS(sst);popS(sst);pushS(sst, 0, 0);out4table[fchain].result = cout4;break;case 6://CB->CBE B thenpopP(pst);popP(pst);popP(pst);pushP(pst, NTS_CB);popS(sst);t = popS(sst);popS(sst);pushS(sst, (*t).value, (*t).loca);gen(JFALSE, (*t), (*t), 0);fchain = cout4 - 1;break;case 7://FB->CB S 拉true链popP(pst);popP(pst);pushP(pst, NTS_FB);popS(sst);t=popS(sst);pushS(sst, 0, 0);gen(JUMP, (*t), (*t), tchain);tchain = cout4-1;break;case 8://FC->CE S ,最后一个S,回填所有true链popP(pst);popP(pst);pushP(pst, NTS_FC);popS(sst);popS(sst);pushS(sst, 0, 0);while (tchain!=-2){r = tchain;tchain = out4table[tchain].result;out4table[r].result = cout4;}r = tchain;tchain = out4table[tchain].result;out4table[r].result = cout4;break;case 9://S->FA FB...FB FCi = 0;popP(pst);popP(pst);i++;if ((*(pst+pstack-1)) == NTS_FB){i++;popP(pst);}popP(pst);pushP(pst, NTS_S);popS(sst);for (int j = 0; j < i; j++){popS(sst);}popS(sst);pushS(sst, 0, 0);break;case 10://S->FApopP(pst);pushP(pst, NTS_S);case 11://S->FA FCpopP(pst);popP(pst);pushP(pst, NTS_S);popS(sst, 0, 0);break;  case 12://S->FAFB...FBpopP(pst);popP(pst);i++;if ((*(pst + pstack - 1)) == NTS_FB){popP(pst);i++;}pushP(pst, NTS_S);popS(sst);for (int j = 0; j < i; j++){popS(sst);}popS(sst);pushS(sst, 0, 0);break;}return 1;
}
int mainredu(enum Symbols *pst, struct _token *sst, int opr)//(语法栈,语义栈,操作码)
{int r = -1;//暂存gen()返回的四元式行号struct _token *t;struct _token *s;//暂存popS(),用于gen()int rb = 0;//暂存popP返回的符号switch (opr){case 99://跳过return 0;case -1:printf("总语法错误!\n");return -1;case 0://不操作,等待入栈pushP(pst, tokentable[ptid].value);pushS(sst, tokentable[ptid].value, tokentable[ptid].loca);ptid++;break;case 1://归约完成,暂时没用return 1;break;case 2://S->begin S...S endpopP(pst);popP(pst);if ((*(pst + pstack - 1)) == NTS_S){popP(pst);}popP(pst);pushP(pst, NTS_S);popS(sst);popS(sst);if ((*(pst + pstack - 1)) == NTS_S){popS(sst);}popS(sst);pushS(sst, NTS_S,0);break;}return 1;
}
//-----------------------------------------------------------------------------------
int arithautomat(enum Symbols * pst, enum Symbols * tpst, struct _token *sst)//(语法栈,语法栈当前位置,语义栈,)
{int * ppst = NULL;//栈指针,用来遍历栈,返回操作码ppst = tpst;int state = 1;//状态int isok = 0;//结束?int opr = 0;while (isok == 0){//不在栈顶switch (state){case 1://开始态switch (*ppst){case NTS_T:state = 2;break;case INT:state = 3;break;case ID:state = 3;break;case L_PARENS:state = 4;break;case NTS_E:state = 15;break;default:state = -1;}break;case 2://E->T|T.+E|T.-Eswitch (*ppst){case PLUS:state = 5;break;case SUB:state = 6;break;default:state = -1;}break;case 3://T->INT.*T|INT./T|INTswitch (*ppst){case MULT:state = 7;break;case DIV:state = 8;break;default:state = -1;}break;case 4://T->(.E)|E->|T->|switch (*ppst){case INT:state = 3;break;case ID:state = 3;break;case NTS_T:state = 2;break;case NTS_E:state = 13;break;default:state = -1;}break;case 5://T->INT|INT*T|INT/T|(E)|E->T-.E|T+.E|Tswitch (*ppst){case NTS_E:state = 9;break;case NTS_T:state = 2;break;case INT:state = 3;break;case ID:state = 3;break;case L_PARENS:state = 4;break;default:state = -1;}break;case 6://同5,-推导出6状态switch (*ppst){case NTS_E:state = 10;break;case NTS_T:state = 2;break;case INT:state = 3;break;case ID:state = 3;break;case L_PARENS:state = 4;break;default:state = -1;}break;case 7://T->INT*.T|INT/.T|INT|.INT*T|.INT/Tswitch (*ppst){case INT:state = 3;break;case ID:state = 3;break;case NTS_T:state = 11;break;case L_PARENS:state = 4;break;default:state = -1;}break;case 8://同7,/推导出8状态switch (*ppst){case INT:state = 3;break;case ID:state = 3;break;case NTS_T:state = 12;break;case L_PARENS:state = 4;break;default:state = -1;}break;case 13://E->(E.)switch (*ppst){case R_PARENS:state = 14;break;default:state = -1;}break;}ppst++;if (ppst == (pst + pstack))//指针在栈顶{switch (state){case -1:opr=-1;break;case 2://预读+.-switch (tokentable[ptid].value)//预读{case PLUS:opr = 0;break;case SUB:opr = 0;break;case L_PARENS:opr = -1;break;default:opr = 2;break;}break;case 3://预读*./switch (tokentable[ptid].value)//预读{case MULT:opr = 0;break;case DIV:opr = 0;break;case L_PARENS:opr = -1;break;default:opr = 8;break;}break;case 9://T+E.opr = 3;break;case 10://T-E.opr = 4;break;case 11://INT*T.opr = 6;break;case 12://INT/T.opr = 7;break;case 14://T->(E).opr = 5;break;case 15://E.归约完成return 1;default:opr = 0;//其他情况均请求归约器入栈}int ok=arithredu(pst, sst, opr);if (ok == -1){return 0;//错误,返回0}state = 1;ppst = tpst;//栈指针归位outs(pst);}}
}
int boolautomat(enum Symbols * pst, enum Symbols * tpst, struct _token *sst)
{int * ppst = NULL;//栈指针,用来遍历栈,返回操作码ppst = tpst;int state = 1;//状态int isok = 0;//结束?int opr = 0;while (isok == 0){switch (state){case 1://开始态switch (*ppst){case NEGA:state = 2;break;case NTS_E:state = 4;break;case NTS_B:state = 15;break;case L_PARENS:state = 20;break;case INT:state = 23;break;case ID:state = 23;break;default:state = -1;}break;case 2://B->!Bswitch (*ppst){case NTS_B:state = 3;break;default:state = 1;}break;case 4://B->E||E rop Eswitch (*ppst){case LT:state = 5;break;case GT:state = 6;break;case LE:state = 7;break;case GE:state = 8;break;case EQUL:state = 9;break;default:state = -1;}break;case 5://B->E<.Eswitch (*ppst){case NTS_E:state = 10;break;case INT:state = 23;break;case ID:state = 23;break;default:state = -1;}break;case 6://B->E>.Eswitch (*ppst){case NTS_E:state = 11;break;case INT:state = 23;break;case ID:state = 23;break;default:state = -1;}break;case 7://B->E<=.Eswitch (*ppst){case NTS_E:state = 12;break;case INT:state = 23;break;case ID:state = 23;break;default:state = -1;}break;case 8://B->E>=.Eswitch (*ppst){case NTS_E:state = 13;break;case INT:state = 23;break;case ID:state = 23;break;default:state = -1;}break;case 9://B->E==.Eswitch (*ppst){case NTS_E:state = 14;break;case INT:state = 23;break;case ID:state = 23;break;default:state = -1;}break;case 15://B->B.||B |B.&&B |B.switch (*ppst){case OR:state = 16;break;case AND:state = 18;break;default:state = -1;}break;case 16://B->B||.Bswitch (*ppst){case NTS_B:state = 17;break;case NEGA:state = 2;break;case NTS_E:state = 4;break;case L_PARENS:state = 20;break;case INT:state = 23;break;case ID:state = 23;break;default:state = 1;}break;case 18://B->B&&.Bswitch (*ppst){case NTS_B:state = 19;break;case NEGA:state = 2;break;case NTS_E:state = 4;break;case L_PARENS:state = 20;break;case INT:state = 23;break;case ID:state = 23;break;default:state = 1;}break;case 20://B->(.B)switch (*ppst){case NTS_B:state = 21;break;case NEGA:state = 2;break;case NTS_E:state = 4;break;case L_PARENS:state = 20;break;case INT:state = 23;break;case ID:state = 23;break;default:state = 1;}break;case 21://B->(B.)switch (*ppst){case R_PARENS:state = 22;break;default:state = -1;}break;}ppst++;if (ppst == (pst + pstack))//指针在栈顶{int z = 0;switch (state){case -1:opr = -1;break;case 3:opr= 2;break;case 4://预读 ropswitch (tokentable[ptid].value)//预读{case LE:opr = 0;break;case LT:opr = 0;break;case GE:opr = 0;break;case GT:opr = 0;break;case EQUL:opr = 0;break;case L_PARENS:opr = -1;break;default:opr = 3;break;}break;case 10://B->E<Eopr = 4;break;case 11://B->E>Eopr = 5;break;case 12://B->E<=Eopr = 6;break;case 13://B->E>=Eopr = 7;break;case 14://B->E==Eopr = 8;break;case 15://预读 || && switch (tokentable[ptid].value)//预读{case AND:opr = 0;break;case OR:opr = 0;break;case L_PARENS:opr = -1;break;default://结束状态return 1;break;}break;case 17://B->B||Bopr = 9;break;case 19://B->B && Bopr = 10;break;case 22://B->(B)opr = 11;break;case 23://调用算术自动机z = 0;z = arithautomat(pst,(ppst - 1), sst);if (z == 0){return 0;}opr = 99;break;default:opr = 0;//其他情况均请求归约器入栈}int ok = boolredu(pst, sst, opr);if (ok == -1){return 0;}state = 1;ppst = tpst;//栈指针归位outs(pst);}}
}
int assignautomat(enum Symbols * pst, enum Symbols * tpst, struct _token *sst)
{int * ppst = NULL;//栈指针,用来遍历栈,返回操作码ppst = tpst;int state = 1;//状态int isok = 0;//结束?int opr = 0;while (isok == 0){switch (state){case 1://开始态switch (*ppst){case ID:state = 2;break;case NTS_S:state = 6;break;default:state = -1;}break;case 2://S->ID.=Bswitch (*ppst){case ASSIGN:state = 3;break;default:state = -1;}break;case 3://S->ID=.Bswitch (*ppst){case NTS_B:state = 5;break;default:state = 4;}break;}ppst++;if (ppst == (pst + pstack))//指针在栈顶{int z = 0;switch (state){case -1:opr = -1;break;case 4://调用布尔自动机z = 0;z = boolautomat(pst, (ppst - 1), sst);if (z == 0){return 0;}opr = 99;break;case 5:opr = 2;break;case 6:return 1;default:opr = 0;//其他情况均请求归约器入栈}int ok = assignredu(pst, sst, opr);if (ok == -1){return 0;}state = 1;ppst = tpst;//栈指针归位outs(pst);}}
}
int defautomat(enum Symbols * pst, enum Symbols * tpst, struct _token *sst)
{int * ppst = NULL;//栈指针,用来遍历栈,返回操作码ppst = tpst;int state = 1;//状态int isok = 0;//结束?int opr = 0;while (isok == 0){switch (state){case 1://开始态switch (*ppst){case TYPE_INT:state = 2;break;case NTS_S:return 1;default:state = -1;}break;case 2://S->TYPE_INT. ID ||TYPE_INT Sswitch (*ppst){case NTS_S:state = 5;break;default:state = 4;}break;}ppst++;if (ppst == (pst + pstack))//指针在栈顶{int z = 0;switch (state){case -1:opr = -1;break;case 3://调用赋值自动机z = 0;z = assignautomat(pst, (ppst - 1), sst);if (z == 0){return 0;}opr = 99;break;case 4:switch (tokentable[ptid].value)//预读{case ASSIGN:z = 0;z = assignautomat(pst, (ppst - 1), sst);if (z == 0){return 0;}opr = 99;break;default:opr = 2;break;}break;case 5:opr = 3;break;default:opr = 0;//其他情况均请求归约器入栈}int ok = defredu(pst, sst, opr);if (ok == -1){return 0;}state = 1;ppst = tpst;//栈指针归位outs(pst);}}
}
int whileautomat(enum Symbols * pst, enum Symbols * tpst, struct _token *sst)
{int * ppst = NULL;//栈指针,用来遍历栈,返回操作码ppst = tpst;int state = 1;//状态int isok = 0;//结束?int opr = 0;while (isok == 0){switch (state){case 1://开始态switch (*ppst){case WHILE:state = 2;break;case NTS_W:state = 3;break;case NTS_WD:state = 6;break;case NTS_S:return 1;default:state = -1;}break;case 3://WD->W.B doswitch (*ppst){case NTS_B:state = 4;break;default:state = 8;}break;case 4://WD->W B. doswitch (*ppst){case DO:state = 5;break;default:state = -1;}break;case 6://S->WD.Sswitch (*ppst){case NTS_S:state = 7;break;default:state = 9;}break;}ppst++;if (ppst == (pst + pstack))//指针在栈顶{int z = 0;switch (state){case -1:opr = -1;break;case 2:opr = 2;break;case 5://WD->W B doopr = 3;break;case 7://S->WD Sopr = 4;break;case 8://调用bool自动机z = 0;z = boolautomat(pst, (ppst - 1), sst);if (z == 0){return 0;}opr = 99;break;case 9://调用主自动机z = 0;z = mainautomat(pst, (ppst - 1), sst);if (z == 0){return 0;}opr = 99;break;default:opr = 0;//其他情况均请求归约器入栈}int ok = whileredu(pst, sst, opr);if (ok == -1){return 0;}state = 1;ppst = tpst;//栈指针归位outs(pst);}}
}
int ifautomat(enum Symbols * pst, enum Symbols * tpst, struct _token *sst)
{int * ppst = NULL;//栈指针,用来遍历栈,返回操作码ppst = tpst;int state = 1;//状态int isok = 0;//结束?int opr = 0;while (isok == 0){switch (state){case 1://开始态switch (*ppst){case IF:state = 2;break;case NTS_CA:state = 5;break;case NTS_FA:state = 17;break;case NTS_S:return 1;default:state = -1;}break;case 2://CA->if. B themswitch (*ppst){case NTS_B:state = 3;break;default:state = 18;}break;case 3://CA->if B. themswitch (*ppst){case THEN:state = 4;break;default:state = -1;}break;case 5://FA->CA.Sswitch (*ppst){case NTS_S:state = 6;break;case BEGIN:state = 19;break;default:state = -1;}break;case 7://CBE->else. ifswitch (*ppst){case IF:state = 9;break;default:state = -1;}break;case 10://CB->CBE. B thenswitch (*ppst){case NTS_B:state = 11;break;default:state = 18;}break;case 11://CB->CBE B. thenswitch (*ppst){case THEN:state = 12;break;default:state = -1;}break;case 13://FB->CB. Sswitch (*ppst){case NTS_S:state = 14;break;case BEGIN:state = 19;default:state = 19;}break;case 15://FC->CE.Sswitch (*ppst){case NTS_S:state = 16;break;case BEGIN:state = 19;break;default:state = 19;}break;case 17://S->FA.***switch (*ppst){case ELSE:state = 7;break;case NTS_CBE:state = 10;break;case NTS_CB:state = 13;break;case NTS_CE:state = 15;break;case NTS_FB:state = 20;break;case NTS_FC:state = 22;break;default:state = -1;}break;case 20://S->FA FB...FB FCswitch (*ppst){case NTS_FB:state = 20;break;case NTS_FC:state = 21;break;default:state = 17;ppst--;}break;}ppst++;if (ppst == (pst + pstack))//指针在栈顶{int z = 0;switch (state){case -1:opr = -1;break;case 4://CA->if B thenopr = 2;break;case 6://FA->CA Sopr = 3;break;case 7://预读 IFswitch (tokentable[ptid].value)//预读{case IF:opr = 0;break;default:opr = 4;//CE->elsebreak;}break;case 9://CBE->else ifopr = 5;break;case 12://CB->CBE B thenopr = 6;break;case 14://FB->CB Sopr = 7;break;case 16://FC->CE Sopr = 8;break;case 17://预读 switch (tokentable[ptid].value)//预读{case ELSE:opr = 0;break;case NTS_CBE:opr = 0;break;case NTS_CB:opr = 0;break;case NTS_CE:opr = 0;break;case NTS_FB:opr = 0;break;default:opr = 10;//S->FAbreak;}break;case 18://调布尔自动机z = 0;z = boolautomat(pst, (ppst - 1), sst);if (z == 0){return 0;}opr = 99;break;case 19://调主自动机z = 0;z = mainautomat(pst, (ppst - 1), sst);if (z == 0){return 0;}opr = 99;break;case 20://预读 switch (tokentable[ptid].value)//预读{case ELSE:opr = 0;break;case NTS_FB:opr = 0;break;case NTS_FC:opr = 0;break;default:opr = 12;//S->FAFB...FBbreak;}break;case 21://S->FA FB...FB FC opr = 9;break;case 22:opr = 11;break;default:opr = 0;//其他情况均请求归约器入栈}int ok = ifredu(pst, sst, opr);if (ok == -1){return 0;}state = 1;ppst = tpst;//栈指针归位outs(pst);}}
}
int mainautomat(enum Symbols * pst, enum Symbols * tpst, struct _token *sst)//主自动机,归约代码块
{int * ppst = NULL;//栈指针,用来遍历栈,返回操作码ppst = tpst;int state = 1;//状态int isok = 0;//结束?int opr = 0;int z = 0;while (isok == 0){//不在栈顶switch (state){case 1://开始态switch (*ppst){case BEGIN:state = 2;break;case IF:state = 4;break;case TYPE_INT:state = 5;break;case WHILE:state = 6;break;case ID:state = 7;break;case NTS_S:return 1;default:state = -1;}break;case 2://S->begin S...S endswitch (*ppst){case NTS_S:state = 2;break;case END:state = 3;break;default:state = 1;ppst--;}break;}ppst++;if (ppst == (pst + pstack))//指针在栈顶{switch (state){case -1:if ((tokentable[ptid - 1].value) == EOS){return 0;}opr = -1;break;case 3://S->begin S...S endopr = 2;break;case 4://调用if自动机z = 0;z = ifautomat(pst, (ppst - 1), sst);if (z == 0){return 0;}opr = 99;break;case 5://调用def自动机z = 0;z = defautomat(pst, (ppst - 1), sst);if (z == 0){return 0;}opr = 99;break;case 6://调用while自动机z = 0;z = whileautomat(pst, (ppst - 1), sst);if (z == 0){return 0;}opr = 99;break;case 7://调用assign自动机z = 0;z = assignautomat(pst, (ppst - 1), sst);if (z == 0){return 0;}opr = 99;break;default:opr = 0;//其他情况均请求归约器入栈}int ok = mainredu(pst, sst, opr);if (ok == -1){return 0;//错误,返回0}state = 1;ppst = tpst;//栈指针归位outs(pst);}}
}//-----------------------------------------------------------------------------------
int redu_se(enum Symbols *pst, struct _token *sst)
{int isok = 0;pushP(pst, tokentable[ptid].value);pushS(sst, tokentable[ptid].value, tokentable[ptid].loca);ptid++;int rb = 0;mainautomat(pst,pst, sst);return 0;
}
//-----------------------------------------------------------------------------------
int btparser(char * str)//传入待编译代码
{int iserr = 0;char *c = NULL;//str文档指针c = str;while ((*c) != 0)//将符号转化成对应编码{iserr = lexer(c);if (iserr == 0)//有错误字符,停止运行{printf("词法错误!");return 0;}c = c + iserr;}printf("正确录入。\n");enum Symbols pStack[64];enum Symbols *pst;//代表语法栈pst = pStack;struct _token sStack[64];struct _token *sst;//代表语义栈sst = sStack;redu_se(pst, sst);printf("ok");
}

有点多,但一个功能齐全的编译器不止如此,我还在学习,这里当做备份。

采用自底向上归约编译器相关推荐

  1. 支付宝App采用华为方舟编译器几乎秒开?支付宝回应:华为好棒,加油

    近日,知乎有话题称"支付宝在更新之后启动速度快了很多,有用户怀疑可能是用华为方舟编译器编译过的,所以变快了",对此,支付宝官方做出相关回应. 知乎有网友提问,如何看待「支付宝采用华 ...

  2. 论内存管理在编译器中的重要性

    关注+星标公众号,不错过精彩内容 来源 | 极客时间 前两天刷知乎,看到一个做编译器的老哥被猎头"三顾茅庐"的经历,给我笑坏了.老哥原话是"第一次感觉自己这么牛逼&quo ...

  3. Bison 移进-归约分析

    bison 采用自底向上 (bottom-up) 的分析方法.它用到一个分析栈 (parser stack),关键有两个动作: 1. 移进 (shift)     读取的 token 移进到分析栈中. ...

  4. 安卓代码拉下来编译后怎么运行_支付宝秒开是因为用了方舟编译器?官方回应...

    近期有不少用户发现,支付宝在更新后可以实现秒开,有传言称支付宝是采用了华为的方舟编译器才达到了这种效果. 有网友在知乎提问:如何看待支付宝采用华为方舟编译器几乎秒开的消息?" 这位网友表示: ...

  5. 自底向上构建知识图谱全过程

    http://www.sohu.com/a/245246344_160850 阿里妹导读:知识图谱的构建技术主要有自顶向下和自底向上两种.其中自顶向下构建是指借助百科类网站等结构化数据源,从高质量数据 ...

  6. 通俗讲解自底向上构建知识图谱全过程

    知识图谱的基础介绍,供学习参考. 转载自:https://mp.weixin.qq.com/s/7cBbtqvPQUVrLZUNDx8XDQ 知识图谱的构建技术主要有自顶向下和自底向上两种.其中自顶向 ...

  7. 《C语言编程魔法书:基于C11标准》——1.3 主流C语言编译器介绍

    本节书摘来自华章计算机<C语言编程魔法书:基于C11标准>一书中的第1章,第1.3节,作者: 陈轶 更多章节内容可以访问云栖社区"华章计算机"公众号查看. 1.3 主流 ...

  8. Visual C++利用Intel C++ 编译器提升多核性能与多媒体指令支持获取更高的程序效率与缩小程序体积

    Intel c++编译器有下列优点,建议VC++项目开发采用intel c++编译器取代VS自带c++编译器: 与 Microsoft Visual C++ 相兼容,可以嵌入 Microsoft Vi ...

  9. 技术动态 | 自底向上构建知识图谱全过程

    本文转载自公众号:阿里技术. "The world is not made of strings , but is made of things." --辛格博士,from Goo ...

最新文章

  1. oracle服务器环境建立,oracle 透明网关环境的建立
  2. python变量定义大全_详解python变量与数据类型
  3. 解析可变参数函数的实现原理(printf,scanf)
  4. jsp+easyui+DataGrid 例子
  5. 自然语言10_分类与标注
  6. element ui 菜单封装_vue模块化(echart+element ui)
  7. python教程视频完整版-Python教程视频完整版
  8. 语音识别在生活中的七个经典应用
  9. 第四十六讲 ASP.NET实例编程(五)
  10. UE4添加人物动画之前后左右移动
  11. codeforces633H Fibonacci-ish II
  12. 配置静态IP失败总结
  13. SpringCloud--鸿鹄Cloud分布式微服务云系统
  14. Windows无法连接到无线网络
  15. 补码/反码、零扩展和符号位扩展(Zero extension and Sign extension)
  16. 【mud】npc对话函数与自动对话匹配(gongsun.c)
  17. 红黑树-介绍/性质/定理/基本操作/特点
  18. c语言中数组的各元素必须具有相同的类型,2018年9月计算机二级C语言程序设计章节习题1...
  19. 李永乐六套卷-2021
  20. Debian10中使用deb包安装WineHQ(鬼畜依赖解决)

热门文章

  1. redis哨兵模式(docker)
  2. [4G5G专题-14]:应用层-5G的三大业务应用场景(多、快、好、省)
  3. python:实现叠加图片(附完整源码)
  4. OpenCV Java入门五 结合摄像头识脸和拍照
  5. openTSDB详解之Writing Data
  6. 【大厂算法系列】学数据结构与算法有用吗?时间与空间复杂度的定义与计算
  7. python 云服务器 网站
  8. 最新手机号码检验正则表达式
  9. html页面标题是什么,javascript如何获取网页的标题(title)?
  10. 【论文下饭】Functional Connectivity Prediction With Deep Learning for Graph Transformation