예제 #1
0
LangDiagram::LangDiagram(const Lang &lang)
 {
  ulen N=lang.getSyntCount();
  
  // start/stop
  {
   stop=N;
   
   start.reserve(N);
    
   lang.applyForSynts( [this] (Synt synt) { if( synt.isLang() ) start.append_fill(synt.getIndex()); } );
   
   start.shrink_extra();
  }
  
  // elements
  {
   elements.reserve(N);
   
   lang.applyForSynts( [this] (Synt synt) { elements.append_fill(synt); } );
  }

  // arrows
  {
   ArrowBuilder builder(N);
   const Element *base=elements.getPtr();
   
   lang.applyForSynts( [=,&builder] (Synt synt) { builder.add(synt,base); } );
   
   lang.applyForRules( [&builder] (Rule rule) { builder.add(rule); } );
   
   builder.finish(arrows);
  }
 }
예제 #2
0
void ExtLang::build(const Lang &lang,ulen map_atom_count)
 {
  original_atom_count=lang.getAtomCount();
  
  // atoms
  {
   ulen len=LenAdd(lang.getAtomCount(),lang.getRuleCount());
   
   auto atoms=createAtoms(len);
   
   ulen index=0;
   
   for(auto &atom : lang.getAtoms() )
     {
      atoms->index=index++;
      atoms->name=pool.dup(atom.name);
      
      atoms->map_index=atom.map_index;
      
      ++atoms;
     }
   
   for(auto &rule : lang.getRules() )
     {
      atoms->index=index++;
      atoms->name=pool.cat(StrLen("@",1),rule.ret->name,StrLen("::",2),rule.name);
      
      atoms->map_index=rule.map_index+map_atom_count;
      
      ++atoms;
     }
  }
  
  // synts
  {
   ulen len=lang.getSyntCount();
   
   auto synts=createSynts(len);
   
   for(auto &synt : lang.getSynts() )
     {
      synts->index=synt.index;
      synts->name=pool.dup(synt.name);
      
      synts->is_lang=synt.is_lang;
      
      synts->map_index=synt.map_index;
      
      synts->rules.len=synt.rules.len;
     
      ++synts;
     }
  }
  
  // rules
  {
   ulen len=lang.getRuleCount();
   
   auto rules=createRules(len);
   
   auto atoms=getAtoms();
   auto synts=getSynts();
   
   ulen delta=original_atom_count;
   
   for(auto &rule : lang.getRules() )
     {
      rules->index=rule.index;
      rules->name=pool.dup(rule.name);
      
      rules->map_index=rule.map_index;
      
      rules->ret=&(synts[rule.ret->index]);
      
      auto args=createElements(*rules,LenAdd(rule.args.len,1));
      
      for(auto element : rule.args )
        {
         element.apply( [=] (const AtomDesc *atom) { args->ptr=&(atoms[atom->index]); } , 
                        [=] (const SyntDesc *synt) { args->ptr=&(synts[synt->index]); } );
        
         ++args;
        }
      
      args->ptr=&(atoms[rule.index+delta]);
     
      ++rules;
     }
  }
  
  // synts.rules
  {
   auto synts=this->synts;
   
   auto *ptr=rules.ptr;
   
   for(; +synts ;++synts)
     {
      ulen len=synts->rules.len;
      
      synts->rules.ptr=ptr;
      
      ptr+=len;
     }
  }
  
  pool.shrink_extra();
 }