编译原理记忆dm
语法树结构
1 算术表达式
typedef enum { Plus, Minus, Times } OpKind;
typedef enum { Opkind, ConstKind } ExpKind;
typedef struct streenode {
ExpKind kind;
OpKind op;
struct streenode *lchild, *rchild;
int val;
} STreeNode;
typedef STreeNode* SynataxTree;
2 if语句:
typedef enum { ExpK, StmtK } NodeKind;
typedef enum { Zero, One } ExpKind;
typedef enum { IfK, OtherK } StmtKind;
typedef struct streenode {
NodeKind kind;
ExpKind ekind;
struct streenode *test, *thenpart, *elsepart;
} STreeNode;
typedef STreeNode* SynataxTree;
递归子程序
1 match函数:
void match ( expectedToken )
{
if (token==expectedToken)
getToken( ); //获取下一个符号
else Error( ); // 产生出错信息
} // match
2 Error函数
void Error ( int ErrorNo )
{
switch(ErrorNo) {
case 1: cout<<"漏了一个a或b" ;break;
case 2: cout<<"漏了一个c或d";break;
case 3: cout<<"漏了一个e或f";break;
......
}// switch
} //Error
3 实现算术表达式值的计算
//exp → exp + term | exp - term |term => exp → term { (+|- ) term }
//每个递归函数返回当前计算结果
int exp( )
{
int temp;
temp = term( );
while ((token =='+')||(token =='-') {
switch (token ){
case '+' :match ('+') ;
temp = temp + term( );
break;
case '-': match ('-') ;
temp = temp – term( );
break;
} //switch
} while
return temp ;
} //exp
4 算术表达式对应语法树的构造
//exp → term { (+|- ) term }
BTreeNode * exp( )
{
BTreeNode * temp, *newtemp;
temp = term( ) ;
while ( token == '+' || token == '-' ) {
newtemp = new BTreeNode ;
newtemp ->data= token ;
match (token) ;
newtemp->lchild = temp ;
newtemp->rchild= term( ) ;
temp = newtemp ;
}
return temp ;
}// exp
5 为if语句构造相应的语法树
//if-stmt→if(exp)statement[else statement ]
syntaxTree ifStatement( )
{
syntaxTree temp;
match ("if") ;
match ('(') ;
temp =makeStmtNode(if) ; //生成新结点
temp->testChild = exp( ) ;
match (')' ) ;
temp->thenChild = statement( ) ;
if (token == "else" ) {
match ("else") ;
temp->elseChild = statement( ) ;
}
else temp->elseChild = NULL ;
} // ifStatement ;
6 求first集
void grammerTable::get_first(char target) {
int tag = 0;
int flag = 0;
for (int i = 0; i<T; i++)
{
if (graStack[i].left == target)//匹配产生式左部
{
if (!isNotSymbol(graStack[i].right[0]) && graStack[i].right[0] != '*')//对于终结符,直接加入first
{
first_set[get_nindex(target)].insert(graStack[i].right[0]);
}
else
{
int j;
if(graStack[i].right[0] == '*') //若为消除左递归后的结果则跳过'*'
j = 1;
else
j = 0;
for (; j<graStack[i].right.length(); j++) {
if (!isNotSymbol(graStack[i].right[j]))//是终结符则结束
{
first_set[get_nindex(target)].insert(graStack[i].right[j]);
break;
}
get_first(graStack[i].right[j]);//递归
set<char>::iterator it;
for (it = first_set[get_nindex(graStack[i].right[j])].begin();it != first_set[get_nindex(graStack[i].right[j])].end(); it++)
{
if (*it == '#') flag = 1;
else first_set[get_nindex(target)].insert(*it);//将FIRST(Y)中的非#就加入FIRST(X)
}
if (flag == 0) break;
else {
tag += flag;
flag = 0;
}
}
if (tag == graStack[i].right.length())//所有右部first(Y)都有#,将#加入FIRST(X)中
first_set[get_nindex(target)].insert('#');
}
}
}
}
7 求follow集
void grammerTable::get_follow(char target) {
for (int i = 0; i<T; i++)
{
int index = -1;
int len = int ( graStack[i].right.length());
for (int j = 0; j<len; j++)
{
if (graStack[i].right[j] == target)
{
index = j;
break;
}
}
if (index != -1 && index < len - 1)
{
char nxt = graStack[i].right[index + 1];
if (!isNotSymbol(nxt))
{
follow_set[get_nindex(target)].insert(nxt);
}
else
{
int isExt = 0;
set<char>::iterator it;
for (it = first_set[get_nindex(nxt)].begin(); it != first_set[get_nindex(nxt)].end(); it++)
{
if (*it == '#')
isExt = 1;
else
follow_set[get_nindex(target)].insert(*it);
}
if (isExt && graStack[i].left != target)
{
get_follow(graStack[i].left);
set<char>::iterator it;
char tmp = graStack[i].left;
for (it = follow_set[get_nindex(tmp)].begin(); it != follow_set[get_nindex(tmp)].end(); it++)
{
follow_set[get_nindex(target)].insert(*it);
}
}
}
else if (index != -1 && index == len - 1 && target != graStack[i].left)
{
get_follow(graStack[i].left);
set<char>::iterator it;
char tmp = graStack[i].left;
for (it = follow_set[get_nindex(tmp)].begin(); it != follow_set[get_nindex(tmp)].end(); it++)
follow_set[get_nindex(target)].insert(*it);
}
}
}
(仅作个人经验记录)