diff --git a/lib/modules/Parser.pmod/C.pmod b/lib/modules/Parser.pmod/C.pmod
new file mode 100644
index 0000000000000000000000000000000000000000..7b7766baa81502839ad7c46cc402c7b78da1e19b
--- /dev/null
+++ b/lib/modules/Parser.pmod/C.pmod
@@ -0,0 +1,265 @@
+mapping(string:string) global_groupings=(["}":"{",")":"(","]":"["]);
+
+array(string) split(string data)
+{
+  int start;
+  int line=1;
+  array(string) ret=({});
+  int pos;
+  data+="\0";
+
+  while(1)
+  {
+    int start=pos;
+
+//    werror("::::%c\n",data[pos]);
+
+    switch(data[pos])
+    {
+      case '\0':
+	return ret;
+
+      case '#':
+      {
+	pos=search(data,"\n",pos);
+	if(pos==-1)
+	  error("Failed to find end of preprocessor statement.\n");
+
+	while(data[pos-1]=='\\') pos=search(data,"\n",pos+1);
+	break;
+
+      case 'a'..'z':
+      case 'A'..'Z':
+      case '_':
+	while(1)
+	{
+	  switch(data[pos])
+	  {
+	    case 'a'..'z':
+	    case 'A'..'Z':
+	    case '0'..'9':
+	    case '_':
+	      pos++;
+	      continue;
+	  }
+	  break;
+	}
+	break;
+
+      case '.':
+	if(data[start..start+2]=="...")
+	{
+	  pos+=2;
+	  break;
+	}
+
+      case '0'..'9':
+	if(data[pos]=='0' && (data[pos+1]=='x' || data[pos+1]=='X'))
+	{
+	  pos+=2;
+	  while(1)
+	  {
+	    switch(data[pos])
+	    {
+	      case '0'..'9':
+	      case 'a'..'f':
+	      case 'A'..'F':
+		pos++;
+		continue;
+	    }
+	    break;
+	  }
+	  break;
+	}
+	while(data[pos]>='0' && data[pos]<='9') pos++;
+	if(data[pos]=='.')
+	{
+	  pos++;
+	  while(data[pos]>='0' && data[pos]<='9') pos++;
+	  if(data[pos]=='e' || data[pos]=='E')
+	  {
+	    pos++;
+	    while(data[pos]>='0' && data[pos]<='9') pos++;
+	  }
+	}
+	break;
+
+      default:
+	werror("Unknown token %s\n",data[pos..pos+5]);
+	exit(1);
+
+      case  '`':
+	while(data[pos]=='`') data[pos]++;
+
+      case '/':
+      case '{': case '}':
+      case '[': case ']':
+      case '(': case ')':
+      case ';':
+      case ',':
+      case '*': case '%':
+      case '?': case ':':
+      case '&': case '|': case '^':
+      case '!': case '~':
+      case '=':
+      case '+':
+      case '-':
+      case '<': case '>':
+	switch(data[pos..pos+1])
+	{
+	  case "//":
+	    pos=search(data,"\n",pos);
+	    break;
+
+	  case "/*":
+	    pos=search(data,"*/",pos);
+	    pos+=2;
+	    break;
+
+	  case "<<": case ">>":
+	    if(data[pos+2]=='=') pos++;
+	  case "==": case "<=": case ">=":
+	  case "*=": case "/=": case "%=":
+	  case "&=": case "|=": case "^=":
+	  case "+=": case "-=":
+	  case "++": case "--":
+	  case "&&": case "||":
+	  case "->":
+	    pos++;
+	  default:
+	    pos++;
+	}
+	break;
+
+
+      case ' ':
+      case '\n':
+      case '\r':
+      case '\t':
+	while(1)
+	{
+	  switch(data[pos])
+	  {
+	    case ' ':
+	    case '\n':
+	    case '\r':
+	    case '\t':
+	      pos++;
+	      continue;
+	  }
+	  break;
+	}
+	break;
+
+	case '\'':
+	  pos++;
+	  if(data[pos]=='\\') pos++;
+	  pos=search(data, "'", pos)+1;
+	  break;
+
+	case '"':
+	{
+	  int q,s;
+	  while(1)
+	  {
+	    q=search(data,"\"",pos+1);
+	    s=search(data,"\\",pos+1);
+	    if(q==-1) q=strlen(data)-1;
+	    if(s==-1) s=strlen(data)-1;
+
+	    if(q<s)
+	    {
+	      pos=q+1;
+	      break;
+	    }else{
+	      pos=s+1;
+	    }
+	  }
+	  break;
+	}
+      }
+    }
+
+    ret+=({ data[start..pos-1] });
+  }
+}
+
+
+class Token
+{
+  int line;
+  string text;
+  /* string file; */
+
+  void create(string t, int l)
+    {
+      text=t;
+      line=l;
+    }
+
+  string _sprintf(int how)
+    {
+      switch(how)
+      {
+	case 's':
+	  return text;
+	case 'O':
+	  return sprintf("Token(%O,%d)",text,line);
+      }
+    }
+
+  int `==(mixed foo)
+    {
+      return objectp(foo) ? foo->text : foo == text;
+    }
+
+  string `+(string ... s)
+    {
+      return predef::`+(text,@s);
+    }
+
+  string ``+(string ... s)
+    {
+      return predef::`+(@s,text);
+    }
+}
+
+array(Token) tokenize(array(string) s)
+{
+  array(Token) ret=allocate(sizeof(s));
+  int line=1;
+  for(int e=0;e<sizeof(s);e++)
+  {
+    ret[e]=Token(s[e],line);
+    line+=sizeof(s[e]/"\n")-1;
+  }
+  return ret;
+}
+
+
+array group(array(Token) tokens, void|mapping groupings)
+{
+  array(Token) ret=({});
+  if(!groupings) groupings=global_groupings;
+  foreach(tokens, Token token)
+  {
+    ret+=({ token });
+    if(string rev=groupings [ token->text ])
+    {
+      for(int q=sizeof(ret)-1;q>=0;q--)
+      {
+	if(ret[q] == rev)
+	{
+	  ret=ret[..q-1]+({ ret[q..] });
+	  break;
+	}
+      }
+    }
+  }
+  return ret;
+}
+
+string simple_reconstitute(array(Token) tokens)
+{
+  return Array.flatten(tokens->text) * "";
+}