LR1語法分析C++實現:二、分析器的實現

轉載請註明出處: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
   };
  }
 }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章