转载请注明出处:https://blog.csdn.net/hhhhhhhhhhkkkkkkkkkk
实现分析器
辅助函数:打印函数集合
void print_vv(t_vv vv)
{
printf("%d", vv);
}
void print_vt(t_vt vt)
{
if (vt >= 31 && vt < 0xffff)
printf("%c", vt);
else
printf("%d", vt);
}
void print_vn(t_vn vn)
{
printf("%d", vn);
}
void print_sym(t_sym sym)
{
if (is_vn(sym))
print_vn(sym);
else if (is_vt(sym))
print_vt(sym);
else if (is_vv(sym))
print_vv(sym);
else
printf("<error sym>");
}
void print_syms(const t_syms&syms)
{
for (auto sym : syms)
print_sym(sym);
}
void print_first(const t_first&first)
{
for (auto vt : first)
print_vt(vt);
}
void print_sen(const t_sen&sen)
{
print_vn(sen.left);
printf("=");
print_syms(sen.rights);
printf(" ->");
print_vv(sen.pri_sym);
}
void print_sens(const t_sens&sens)
{
for (const auto&sen : sens)
{
print_sen(sen);
printf("\n");
}
}
void print_vv_pri_ass_map(const t_vv_pri_ass_map&vv_pri_ass_map)
{
for (const auto&vv_pri_ass : vv_pri_ass_map)
{
print_vv(vv_pri_ass.first);
printf(":");
printf("%d,", vv_pri_ass.second.first);
switch (vv_pri_ass.second.second)
{
case e_ass_none:
{
printf("none");
break;
}
case e_ass_left:
{
printf("left");
break;
}
case e_ass_right:
{
printf("right");
break;
}
default:
{
printf("error ass");
break;
}
}
printf("\n");
}
}
void print_grammar(const t_grammar&grammar)
{
printf("sens:\n");
print_sens(grammar.sens);
printf("pri_ass:\n");
print_vv_pri_ass_map(grammar.vv_pri_ass_map);
}
void print_item(const t_item&item, const t_sens&sens)
{
const auto&sen = sens.at(item.senid);
printf("%d:", item.senid);
print_vn(sen.left);
printf("=");
for (size_t i = 0; i < item.pos; i++)
print_sym(sen.rights.at(i));
printf(".");
for (size_t i = item.pos; i < sen.rights.size(); i++)
print_sym(sen.rights.at(i));
printf(" ->");
print_first(item.first);
}
void print_items(const t_items&items, const t_sens&sens)
{
for (const auto&item : items)
{
print_item(item, sens);
printf("\n");
}
}
void print_action_map(const t_action_map&action_map)
{
for (const auto&pr : action_map)
{
print_sym(pr.first);
printf(":");
if (pr.second >= 0)
{
printf("shift %d", pr.second);
}
else if (pr.second == -1)
{
printf("access %d", -int(pr.second) - 1);
}
else
{
printf("reduce %d", -int(pr.second) - 1);
}
printf("\n");
}
}
void print_collision_map(const t_collision_map&collision_map)
{
for (const auto&pr : collision_map)
{
if (pr.second.size() < 2)continue;
print_vt(pr.first);
printf(":");
auto it = pr.second.find(e_shift);
if (it != pr.second.end())
{
printf("shift[ ");
for (auto senid : it->second)
printf("%d ", senid);
printf("]");
}
auto it1 = pr.second.find(e_reduce);
if (it1 != pr.second.end())
{
if (it != pr.second.end())
printf(",");
printf("reduce[ ");
for (auto senid : it1->second)
printf("%d ", int(senid));
printf("]");
}
printf("\n");
}
}
void print_set(const t_set&set, const t_sens&sens)
{
//printf("items:\n");
print_items(set.items, sens);
if (set.action_map.size() > 0)
{
printf("action_map:\n");
print_action_map(set.action_map);
}
if (set.collision_map.size() > 0)
{
printf("collision_map:\n");
print_collision_map(set.collision_map);
}
}
void print_cluster(const t_cluster&cluster, const t_sens&sens)
{
size_t i = 0;
for (const auto&set : cluster)
{
printf("item %d:\n", i);
print_set(set, sens);
printf("\n");
i++;
}
}
void print_collision_map_only(const t_cluster&cluster, const t_sens&sens)
{
size_t i = 0;
for (const auto&set : cluster)
{
if (set.collision_map.size() > 0)
{
print_collision_map(set.collision_map);
printf("\n");
i++;
}
}
}
分析器的实现
//节点
struct t_range
{
int left, right;
};
struct t_lrnode
{
int type;
t_range range;
std::vector<t_lrnode*>children;
};
class t_analyzer
{
struct t_unit
{
int state;
t_sym sym;
int pos;
void*data;
t_lrnode*node;
};
struct t_ctx
{
std::vector<t_unit>stacks;
int vtid;
int sen_len;
void*_ret;
t_lrnode*node;
t_vv vv;
void*user_data;
e_action ret;
const t_cluster*cl0;
const t_grammar*gm0;
};
t_ctx ctx;
public:
template<typename t_type>void analysis(const t_type&vts, const t_cluster&cluster, const t_grammar&g, void*user_data)
{
start(&ctx, cluster, g, user_data);
while (true)
{
auto ret = push(&ctx, vts[ctx.vtid]);
if (ret == e_access || ret == e_error)
break;
}
}
void start(t_ctx*ctx, const t_cluster&cluster, const t_grammar&grammar, void*user_data)
{
ctx->stacks.clear();
ctx->stacks.push_back({ 0,'#',0,nullptr });
ctx->vtid = 0;
ctx->user_data = user_data;
ctx->cl0 = &cluster;
ctx->gm0 = &grammar;
}
void print_stack(t_ctx*ctx)
{
for (const auto&unit : ctx->stacks)
printf("%3d ", unit.state);
printf("\n");
for (const auto&unit : ctx->stacks)
{
printf(" ");
print_sym(unit.sym);
printf(" ");
}
printf("\n ");
for (const auto&uint : ctx->stacks)
{
printf("%.1f ", *(float*)&uint.data);
}
printf("\n\n");
}
e_action push(t_ctx*ctx, int _vv)
{
print_stack(ctx);
///
ctx->vv = _vv;
const auto&action_map = ctx->cl0->at(ctx->stacks.back().state).action_map;
auto it = action_map.find(ctx->vv);
if (it == action_map.end())
{
if (ctx->gm0->other_sens)
{
ctx->gm0->other_sens(this);
it = action_map.find(ctx->vv);
}
}
ctx->node = nullptr;
if (it != action_map.end())
{
auto action = it->second;
if (action > -1)//移进
{
ctx->stacks.push_back({ action,ctx->vv,ctx->vtid + 1,ctx->_ret,ctx->node = new t_lrnode{ctx->vv,{ctx->vtid,ctx->vtid + 1},{}} });
ctx->vtid++;
return e_shift;
}
else//归约或接受
{
const auto&sen = ctx->gm0->sens.at(-action - 1);
ctx->sen_len = int(sen.rights.size());
if (true)
{
ctx->node = new t_lrnode{ action,this->range(-1),{} };
for (int i = 0; i < ctx->sen_len; i++)
{
auto&ut = ctx->stacks.at(ctx->stacks.size() - ctx->sen_len + i);
ctx->node->children.push_back(ut.node);
}
}
if (sen.sematic)
sen.sematic(this);
for (size_t j = 0; j < sen.rights.size(); j++)
{
ctx->stacks.pop_back();
}
if (action < -1)//归约
{
ctx->stacks.push_back({ ctx->cl0->at(ctx->stacks.back().state).action_map.at(sen.left),sen.left,ctx->vtid ,ctx->_ret,ctx->node });
return e_reduce;
}
else//接受
{
print_stack(ctx);
printf("接受\n");
return e_action::e_access;
}
}
}
else//出错
{
printf("出错");
return e_action::e_error;
}
}
public:
template<typename t_type>
t_type get(int id)const
{
return *(t_type*)&ctx.stacks.at(int(ctx.stacks.size()) - ctx.sen_len + id).data;
}
template<typename t_type>
void ret(t_type v)
{
ctx._ret = *(void**)&v;
}
void ref(int id)
{
ctx._ret = ctx.stacks.at(int(ctx.stacks.size()) - ctx.sen_len + id).data;
}
public:
t_vv get_vv()const
{
return ctx.vv;
}
void set_vv(t_vv _vv)
{
ctx.vv = _vv;
}
void*get_user_data()const
{
return ctx.user_data;
}
t_lrnode*get_node()const
{
return ctx.node;
}
t_sym symbol(int id)const
{
return ctx.stacks.at(int(ctx.stacks.size()) - ctx.sen_len + id).sym;
}
t_range range(int id)
{
if (id >= 0)
{
return {
ctx.stacks.at(int(ctx.stacks.size()) - ctx.sen_len + id - 1).pos,
ctx.stacks.at(int(ctx.stacks.size()) - ctx.sen_len + id).pos
};
}
else
{
return{
ctx.stacks.at(int(ctx.stacks.size()) - ctx.sen_len - 1).pos,
ctx.stacks.at(int(ctx.stacks.size()) - 1).pos
};
}
}
};