您的位置:首页 > 其它

编译原理学习笔记(四)预测分析器(2)

2017-04-11 17:26 417 查看
上次说到了驱动表,这里给出利用驱动表进行预测分析的算法实现(原书伪码见p144)

syn_unit end(0);//结束符
syn_unit start(mode, mesh_table[mode]->src.lex, 0, syn_unit::NONTERMINATOR);//mode为开始符号的参数
stack<syn_unit> stk;
stk.push(end);
stk.push(start);
int pos = 0;
auto lx_unit = lex->getNextToken(code, pos);//读入第一个词法单元
while (stk.top() != end && pos < code.length()){
auto&cur_sig = stk.top();
switch (cur_sig.type){//符号类型
case syn_unit::LEX:
if (lx_unit->compare(cur_sig.token)){//匹配
output(lx_unit->token);//处理匹配结果
stk.pop();
}
else{//失配 尝试别的?
report("不匹配的类型:"+lx_unit->token);
}
lx_unit = lex->getNextToken(code, pos);//匹配后才后移
break;
case syn_unit::NONTERMINATOR:
auto&prod = mesh_table[cur_sig.token];//获取产生式组
if (prod->drivetable.find(lx_unit) != prod->drivetable.end()){//该单词在驱动表中
stk.pop();
auto&dst = prod->dst[prod->drivetable[lx_unit]];//选择产生式
for (auto&var = dst.rbegin(); var != dst.rend(); var++)
stk.push(*var);//展开并逆序压入栈
}
break;
}
}


驱动表是是一个二维数组,其行和列分别用产生式头(非终结符)和当前词法单元(终结符)为索引,构造这个表需要每个产生式的FIRST集合以及FOLLOW集合,每个产生式组(各个产生式以‘|’分割开来)的FIRST集合是互不相交的(LL(1)文法的要求),因此根据FIRST集合中的终结符可以确定产生式,但这不是唯一确定,因为FIRST集合中可能有空符ε的存在,如果ε存在,则需要查看其FOLLOW集合,将FOLLOW集合中含有该词法单元的产生式添加到表中。

上次的结构中没有FOLLOW集合,大致说一下FOLLOW集合的构成。举个例子:A->ABc,其中A B为非终结符,c为终结符,A的FOLOW集合在这个产生式中就是FIRST(B)的内容,如果FIRST(B)含有ε,那么还需要添加c。

至此预测分析器的内容大致结束,由于代码太长不适合贴出,只留下运行结果。



可以看出跟词法分析的结果类似,但不同的是每个数字都输出为词法单元标识,而不是具体值。每个词法单元所含的具体值是其一种属性,需要在制导翻译的过程中获得,并通过产生式的语义动作进行运算,得到翻译结果。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  编译原理
相关文章推荐