Index: src/dgp.old/grammar.cc
===================================================================
--- src/dgp.old/grammar.cc	(revision e7de6cc88c605c4f810cbc852e843294b4b0e8ac)
+++ src/dgp.old/grammar.cc	(revision e7de6cc88c605c4f810cbc852e843294b4b0e8ac)
@@ -0,0 +1,181 @@
+
+#include <stdio.h>
+
+#include "grammar.hh"
+
+bool (*constraint[MAXCONSTRS])(int head, int dep);
+
+
+int chk_type(const char* s, int lineno) // SIDE EFECTS!
+{
+  if(Role::index(s)>0) return 1;
+
+  fprintf(stderr,"%8d: Invalid type '%s'. Line ignored.\n",lineno,s);
+  return 0;
+}
+
+int chk_cat(const char* s, int lineno)
+{
+  if(Cat::index(s)>0) return 1;
+
+  fprintf(stderr,"%8d: Invalid category '%s'. Line ignored.\n",lineno,s);
+  return 0;
+}
+
+void Grammar::add_category(const char* s)
+{
+  Cat::add(s);
+  if(Cat::count()>cats_sz)
+  {
+    cats_sz += 16;
+    connect.resize(cats_sz);
+    for(int i=0; i<cats_sz; ++i)
+      connect[i].resize(cats_sz);
+    obl.resize(cats_sz);
+  }
+}
+
+void Grammar::add_type(const char* s)
+{  
+  Role::add(s);
+  if(Role::count()>types_sz)
+  {
+    types_sz += 16;
+    lt.resize(types_sz);
+    gt.resize(types_sz);
+  }
+}
+
+void Grammar::add_flag(const char* s)
+{  
+  Flag::add(s);
+  if(Flag::count()>flags_sz)
+  {
+    flags_sz += 16;
+    pass.resize(flags_sz);
+  }
+}
+
+
+void Grammar::set_lt(Role s, Role t)
+{
+  lt[s].set(t);
+  gt[t].set(s);
+  if(s==0||(int)t==0)
+    return;
+  else
+  {
+    for(int i=0; i<Role::count(); ++i)
+      if(lt[i][s])
+	set_lt(i,t);
+    for(int i=0; i<Role::count(); ++i)
+      if(lt[t][i])
+	set_lt(s,i);
+  }
+}  
+
+
+void Grammar::compute_gt()
+{
+  for(Role s=0; s<Role::count(); ++s)
+    for(Role t=0; t<Role::count(); ++t)
+      if(lt[s][t])
+	gt[t].set(s);
+}
+
+
+bool Grammar::read(FILE* f)
+{
+  int lineno=0;
+  char line[MAXLINE]; // line has the structure: key [arg1 [arg2 [arg3]]]
+  char key[MAXLINE];
+  char arg1[MAXLINE];
+  char arg2[MAXLINE];
+  char arg3[MAXLINE];
+
+  while(fgets(line,MAXLINE,f))
+  {
+    lineno++;
+    int fields=sscanf(line,"%s %s %s %s",key,arg1,arg2,arg3);
+
+    if(fields<1 || key[0]=='#') continue; // skip empty lines and comments
+
+    if     (strcmp(key,"CAT")==0 && fields>=2)
+    {
+      add_category(arg1);
+    }
+    else if(strcmp(key,"ROLE")==0 && fields>=2)
+    {
+      add_type(arg1);
+    }
+    else if(strcmp(key,"SGL")==0 && fields>=2)
+    {  
+      if(chk_type(arg1,lineno))
+        set_sgl(arg1);
+    }
+    else if(strcmp(key,"LEFT")==0 && fields>=2)
+    { 
+      if(chk_type(arg1,lineno))
+        set_left(arg1);
+    }
+    else if(strcmp(key,"RIGHT")==0 && fields>=2)
+    {
+      if(chk_type(arg1,lineno))
+        set_right(arg1);
+    }
+    else if(strcmp(key,"REQ")==0 && fields>=3)
+    {
+      if(chk_cat(arg1,lineno) + chk_type(arg2,lineno) == 2)
+        set_obl(arg1,arg2);
+    }
+    else if(strcmp(key,"LINK")==0 && fields>=4)
+    { 
+      if(chk_cat(arg1,lineno) + chk_cat(arg2,lineno) + chk_type(arg3,lineno) == 3)    
+        set_connect(arg1,arg2,arg3);
+    }
+    // FLAG DECLARATION
+    else if(strcmp(key,"FLAG")==0 && fields>=2)
+    { 
+      add_flag(arg1);
+    }
+
+    else fprintf(stderr,"Invalid line %d. Ignored.\n", lineno);
+  }
+
+//   compute_gt();
+
+  return true;
+  
+}
+
+void Grammar::write(FILE* f)
+{
+  for(Cat i=1; i<Cat::count(); ++i)
+    fprintf(f,"CAT\t%s\n",i.str());
+
+  for(Role i=1; i<Role::count(); ++i)
+    fprintf(f,"ROLE\t%s\n",i.str());
+
+  for(Role i=1; i<Role::count(); ++i)
+    if(sgl.test(i)) fprintf(f,"SGL\t%s\n",i.str());
+  
+  for(Role i=1; i<Role::count(); ++i)
+    if(left.test(i)) fprintf(f,"LEFT\t%s\n",i.str());
+
+  for(Role i=1; i<Role::count(); ++i)
+    if(right.test(i)) fprintf(f,"RIGHT\t%s\n",i.str());
+
+  for(Cat c=1; c<Cat::count(); ++c)
+    for(Role r=1; r<Role::count(); ++r)
+      if(obl[c].test(r)) fprintf(f,"REQ\t%s\t%s\n",c.str(),r.str());
+  
+  for(Cat c=1; c<Cat::count(); ++c)
+    for(Cat d=1; d<Cat::count(); ++d)
+      for(Role t=1; t<Role::count(); ++t)
+	if(connect[c][d].count(t))
+          fprintf(f,"LINK\t%s\t%s\t%s\n",c.str(),d.str(),t.str());
+
+  for(Flag i=1; i<Flag::count(); ++i)
+    fprintf(f,"FLAG\t%s\n",i.str());
+}
+
