diff --git a/rngparser.c b/rngparser.c
new file mode 100644
index 0000000..67a25b7
--- /dev/null
+++ b/rngparser.c
@@ -0,0 +1,1571 @@
+/**
+ * rngparser.c: parser for the Relax-NG compact syntax.
+ *
+ * See Copyright for the status of this software.
+ *
+ * Daniel Veillard <veillard@redhat.com>
+ */
+
+#include <string.h>
+
+#include <libxml/parser.h>
+#include <libxml/parserInternals.h>
+#include <libxml/relaxng.h>
+#include <libxml/dict.h>
+
+#define TODO 								\
+    xmlGenericError(xmlGenericErrorContext,				\
+	    "Unimplemented block at %s:%d\n",				\
+            __FILE__, __LINE__);
+
+#define MAX_TOKEN 10
+
+typedef enum {
+    CRNG_NONE = 0,
+    CRNG_OP = 1,
+    CRNG_KEYWORD,
+    CRNG_IDENTIFIER,
+    CRNG_LITERAL_SEGMENT,
+    CRNG_CNAME,
+    CRNG_QNAME,
+    CRNG_NSNAME,
+    CRNG_DOCUMENTATION
+} xmlCRNGTokType;
+
+typedef enum {
+    CRNG_OKAY = 0,
+    CRNG_MEMORY_ERROR,
+    CRNG_INVALID_CHAR_ERROR,
+    CRNG_END_ERROR,
+    CRNG_ENCODING_ERROR
+} xmlCRNGError;
+
+typedef enum {
+    XML_CRNG_ERROR = -1,
+    XML_CRNG_OK = 0,
+    XML_CRNG_EOF = 1
+} xmlCRelaxNGParserState;
+
+typedef struct _token _token;
+typedef _token *tokenPtr;
+struct _token {
+    xmlCRNGTokType toktype;
+    int toklen;
+    const xmlChar *token;
+    const xmlChar *prefix;
+};
+
+typedef struct _xmlCRelaxNGParserCtxt xmlCRelaxNGParserCtxt;
+typedef xmlCRelaxNGParserCtxt *xmlCRelaxNGParserCtxtPtr;
+struct _xmlCRelaxNGParserCtxt {
+    void *userData;			/* user specific data block */
+    xmlRelaxNGValidityErrorFunc error;	/* the callback in case of errors */
+    xmlRelaxNGValidityWarningFunc warning;/* the callback in case of warning */
+    xmlRelaxNGValidErr err;
+
+    const xmlChar *compact;
+    const xmlChar *end;
+    const xmlChar *cur;
+    int isElem;
+    int lineno;
+    const xmlChar *linestart;
+    const char *filename;
+
+    int  nbTokens;
+    int  firstToken;
+    _token tokens[MAX_TOKEN];
+    int  totalToken;
+
+    xmlCRelaxNGParserState state;
+
+    int            nbErrors;
+
+    xmlDocPtr      res;			/* the result */
+    xmlNodePtr     ins;			/* the current insertion node */
+
+    xmlNsPtr       nsDef;
+    tokenPtr token;
+
+    xmlHashTablePtr namespaces;
+    xmlHashTablePtr datatypes;
+
+    /*
+     * dictionnary and keywords
+     */
+    xmlDictPtr     dict;
+    const xmlChar *key_attribute;
+    const xmlChar *key_default;
+    const xmlChar *key_datatypes;
+    const xmlChar *key_div;
+    const xmlChar *key_element;
+    const xmlChar *key_empty;
+    const xmlChar *key_external;
+    const xmlChar *key_grammar;
+    const xmlChar *key_include;
+    const xmlChar *key_inherit;
+    const xmlChar *key_list;
+    const xmlChar *key_mixed;
+    const xmlChar *key_namespace;
+    const xmlChar *key_notAllowed;
+    const xmlChar *key_parent;
+    const xmlChar *key_start;
+    const xmlChar *key_string;
+    const xmlChar *key_text;
+    const xmlChar *key_token;
+    const xmlChar *key_equal;
+    const xmlChar *key_orequal;
+    const xmlChar *key_andequal;
+    const xmlChar *key_combine;
+    const xmlChar *key_or;
+    const xmlChar *key_comma;
+    const xmlChar *key_and;
+    const xmlChar *key_choice;
+    const xmlChar *key_group;
+    const xmlChar *key_interleave;
+    const xmlChar *key_ref;
+    const xmlChar *key_define;
+
+    /* results */
+    xmlDocPtr doc;	/* the resulting doc */
+    xmlNodePtr insert;	/* the insertion point */
+    xmlAttrPtr attrs;   /* pending attributes */
+};
+
+static const xmlChar *xmlCRelaxNGInherit = BAD_CAST "Inherit string";
+static const xmlChar *xmlCRelaxNGDefault = BAD_CAST "Default string";
+
+#define CUR_CHAR(l) xmlXPathCurrentChar(ctxt, &l)
+/**
+ * IS_BLANK:
+ * @c:  an UNICODE value (int)
+ *
+ * Macro to check the following production in the XML spec:
+ *
+ * [3] S ::= (#x20 | #x9 | #xD | #xA)+
+ */
+#ifndef IS_BLANK
+#define IS_BLANK(c) (((c) == 0x20) || ((c) == 0x09) || ((c) == 0xA) ||	\
+                     ((c) == 0x0D))
+#endif
+#define IS_SEPARATOR(c) (((c) == 0x20) || ((c) == 0x09) || ((c) == 0xA) || \
+                     ((c) == 0x0D) || (c == '#'))
+
+#define CRNG_ERROR0(X)							\
+    { xmlCRNGErr(ctxt, X, NULL); return(0); }
+#define CRNG_ERROR(X)							\
+    { xmlCRNGErr(ctxt, X, NULL); }
+
+#define CRNG_MEM_ERROR0()						\
+    { xmlCRNGErr(ctxt, CRNG_MEMORY_ERROR, NULL); return(0); }
+#define CRNG_MEM_ERROR()						\
+    { xmlCRNGErr(ctxt, CRNG_MEMORY_ERROR, NULL); }
+
+#define ERROR(str) xmlCRNGErr(ctxt, 0, str);
+
+static void
+xmlCRNGErr(xmlCRelaxNGParserCtxtPtr ctxt, int err_no, const char *err_msg) {
+    const xmlChar *cur;
+    xmlChar buffer[150];
+    int i, l;
+
+    if (ctxt != NULL) {
+        if (ctxt->filename != NULL)
+	    fprintf(stderr, "%s:%d ", ctxt->filename, ctxt->lineno);
+    }
+    if (err_msg != NULL) {
+	fprintf(stderr, "error: %s\n", err_msg);
+    } else if (err_no != 0)
+	fprintf(stderr, "error %d\n", err_no);
+    cur = ctxt->cur;
+    while ((*cur != '\n') && (*cur != '\r') && (ctxt->cur - cur < 80)) cur--;
+    l = ctxt->cur - cur;
+    cur++;
+    for (i = 0; i < 100;i++) {
+        if ((*cur == '\n') || (*cur == '\r')) break;
+        buffer[i] = *cur++;
+    }
+    buffer[i] = 0;
+    fprintf(stderr, "%s\n", buffer);
+    for (i = 0; i < l;i++) buffer[i] = ' ';
+    buffer[i++] = '^';
+    buffer[i++] = 0;
+    fprintf(stderr, "%s\n", buffer);
+}
+
+/**
+ * IS_OP
+ * @c:  an UNICODE value (int)
+ *
+ * Macro to check for operator value
+ */
+#ifndef IS_OP
+#define IS_OP(c) (((c) == ',') || ((c) == '&') || ((c) == '|') ||	\
+		  ((c) == '?') || ((c) == '-') || ((c) == '*') ||	\
+		  ((c) == '{') || ((c) == '}') || ((c) == '(') ||	\
+		  ((c) == ')') || ((c) == '+') || ((c) == '=') ||	\
+		  ((c) == ':'))
+#endif
+
+static int
+xmlCRNGIsKeyword(xmlCRelaxNGParserCtxtPtr ctxt, const xmlChar *str) {
+    if ((str == ctxt->key_attribute) ||
+        (str == ctxt->key_default) ||
+        (str == ctxt->key_datatypes) ||
+        (str == ctxt->key_div) ||
+        (str == ctxt->key_element) ||
+        (str == ctxt->key_empty) ||
+        (str == ctxt->key_external) ||
+        (str == ctxt->key_grammar) ||
+        (str == ctxt->key_include) ||
+        (str == ctxt->key_inherit) ||
+        (str == ctxt->key_list) ||
+        (str == ctxt->key_mixed) ||
+        (str == ctxt->key_namespace) ||
+        (str == ctxt->key_notAllowed) ||
+        (str == ctxt->key_parent) ||
+        (str == ctxt->key_start) ||
+        (str == ctxt->key_string) ||
+        (str == ctxt->key_text) ||
+        (str == ctxt->key_token))
+	return(1);
+    return(0);
+
+}
+
+/*
+ * xmlCRNGNextToken:
+ * ctxt:  a compact RNG parser context
+ *
+ * Scan the schema to get the next token
+ *
+ * Return 0 if success and -1 in case of error
+ */
+
+static int
+xmlCRNGNextToken(xmlCRelaxNGParserCtxtPtr ctxt) {
+    const xmlChar *cur;
+    tokenPtr token;
+
+    if (ctxt == NULL) return(-1);
+    if (ctxt->nbTokens >= MAX_TOKEN) return(-1);
+    token = &(ctxt->tokens[(ctxt->firstToken + ctxt->nbTokens) % MAX_TOKEN]);
+    token->toktype = CRNG_NONE;
+
+    if (ctxt->cur == NULL) {
+        ctxt->cur = ctxt->compact;
+    }
+retry:
+    if (ctxt->cur >= ctxt->end) {
+	ctxt->state = XML_CRNG_EOF;
+	return(-1);
+    }
+    while ((ctxt->cur < ctxt->end) &&
+           (IS_BLANK(*ctxt->cur))) ctxt->cur++;
+    if (ctxt->cur >= ctxt->end) {
+	ctxt->state = XML_CRNG_EOF;
+	return(-1);
+    }
+    if (*ctxt->cur == '#') {
+        cur = ctxt->cur;
+	cur++;
+	while ((cur < ctxt->end) && (*cur != '\n') && (*cur != '\r'))
+	    cur++;
+        ctxt->cur = cur;
+	goto retry;
+    } else if (*ctxt->cur == '"') {
+        /* string, check for '"""' */
+	ctxt->cur++;
+	if (ctxt->cur >= ctxt->end) goto eof;
+	cur = ctxt->cur;
+        if ((ctxt->end - ctxt->end > 2) && 
+	    (*cur == '"') && (cur[1] == '"')) {
+	    TODO
+	} else {
+	    while ((cur < ctxt->end) && (*cur != '"')) cur++;
+	    if (cur >= ctxt->end) goto eof;
+	    token->toklen = cur - ctxt->cur;
+	    token->token = xmlDictLookup(ctxt->dict, ctxt->cur, token->toklen);
+	    token->toktype = CRNG_LITERAL_SEGMENT;
+	    token->prefix = NULL;
+	    cur++;
+	    ctxt->cur = cur;
+	}
+    } else if (*ctxt->cur == '\'') {
+        /* string, check for "'''" */
+	TODO
+    } else if ((IS_OP(*ctxt->cur)) || (*ctxt->cur == ':')) {
+        cur = ctxt->cur;
+	cur++;
+	if ((cur < ctxt->end) &&
+	    (((*cur == '=') &&
+	      ((*ctxt->cur == '|') || (*ctxt->cur == '&'))) ||
+	     ((*cur == '*') && (*ctxt->cur == ':')))) {
+	    token->toklen = 2;
+	} else {
+	    token->toklen = 1;
+	}
+	token->token = xmlDictLookup(ctxt->dict, ctxt->cur, token->toklen);
+	token->toktype = CRNG_OP;
+	token->prefix = NULL;
+	ctxt->cur += token->toklen;
+    } else {
+        int escape = 0;
+
+        cur = ctxt->cur;
+        if (*cur == '\\') {
+	    escape = 1;
+	    cur++;
+	    ctxt->cur++;
+	}
+	while ((cur < ctxt->end) &&
+	       (!(IS_SEPARATOR(*cur))) && (!(IS_OP(*cur)))) cur++;
+
+	token->toklen = cur - ctxt->cur;
+	token->token = xmlDictLookup(ctxt->dict, ctxt->cur, token->toklen);
+	token->prefix = NULL;
+	ctxt->cur = cur;
+	if ((escape == 0) && (xmlCRNGIsKeyword(ctxt, token->token)))
+	    token->toktype = CRNG_KEYWORD;
+	else {
+	    token->toktype = CRNG_IDENTIFIER;
+	}
+	if (*ctxt->cur == ':') {
+	    ctxt->cur++;
+	    if (*ctxt->cur == '*') {
+		ctxt->cur++;
+		token->toktype = CRNG_NSNAME;
+	    } else {
+	        cur = ctxt->cur;
+		while ((cur < ctxt->end) &&
+		       (!(IS_SEPARATOR(*cur))) && (!(IS_OP(*cur)))) cur++;
+		token->prefix = token->token;
+		token->toklen = cur - ctxt->cur;
+		token->token = xmlDictLookup(ctxt->dict, ctxt->cur,
+		                             token->toklen);
+		ctxt->cur = cur;
+		if (xmlValidateNCName(token->token, 0) == 0)
+		    token->toktype = CRNG_QNAME;
+		else {
+		    TODO /* sounds like an error ! */
+		    token->toktype = CRNG_IDENTIFIER;
+		}
+	    }
+	}
+    }
+    ctxt->nbTokens++;
+    return(0);
+eof:
+    ctxt->state = XML_CRNG_EOF;
+    CRNG_ERROR(CRNG_END_ERROR);
+    return(-1);
+}
+
+/**
+ * xmlParseCRNGGetToken:
+ * @ctxt: a compact RNG parser context
+ * @no: the number of the token from 1 for the first one
+ *      and 2, 3 ... for read-ahead
+ *
+ * Token reading interface
+ *
+ * returns a pointer to the new token, or NULL in case of error or EOF
+ */
+static tokenPtr
+xmlParseCRNGGetToken(xmlCRelaxNGParserCtxtPtr ctxt, int no) {
+    tokenPtr ret;
+    int res;
+
+    if ((no <= 0) || (no >= MAX_TOKEN)) return(NULL);
+    no--;
+    while (ctxt->nbTokens <= no) {
+        res = xmlCRNGNextToken(ctxt);
+	if (res < 0)
+	    return(NULL);
+    }
+    ret = &(ctxt->tokens[(ctxt->firstToken + no) % MAX_TOKEN]);
+    return(ret);
+}
+
+/**
+ * xmlParseCRNGDropTokens:
+ * @ctxt: a compact RNG parser context
+ * @nr: the number of token marked as read
+ * 
+ * mark a number of token as read and consumed.
+ *
+ * Returns -1 in case of error and 0 otherwise
+ */
+static int
+xmlParseCRNGDropTokens(xmlCRelaxNGParserCtxtPtr ctxt, int nr) {
+    if ((nr <= 0) || (nr >= MAX_TOKEN)) return(-1);
+    while ((ctxt->nbTokens >0) && (nr > 0)) {
+        ctxt->firstToken++;
+	nr--;
+	ctxt->nbTokens--;
+	ctxt->totalToken++;
+	if (ctxt->totalToken == 384) 
+	    fprintf(stderr, "found\n");
+    }
+    ctxt->firstToken = ctxt->firstToken % MAX_TOKEN;
+    return(0);
+}
+
+static void
+xmlParseCRNGTokenize(xmlCRelaxNGParserCtxtPtr ctxt) {
+    tokenPtr token;
+    
+    token = xmlParseCRNGGetToken(ctxt, 1);
+    while (token != NULL) {
+        switch (token->toktype) {
+            case CRNG_NONE: printf("none"); break;
+            case CRNG_OP: printf("op"); break;
+            case CRNG_KEYWORD: printf("keyword"); break;
+            case CRNG_IDENTIFIER: printf("identifier"); break;
+            case CRNG_LITERAL_SEGMENT: printf("literal"); break;
+            case CRNG_CNAME: printf("cname"); break;
+            case CRNG_QNAME: printf("qname"); break;
+            case CRNG_NSNAME: printf("nsname"); break;
+            case CRNG_DOCUMENTATION: printf("doc"); break;
+	}
+        printf(":%s\n", token->token);
+	xmlParseCRNGDropTokens(ctxt, 1);
+	token = xmlParseCRNGGetToken(ctxt, 1);
+    }
+}
+
+/**
+ * xmlParseCRNG_attribute:
+ * @ctxt: a compact RNG parser context
+ * @name: the attribute name
+ * @ns: the attribute namespace
+ * @value: the attribute value
+ *
+ * implements attribute of the RELAX NG Compact Syntax Appendix A
+ *
+ * Returns 0 in case of success and -1 in case of error
+ */
+static int
+xmlParseCRNG_attribute(xmlCRelaxNGParserCtxtPtr ctxt, 
+                       const xmlChar *name,
+                       xmlNsPtr ns,
+		       const xmlChar *value)
+{
+    xmlAttrPtr attr;
+
+    attr = xmlNewNsPropEatName(NULL, ns, (xmlChar *) name, value);
+    if (attr == NULL) CRNG_MEM_ERROR0();
+    attr->next = ctxt->attrs;
+    if (ctxt->attrs != NULL)
+        ctxt->attrs->prev = attr;
+    ctxt->attrs = attr;
+    return(0);
+}
+
+/**
+ * xmlParseCRNG_bindPrefix:
+ * @ctxt: a compact RNG parser context
+ * @prefix: the namespace prefix or NULL
+ * @namespace: the namespace name
+ *
+ * implements bindPrefix of the RELAX NG Compact Syntax Appendix A
+ *
+ * Returns 0 in case of success and -1 in case of error
+ */
+static int
+xmlParseCRNG_bindPrefix(xmlCRelaxNGParserCtxtPtr ctxt, 
+                        const xmlChar *prefix,
+			const xmlChar *namespace)
+{
+    int ret;
+
+    if ((prefix != NULL) && (xmlStrEqual(prefix, BAD_CAST "xml"))  &&
+        (!xmlStrEqual(namespace, XML_XML_NAMESPACE))) {
+	ERROR("The \"xml\" prefix must be bound to \"http://www.w3.org/XML/1998/namespace\"");
+	return(-1);
+    } else if ((xmlStrEqual(namespace, XML_XML_NAMESPACE)) &&
+               (!xmlStrEqual(prefix, BAD_CAST "xml"))) {
+	ERROR("The \"http://www.w3.org/XML/1998/namespace\" name must be bound to \"xml\" prefix");
+	return(-1);
+    }
+    if (ctxt->namespaces == NULL)
+        ctxt->namespaces = xmlHashCreate(10);
+    if (ctxt->namespaces == NULL) {
+        ERROR("Failed to create namespace hash table");
+	return(-1);
+    }
+    if (prefix == NULL)
+        ret = xmlHashAddEntry(ctxt->namespaces, xmlCRelaxNGDefault,
+	                      (void *) namespace);
+    else
+        ret = xmlHashAddEntry(ctxt->namespaces, prefix, 
+	                      (void *) namespace);
+    if (ret < 0) {
+        if (prefix == NULL) {
+	    ERROR("Redefinition of default namespace");
+	} else {
+	    ERROR("Redefinition of namespace");
+	}
+	return(-1);
+    }
+
+    return(0);
+}
+
+/**
+ * xmlParseCRNG_bindDatatypePrefix:
+ * @ctxt: a compact RNG parser context
+ * @prefix: the datatype prefix
+ * @namespace: the datatype identifier
+ *
+ * implements bindDatatypePrefix of the RELAX NG Compact Syntax Appendix A
+ *
+ * Returns 0 in case of success and -1 in case of error
+ */
+static int
+xmlParseCRNG_bindDatatypePrefix(xmlCRelaxNGParserCtxtPtr ctxt ATTRIBUTE_UNUSED, 
+                                const xmlChar *prefix,
+			        const xmlChar *namespace)
+{
+    int ret;
+
+    if ((prefix != NULL) && (xmlStrEqual(prefix, BAD_CAST "xsd"))  &&
+        (!xmlStrEqual(namespace, 
+		  BAD_CAST "http://www.w3.org/2001/XMLSchema-datatypes"))) {
+	ERROR("The \"xsd\" prefix must be bound to \"http://www.w3.org/2001/XMLSchema-datatypes\"");
+	return(-1);
+    }
+    if (ctxt->datatypes == NULL)
+        ctxt->datatypes = xmlHashCreate(10);
+    if (ctxt->datatypes == NULL) {
+        ERROR("Failed to create namespace hash table");
+	return(-1);
+    }
+    ret = xmlHashAddEntry(ctxt->datatypes, prefix, 
+                          (void *) namespace);
+    if (ret < 0) {
+	ERROR("Redefinition of datatype");
+	return(-1);
+    }
+    return(0);
+}
+
+/**
+ * xmlParseCRNG_lookupPrefix:
+ * @ctxt: a compact RNG parser context
+ * @prefix: the namespace prefix or NULL
+ *
+ * implements lookupPrefix of the RELAX NG Compact Syntax Appendix A
+ *
+ * Returns the prefix in case of success or NULL in case of error
+ */
+static const xmlChar *
+xmlParseCRNG_lookupPrefix(xmlCRelaxNGParserCtxtPtr ctxt ATTRIBUTE_UNUSED, 
+                        const xmlChar *prefix)
+{
+    const xmlChar *ret;
+
+    if (prefix == NULL)
+        ret = xmlHashLookup(ctxt->namespaces, xmlCRelaxNGDefault);
+    else
+        ret = xmlHashLookup(ctxt->namespaces, prefix);
+    return(ret);
+}
+
+/**
+ * xmlParseCRNG_lookupDatatypePrefix:
+ * @ctxt: a compact RNG parser context
+ * @prefix: the namespace prefix or NULL
+ *
+ * implements lookupDatatypePrefix of the RELAX NG Compact Syntax Appendix A
+ *
+ * Returns the prefix in case of success or NULL in case of error
+ */
+static const xmlChar *
+xmlParseCRNG_lookupDatatypePrefix(xmlCRelaxNGParserCtxtPtr ctxt ATTRIBUTE_UNUSED, 
+                        const xmlChar *prefix)
+{
+    const xmlChar *ret;
+    ret = xmlHashLookup(ctxt->datatypes, prefix);
+    return(ret);
+}
+
+/**
+ * xmlParseCRNG_datatypeAttributes:
+ * @ctxt: a compact RNG parser context
+ * @prefix: the namespace prefix or NULL
+ *
+ * implements lookupPrefix of the RELAX NG Compact Syntax Appendix A
+ *
+ * Returns the prefix in case of success or NULL in case of error
+ */
+static xmlAttrPtr
+xmlParseCRNG_datatypeAttributes(xmlCRelaxNGParserCtxtPtr ctxt ATTRIBUTE_UNUSED, 
+                        const xmlChar *library, const xmlChar *type)
+{
+    xmlAttrPtr lib, typ;
+
+    lib = xmlNewNsProp(NULL, NULL, BAD_CAST "datatypeLibrary", library);
+    if (lib == NULL) {
+        CRNG_MEM_ERROR();
+	return(NULL);
+    }
+    typ = xmlNewNsProp(NULL, NULL, BAD_CAST "type", type);
+    if (typ == NULL) {
+        CRNG_MEM_ERROR();
+	return(lib);
+    }
+    lib->next = typ;
+
+    return(lib);
+}
+
+/**
+ * xmlParseCRNG_XXX:
+ * @ctxt: a compact RNG parser context
+ *
+ * Parse XXX of the RELAX NG Compact Syntax Appendix A
+ *
+ * Returns 0 in case of success and -1 in case of error
+ */
+static int
+xmlParseCRNG_XXX(xmlCRelaxNGParserCtxtPtr ctxt ATTRIBUTE_UNUSED)
+{
+    return(0);
+}
+
+static int xmlParseCRNG_pattern(xmlCRelaxNGParserCtxtPtr ctxt);
+static int xmlParseCRNG_nameClass(xmlCRelaxNGParserCtxtPtr ctxt);
+
+/**
+ * xmlParseCRNG_params:
+ * @ctxt: a compact RNG parser context
+ *
+ * Parse params of the RELAX NG Compact Syntax Appendix A
+ *
+ * Returns 0 in case of success and -1 in case of error
+ */
+static int
+xmlParseCRNG_params(xmlCRelaxNGParserCtxtPtr ctxt ATTRIBUTE_UNUSED)
+{
+    TODO
+    return(0);
+}
+
+/**
+ * xmlParseCRNG_exceptNameClass:
+ * @ctxt: a compact RNG parser context
+ *
+ * Parse exceptNameClass of the RELAX NG Compact Syntax Appendix A
+ *
+ * Returns 0 in case of success and -1 in case of error
+ */
+static int
+xmlParseCRNG_exceptNameClass(xmlCRelaxNGParserCtxtPtr ctxt ATTRIBUTE_UNUSED)
+{
+    tokenPtr token;
+    xmlNodePtr insert = ctxt->insert, cur;
+
+    token = xmlParseCRNGGetToken(ctxt, 1);
+    if ((token->toktype == CRNG_OP) &&
+        (token->token[0] == '-') && (token->token[1] == 0)) {
+	xmlParseCRNGDropTokens(ctxt, 1);
+	cur = xmlNewNode(NULL, BAD_CAST "except");
+	if (cur == NULL) CRNG_MEM_ERROR0();
+	if (ctxt->insert != NULL)
+	    xmlAddChild(ctxt->insert, cur);
+	ctxt->insert = cur;
+	xmlParseCRNG_nameClass(ctxt);
+    }
+    ctxt->insert = insert;
+    return(0);
+}
+
+/**
+ * xmlParseCRNG_innerNameClass:
+ * @ctxt: a compact RNG parser context
+ *
+ * Parse innerNameClass of the RELAX NG Compact Syntax Appendix A
+ *
+ * Returns 0 in case of success and -1 in case of error
+ */
+static int
+xmlParseCRNG_innerNameClass(xmlCRelaxNGParserCtxtPtr ctxt)
+{
+    tokenPtr token;
+    xmlNodePtr cur;
+
+    token = xmlParseCRNGGetToken(ctxt, 1);
+    if (token->toktype == CRNG_OP) {
+        if ((token->token[0] == '(') && (token->token[1] == 0)) {
+	    xmlParseCRNGDropTokens(ctxt, 1);
+	    xmlParseCRNG_nameClass(ctxt);
+	    token = xmlParseCRNGGetToken(ctxt, 1);
+	    if ((token->toktype != CRNG_OP) ||
+	        (token->token[0] != ')') || (token->token[1] != 0)) {
+		ERROR("Expecting \")\" here");
+	    }
+	    xmlParseCRNGDropTokens(ctxt, 1);
+	} else if ((token->token[0] == '*') && (token->token[1] == 0)) {
+	    xmlParseCRNGDropTokens(ctxt, 1);
+	    cur = xmlNewNode(NULL, BAD_CAST "anyName");
+	    if (cur == NULL) CRNG_MEM_ERROR0();
+	    if (ctxt->insert != NULL)
+		xmlAddChild(ctxt->insert, cur);
+	    ctxt->insert = cur;
+	    xmlParseCRNG_exceptNameClass(ctxt);
+	} else {
+	    TODO
+	}
+    } else if ((token->toktype == CRNG_IDENTIFIER) ||
+               (token->toktype == CRNG_KEYWORD)) {
+	cur = xmlNewNode(NULL, BAD_CAST "name");
+	if (cur == NULL) CRNG_MEM_ERROR0();
+	if (ctxt->isElem) {
+	    xmlSetProp(cur, BAD_CAST "ns",
+	               xmlParseCRNG_lookupPrefix(ctxt, NULL)); 
+	} else {
+	    xmlSetProp(cur, BAD_CAST "ns", BAD_CAST ""); 
+	}
+	xmlNodeAddContent(cur, token->token);
+	if (ctxt->insert != NULL)
+	    xmlAddChild(ctxt->insert, cur);
+	ctxt->insert = cur;
+	xmlParseCRNGDropTokens(ctxt, 1);
+    } else if (token->toktype == CRNG_CNAME) {
+        TODO
+    } else if (token->toktype == CRNG_NSNAME) {
+	cur = xmlNewNode(NULL, BAD_CAST "nsName");
+	if (cur == NULL) CRNG_MEM_ERROR0();
+        xmlSetProp(cur, BAD_CAST "ns",
+	           xmlParseCRNG_lookupPrefix(ctxt, token->token)); 
+	if (ctxt->insert != NULL)
+	    xmlAddChild(ctxt->insert, cur);
+	ctxt->insert = cur;
+	xmlParseCRNGDropTokens(ctxt, 1);
+	xmlParseCRNG_exceptNameClass(ctxt);
+    } else {
+        TODO /* probably an error */
+    }
+
+    return(0);
+}
+
+/**
+ * xmlParseCRNG_nameClass:
+ * @ctxt: a compact RNG parser context
+ *
+ * Parse nameClass of the RELAX NG Compact Syntax Appendix A
+ *
+ * Returns 0 in case of success and -1 in case of error
+ */
+static int
+xmlParseCRNG_nameClass(xmlCRelaxNGParserCtxtPtr ctxt)
+{
+    tokenPtr token;
+    xmlNodePtr insert = ctxt->insert, last, choice;
+
+    ctxt->insert = NULL;
+    xmlParseCRNG_innerNameClass(ctxt);
+    last = ctxt->insert;
+    token = xmlParseCRNGGetToken(ctxt, 1);
+    while ((token->toktype == CRNG_OP) &&
+        (token->token[0] == '|') && (token->token[1] == 0)) {
+	choice = xmlNewNodeEatName(NULL, (xmlChar *) ctxt->key_choice);
+	xmlParseCRNGDropTokens(ctxt, 1);
+	if (choice == NULL) CRNG_MEM_ERROR0();
+	ctxt->insert = NULL;
+	xmlParseCRNG_innerNameClass(ctxt);
+	xmlAddChild(choice, last);
+	xmlAddChild(choice, ctxt->insert);
+	last = choice;
+	token = xmlParseCRNGGetToken(ctxt, 1);
+    }
+    xmlAddChild(insert, last);
+
+    ctxt->insert = insert;
+    return(0);
+}
+
+/**
+ * xmlParseCRNG_patternBlock:
+ * @ctxt: a compact RNG parser context
+ *
+ * Parse a pattern block of the RELAX NG Compact Syntax Appendix A
+ *
+ * Returns 0 in case of success and -1 in case of error
+ */
+static int
+xmlParseCRNG_patternBlock(xmlCRelaxNGParserCtxtPtr ctxt)
+{
+    tokenPtr token;
+
+    token = xmlParseCRNGGetToken(ctxt, 1);
+    if ((token->toktype != CRNG_OP) ||
+	(token->token[0] != '{') || (token->token[1] != 0)) {
+	ERROR("Expecting \"{\" here");
+    }
+    xmlParseCRNGDropTokens(ctxt, 1);
+    xmlParseCRNG_pattern(ctxt);
+    token = xmlParseCRNGGetToken(ctxt, 1);
+    if ((token->toktype != CRNG_OP) ||
+	(token->token[0] != '}') || (token->token[1] != 0)) {
+	ERROR("Expecting \"}\" here");
+    }
+    xmlParseCRNGDropTokens(ctxt, 1);
+    return(0);
+}
+
+/**
+ * xmlParseCRNG_datatype:
+ * @ctxt: a compact RNG parser context
+ *
+ * Parse datatype of the RELAX NG Compact Syntax Appendix A
+ *
+ * Returns 0 in case of success and -1 in case of error
+ */
+static int
+xmlParseCRNG_datatype(xmlCRelaxNGParserCtxtPtr ctxt ATTRIBUTE_UNUSED)
+{
+    tokenPtr token;
+    xmlAttrPtr attrs = NULL;
+
+    token = xmlParseCRNGGetToken(ctxt, 1);
+    if (token->toktype == CRNG_KEYWORD) {
+	if (token->token == ctxt->key_string) {
+	    attrs = xmlParseCRNG_datatypeAttributes(ctxt, BAD_CAST "", 
+	                                            token->token);
+	    xmlParseCRNGDropTokens(ctxt, 1);
+	} else if (token->token == ctxt->key_token) {
+	    attrs = xmlParseCRNG_datatypeAttributes(ctxt, BAD_CAST "", 
+	                                            token->token);
+	    xmlParseCRNGDropTokens(ctxt, 1);
+	} else {
+	    TODO /* probably an error */
+	}
+    } else if (token->toktype == CRNG_LITERAL_SEGMENT) {
+	ctxt->insert = xmlNewNode(NULL, BAD_CAST "value");
+	xmlParseCRNGDropTokens(ctxt, 1);
+	if (ctxt->insert == NULL) CRNG_MEM_ERROR0();
+	xmlNodeAddContent(ctxt->insert, token->token);
+    } else if (token->toktype == CRNG_QNAME) {
+	attrs = xmlParseCRNG_datatypeAttributes(ctxt, 
+	            xmlParseCRNG_lookupDatatypePrefix(ctxt, token->prefix),
+		    token->token);
+    } else {
+        TODO
+    }
+    if (attrs != NULL) {
+	token = xmlParseCRNGGetToken(ctxt, 1);
+	if (token->toktype == CRNG_LITERAL_SEGMENT) {
+	    ctxt->insert = xmlNewNode(NULL, BAD_CAST "value");
+	    xmlParseCRNGDropTokens(ctxt, 1);
+	    if (ctxt->insert == NULL) {
+	        xmlFreePropList(attrs);
+		CRNG_MEM_ERROR0();
+	    }
+	    ctxt->insert->properties = attrs;
+	    xmlNodeAddContent(ctxt->insert, token->token);
+	} else if ((token->toktype == CRNG_OP) &&
+	           (token->token[0] == '{') && (token->token[0] == 0)) {
+	    ctxt->insert = xmlNewNode(NULL, BAD_CAST "data");
+	    xmlParseCRNGDropTokens(ctxt, 1);
+	    if (ctxt->insert == NULL) {
+	        xmlFreePropList(attrs);
+		CRNG_MEM_ERROR0();
+	    }
+	    ctxt->insert->properties = attrs;
+	    xmlParseCRNG_params(ctxt);
+        } else {
+	    ctxt->insert = xmlNewNode(NULL, BAD_CAST "data");
+	    xmlParseCRNGDropTokens(ctxt, 1);
+	    if (ctxt->insert == NULL) {
+	        xmlFreePropList(attrs);
+		CRNG_MEM_ERROR0();
+	    }
+	    ctxt->insert->properties = attrs;
+	    xmlNodeAddContent(ctxt->insert, token->token);
+	}
+    }
+    return(0);
+}
+
+/**
+ * xmlParseCRNG_primary:
+ * @ctxt: a compact RNG parser context
+ *
+ * Parse primary of the RELAX NG Compact Syntax Appendix A
+ *
+ * Returns 0 in case of success and -1 in case of error
+ */
+static int
+xmlParseCRNG_primary(xmlCRelaxNGParserCtxtPtr ctxt ATTRIBUTE_UNUSED)
+{
+    tokenPtr token;
+
+    token = xmlParseCRNGGetToken(ctxt, 1);
+    if (token == NULL)
+        return(0);
+    if (token->toktype == CRNG_KEYWORD) {
+        if (token->token == ctxt->key_element) {
+	    ctxt->insert = xmlNewNodeEatName(NULL, (xmlChar *) token->token);
+	    xmlParseCRNGDropTokens(ctxt, 1);
+	    if (ctxt->insert == NULL) CRNG_MEM_ERROR0();
+	    ctxt->isElem = 1;
+	    xmlParseCRNG_nameClass(ctxt);
+	    xmlParseCRNG_patternBlock(ctxt);
+	} else if (token->token == ctxt->key_attribute) {
+	    ctxt->insert = xmlNewNodeEatName(NULL, (xmlChar *) token->token);
+	    xmlParseCRNGDropTokens(ctxt, 1);
+	    if (ctxt->insert == NULL) CRNG_MEM_ERROR0();
+	    ctxt->isElem = 0;
+	    xmlParseCRNG_nameClass(ctxt);
+	    xmlParseCRNG_patternBlock(ctxt);
+	} else if (token->token == ctxt->key_mixed) {
+	    ctxt->insert = xmlNewNodeEatName(NULL, (xmlChar *) token->token);
+	    xmlParseCRNGDropTokens(ctxt, 1);
+	    if (ctxt->insert == NULL) CRNG_MEM_ERROR0();
+	    xmlParseCRNG_patternBlock(ctxt);
+	} else if (token->token == ctxt->key_list) {
+	    ctxt->insert = xmlNewNodeEatName(NULL, (xmlChar *) token->token);
+	    xmlParseCRNGDropTokens(ctxt, 1);
+	    if (ctxt->insert == NULL) CRNG_MEM_ERROR0();
+	    xmlParseCRNG_patternBlock(ctxt);
+	} else if (token->token == ctxt->key_empty) {
+	    ctxt->insert = xmlNewNodeEatName(NULL, (xmlChar *) token->token);
+	    xmlParseCRNGDropTokens(ctxt, 1);
+	    if (ctxt->insert == NULL) CRNG_MEM_ERROR0();
+	} else if (token->token == ctxt->key_notAllowed) {
+	    ctxt->insert = xmlNewNodeEatName(NULL, (xmlChar *) token->token);
+	    xmlParseCRNGDropTokens(ctxt, 1);
+	    if (ctxt->insert == NULL) CRNG_MEM_ERROR0();
+	} else if (token->token == ctxt->key_text) {
+	    ctxt->insert = xmlNewNodeEatName(NULL, (xmlChar *) token->token);
+	    xmlParseCRNGDropTokens(ctxt, 1);
+	    if (ctxt->insert == NULL) CRNG_MEM_ERROR0();
+	} else if (token->token == ctxt->key_parent) {
+	    ctxt->insert = xmlNewNodeEatName(NULL, (xmlChar *) token->token);
+	    xmlParseCRNGDropTokens(ctxt, 1);
+	    if (ctxt->insert == NULL) CRNG_MEM_ERROR0();
+	    TODO
+	} else if (token->token == ctxt->key_grammar) {
+	    ctxt->insert = xmlNewNodeEatName(NULL, (xmlChar *) token->token);
+	    xmlParseCRNGDropTokens(ctxt, 1);
+	    if (ctxt->insert == NULL) CRNG_MEM_ERROR0();
+	    TODO
+	} else if (token->token == ctxt->key_external) {
+	    ctxt->insert = xmlNewNode(NULL, BAD_CAST "externalRef");
+	    xmlParseCRNGDropTokens(ctxt, 1);
+	    if (ctxt->insert == NULL) CRNG_MEM_ERROR0();
+	    TODO
+	} else {
+	   TODO
+	}
+    } else if (token->toktype == CRNG_IDENTIFIER) {
+	ctxt->insert = xmlNewNodeEatName(NULL, (xmlChar *) ctxt->key_ref);
+	if (ctxt->insert == NULL) CRNG_MEM_ERROR0();
+	xmlSetProp(ctxt->insert, BAD_CAST "name", token->token);
+	xmlParseCRNGDropTokens(ctxt, 1);
+    } else if (token->toktype == CRNG_QNAME) {
+        xmlParseCRNG_datatype(ctxt);
+    } else if (token->toktype == CRNG_LITERAL_SEGMENT) {
+        xmlParseCRNG_datatype(ctxt);
+    } else if ((token->toktype == CRNG_OP) &&
+               (token->token[0] == '(') && (token->token[1] == 0)) {
+	xmlParseCRNGDropTokens(ctxt, 1);
+	xmlParseCRNG_pattern(ctxt);
+	token = xmlParseCRNGGetToken(ctxt, 1);
+	if ((token->toktype != CRNG_OP) ||
+	    (token->token[0] != ')') || (token->token[1] != 0)) {
+	    ERROR("Expecting \")\" here");
+	}
+	xmlParseCRNGDropTokens(ctxt, 1);
+    }
+    return(0);
+}
+
+/**
+ * xmlParseCRNG_particle:
+ * @ctxt: a compact RNG parser context
+ *
+ * Parse particle of the RELAX NG Compact Syntax Appendix A
+ *
+ * Returns 0 in case of success and -1 in case of error
+ */
+static int
+xmlParseCRNG_particle(xmlCRelaxNGParserCtxtPtr ctxt)
+{
+    tokenPtr token;
+    xmlNodePtr insert = ctxt->insert, res, tmp = NULL;
+
+    ctxt->insert = NULL;
+    xmlParseCRNG_primary(ctxt);
+    res = ctxt->insert;
+    token = xmlParseCRNGGetToken(ctxt, 1);
+    if ((token != NULL) && (token->toktype == CRNG_OP)) {
+        if ((token->token[0] == '*') && (token->token[1] == 0)) {
+	    tmp = xmlNewNode(NULL, BAD_CAST "zeroOrMore");
+	    if (tmp == NULL) CRNG_MEM_ERROR0();
+	} else if ((token->token[0] == '+') && (token->token[1] == 0)) {
+	    tmp = xmlNewNode(NULL, BAD_CAST "oneOrMore");
+	    if (tmp == NULL) CRNG_MEM_ERROR0();
+	} else if ((token->token[0] == '?') && (token->token[1] == 0)) {
+	    tmp = xmlNewNode(NULL, BAD_CAST "optional");
+	    if (tmp == NULL) CRNG_MEM_ERROR0();
+	}
+	if (tmp != NULL) {
+	    xmlAddChild(tmp, res);
+	    res = tmp;
+	    xmlParseCRNGDropTokens(ctxt, 1);
+	}
+    }
+    if (insert != NULL) {
+        xmlAddChild(insert, res);
+	ctxt->insert = insert;
+    } else
+        ctxt->insert = res;
+    return(0);
+}
+
+/**
+ * xmlParseCRNG_pattern:
+ * @ctxt: a compact RNG parser context
+ *
+ * Parse pattern of the RELAX NG Compact Syntax Appendix A
+ *
+ * Returns 0 in case of success and -1 in case of error
+ */
+static int
+xmlParseCRNG_pattern(xmlCRelaxNGParserCtxtPtr ctxt)
+{
+    tokenPtr token;
+    xmlNodePtr insert = ctxt->insert, prev, grp;
+
+    ctxt->insert = NULL;
+    xmlParseCRNG_particle(ctxt);
+    prev = ctxt->insert;
+    token = xmlParseCRNGGetToken(ctxt, 1);
+    while ((prev != NULL) && (token != NULL) && (token->toktype == CRNG_OP)) {
+        if (token->token == ctxt->key_or) {
+	    grp = xmlNewNodeEatName(NULL, (xmlChar *) ctxt->key_choice);
+	    if (grp == NULL) CRNG_MEM_ERROR0();
+	} else if (token->token == ctxt->key_and) {
+	    grp = xmlNewNodeEatName(NULL, (xmlChar *) ctxt->key_interleave);
+	    if (grp == NULL) CRNG_MEM_ERROR0();
+	} else if (token->token == ctxt->key_comma) {
+	    grp = xmlNewNodeEatName(NULL, (xmlChar *) ctxt->key_group);
+	    if (grp == NULL) CRNG_MEM_ERROR0();
+	} else
+	   break;
+	xmlParseCRNGDropTokens(ctxt, 1);
+        ctxt->insert = NULL;
+	xmlParseCRNG_particle(ctxt);
+	xmlAddChild(grp, prev);
+	xmlAddChild(grp, ctxt->insert);
+	prev = grp;
+	token = xmlParseCRNGGetToken(ctxt, 1);
+    }
+    if (insert != NULL) {
+	xmlAddChild(insert, prev);
+	ctxt->insert = insert;
+    } else {
+	ctxt->insert = prev;
+    }
+        
+    return(0);
+}
+
+/**
+ * xmlParseCRNG_component:
+ * @ctxt: a compact RNG parser context
+ *
+ * Parse component of the RELAX NG Compact Syntax Appendix A
+ *
+ * Returns 0 in case of success and -1 in case of error
+ */
+static int
+xmlParseCRNG_component(xmlCRelaxNGParserCtxtPtr ctxt)
+{
+    tokenPtr token, tok2;
+    xmlNodePtr insert = ctxt->insert;
+    
+    token = xmlParseCRNGGetToken(ctxt, 1);
+    if (token == NULL)
+        return(0);
+    if (token->toktype == CRNG_KEYWORD) {
+        if (token->token == ctxt->key_start) {
+	    xmlNodePtr start;
+
+	    start = xmlNewNodeEatName(NULL, (xmlChar *) ctxt->key_start);
+	    if (start == NULL) CRNG_MEM_ERROR0();
+	    if (ctxt->insert != NULL)
+	        xmlAddChild(ctxt->insert, start);
+	    ctxt->insert = start;
+            xmlParseCRNGDropTokens(ctxt, 1);
+	    token = xmlParseCRNGGetToken(ctxt, 1);
+
+            if ((token->toktype == CRNG_OP) &&
+	        (token->token == ctxt->key_equal)) {
+	    } else if ((token->toktype == CRNG_OP) &&
+	               (token->token == ctxt->key_orequal)) {
+		xmlParseCRNG_attribute(ctxt, ctxt->key_combine, NULL,
+		                       BAD_CAST "choice");
+	    } else if ((token->toktype == CRNG_OP) &&
+	               (token->token == ctxt->key_andequal)) {
+		xmlParseCRNG_attribute(ctxt, ctxt->key_combine, NULL,
+		                       BAD_CAST "interleave");
+	    } else {
+	        ERROR("expecting \"=\" or \"&=\" or \"|=\" here")
+		return(-1);
+	    }
+	    start->properties = ctxt->attrs;
+	    ctxt->attrs = NULL;
+            xmlParseCRNGDropTokens(ctxt, 1);
+	    xmlParseCRNG_pattern(ctxt);
+
+	} else if (token->token == ctxt->key_include) {
+	    TODO
+	} else if (token->token == ctxt->key_div) {
+	    TODO
+	} else {
+	    return(-1);
+	}
+    } else if (token->toktype == CRNG_IDENTIFIER) {
+        xmlNodePtr define;
+	const xmlChar *identifier;
+
+        identifier = token->token;
+	tok2 = xmlParseCRNGGetToken(ctxt, 2);
+	if ((tok2->toktype == CRNG_OP) &&
+	    (tok2->token == ctxt->key_equal)) {
+	} else if ((tok2->toktype == CRNG_OP) &&
+		   (tok2->token == ctxt->key_orequal)) {
+	    xmlParseCRNG_attribute(ctxt, ctxt->key_combine, NULL,
+				   BAD_CAST "choice");
+	} else if ((tok2->toktype == CRNG_OP) &&
+		   (tok2->token == ctxt->key_andequal)) {
+	    xmlParseCRNG_attribute(ctxt, ctxt->key_combine, NULL,
+				   BAD_CAST "interleave");
+	} else {
+	    ERROR("expecting \"=\" or \"&=\" or \"|=\" here")
+	    return(-1);
+	}
+	xmlParseCRNGDropTokens(ctxt, 2);
+
+	define = xmlNewNodeEatName(NULL, (xmlChar *) ctxt->key_define);
+	if (define == NULL) CRNG_MEM_ERROR0();
+	define->properties = ctxt->attrs;
+	ctxt->attrs = NULL;
+	xmlSetProp(define, BAD_CAST "name", identifier);
+	if (ctxt->insert != NULL)
+	    xmlAddChild(ctxt->insert, define);
+	ctxt->insert = define;
+	xmlParseCRNG_pattern(ctxt);
+    } else {
+	return(-1);
+    }
+    ctxt->insert = insert;
+    return(0);
+}
+
+/**
+ * xmlParseCRNG_grammar:
+ * @ctxt: a compact RNG parser context
+ *
+ * Parse grammar of the RELAX NG Compact Syntax Appendix A
+ *
+ * Returns 0 in case of success and -1 in case of error
+ */
+static int
+xmlParseCRNG_grammar(xmlCRelaxNGParserCtxtPtr ctxt ATTRIBUTE_UNUSED)
+{
+    tokenPtr token;
+    int ret;
+    
+    token = xmlParseCRNGGetToken(ctxt, 1);
+    while (token != NULL) {
+        ret = xmlParseCRNG_component(ctxt);
+	if (ret != 0)
+	    break;
+	token = xmlParseCRNGGetToken(ctxt, 1);
+    }
+    return(0);
+}
+
+/**
+ * xmlParseCRNG_topLevelBody:
+ * @ctxt: a compact RNG parser context
+ *
+ * Parse topLevelBody of the RELAX NG Compact Syntax Appendix A
+ *
+ * Returns 0 in case of success and -1 in case of error
+ */
+static int
+xmlParseCRNG_topLevelBody(xmlCRelaxNGParserCtxtPtr ctxt)
+{
+    tokenPtr token, tok2;
+    
+    token = xmlParseCRNGGetToken(ctxt, 1);
+    if (token->toktype == CRNG_KEYWORD) {
+        if ((token->token == ctxt->key_start) ||
+	    (token->token == ctxt->key_include) ||
+	    (token->token == ctxt->key_div)) {
+	    xmlNodePtr grammar;
+
+	    grammar = xmlNewNodeEatName(NULL, (xmlChar *) ctxt->key_grammar);
+	    if (grammar == NULL) CRNG_MEM_ERROR0();
+	    xmlDocSetRootElement(ctxt->doc, grammar);
+	    ctxt->insert = grammar;
+	    
+	    xmlParseCRNG_grammar(ctxt);
+	} else {
+	    xmlParseCRNG_pattern(ctxt);
+	}
+    } else {
+        tok2 = xmlParseCRNGGetToken(ctxt, 2);
+	if ((tok2->toktype == CRNG_OP) && 
+	    ((tok2->token == ctxt->key_equal) ||
+	     (tok2->token == ctxt->key_orequal) ||
+	     (tok2->token == ctxt->key_andequal))) {
+	    xmlNodePtr grammar;
+
+	    grammar = xmlNewNodeEatName(NULL, (xmlChar *) ctxt->key_grammar);
+	    if (grammar == NULL) CRNG_MEM_ERROR0();
+	    xmlDocSetRootElement(ctxt->doc, grammar);
+	    ctxt->insert = grammar;
+	    
+	    xmlParseCRNG_grammar(ctxt);
+	} else {
+	    xmlParseCRNG_pattern(ctxt);
+	}
+    }
+    return(0);
+}
+
+/**
+ * xmlParseCRNG_namespacePrefix:
+ * @ctxt: a compact RNG parser context
+ *
+ * Parse namespacePrefix of the RELAX NG Compact Syntax Appendix A
+ *
+ * Returns the prefix or NULL in case of error
+ */
+static const xmlChar *
+xmlParseCRNG_namespacePrefix(xmlCRelaxNGParserCtxtPtr ctxt)
+{
+    tokenPtr token;
+    const xmlChar *prefix = NULL;
+
+    token = xmlParseCRNGGetToken(ctxt, 1);
+    if (token->toktype == CRNG_IDENTIFIER) {
+        prefix = token->token;
+    } else if (token->toktype == CRNG_OP) {
+	if ((token->token[0] == '=') && (token->token[1] == 0))
+	    return(NULL);
+        prefix = token->token;
+    } else {
+	ERROR("Expecting a namespace prefix");
+	return(NULL);
+    }
+    xmlParseCRNGDropTokens(ctxt, 1);
+
+    if (xmlStrEqual(prefix, BAD_CAST "xmlns")) {
+	ERROR("Namespace prefix \"xmlns\" is forbidden");
+    }
+    return(prefix);
+}
+
+/**
+ * xmlParseCRNG_decl:
+ * @ctxt: a compact RNG parser context
+ *
+ * Parse decl of the RELAX NG Compact Syntax Appendix A
+ *
+ * Returns 0 in case of success and -1 in case of error
+ */
+static int
+xmlParseCRNG_decl(xmlCRelaxNGParserCtxtPtr ctxt)
+{
+    const xmlChar *prefix = NULL;
+    const xmlChar *namespace = NULL;
+    tokenPtr token;
+    
+    token = xmlParseCRNGGetToken(ctxt, 1);
+    if (token->toktype != CRNG_KEYWORD) return(-1);
+    if (token->token == ctxt->key_default) {
+        xmlParseCRNGDropTokens(ctxt, 1);
+        token = xmlParseCRNGGetToken(ctxt, 1);
+        if ((token->toktype != CRNG_KEYWORD) ||
+	    (token->token != ctxt->key_namespace)) {
+	    ERROR("Expecting keyword \"namespace\" after \"default\"");
+	}
+        xmlParseCRNGDropTokens(ctxt, 1);
+	prefix = xmlParseCRNG_namespacePrefix(ctxt);
+        token = xmlParseCRNGGetToken(ctxt, 1);
+        if ((token->toktype != CRNG_OP) ||
+	    (token->token[0] != '=') || (token->token[1] != 0)) {
+	    ERROR("Expecting keyword \"=\" here");
+	}
+        xmlParseCRNGDropTokens(ctxt, 1);
+        token = xmlParseCRNGGetToken(ctxt, 1);
+        if ((token->toktype == CRNG_KEYWORD) &&
+	    (token->token == ctxt->key_inherit)) {
+	    namespace = xmlCRelaxNGInherit;
+	} else if (token->toktype == CRNG_LITERAL_SEGMENT) {
+	    namespace = token->token;
+	} else {
+	    ERROR("Expecting an URI or \"inherit\" value");
+	}
+        xmlParseCRNGDropTokens(ctxt, 1);
+        if (namespace != NULL) {
+	    if (prefix != NULL)
+		xmlParseCRNG_bindPrefix(ctxt, prefix, namespace);
+            xmlParseCRNG_bindPrefix(ctxt, NULL, namespace);
+	}
+    } else if (token->token == ctxt->key_namespace) {
+        xmlParseCRNGDropTokens(ctxt, 1);
+	prefix = xmlParseCRNG_namespacePrefix(ctxt);
+        token = xmlParseCRNGGetToken(ctxt, 1);
+        if ((token->toktype != CRNG_OP) ||
+	    (token->token[0] != '=') || (token->token[1] != 0)) {
+	    ERROR("Expecting keyword \"=\" here");
+	}
+        xmlParseCRNGDropTokens(ctxt, 1);
+        token = xmlParseCRNGGetToken(ctxt, 1);
+        if ((token->toktype == CRNG_KEYWORD) &&
+	    (token->token == ctxt->key_inherit)) {
+	    namespace = xmlCRelaxNGInherit;
+	} else if (token->toktype == CRNG_LITERAL_SEGMENT) {
+	    namespace = token->token;
+	} else {
+	    ERROR("Expecting an URI or \"inherit\" value");
+	}
+        xmlParseCRNGDropTokens(ctxt, 1);
+        if (namespace != NULL)
+	    xmlParseCRNG_bindPrefix(ctxt, prefix, namespace);
+    } else if (token->token == ctxt->key_datatypes) {
+        xmlParseCRNGDropTokens(ctxt, 1);
+        
+        token = xmlParseCRNGGetToken(ctxt, 1);
+	if ((token->toktype != CRNG_KEYWORD) &&
+	    (token->toktype != CRNG_IDENTIFIER)) {
+	    ERROR("Expecting a datatype prefix identifier here");
+	} else 
+	    prefix = token->token;
+        xmlParseCRNGDropTokens(ctxt, 1);
+        token = xmlParseCRNGGetToken(ctxt, 1);
+        if ((token->toktype != CRNG_OP) ||
+	    (token->token[0] != '=') || (token->token[1] != 0)) {
+	    ERROR("Expecting keyword \"=\" here");
+	}
+        xmlParseCRNGDropTokens(ctxt, 1);
+        token = xmlParseCRNGGetToken(ctxt, 1);
+	if (token->toktype == CRNG_LITERAL_SEGMENT) {
+	    namespace = token->token;
+	} else {
+	    ERROR("Expecting a literal value for the datatype identifier");
+	}
+        xmlParseCRNGDropTokens(ctxt, 1);
+        if ((namespace != NULL) && (prefix != NULL))
+	    xmlParseCRNG_bindDatatypePrefix(ctxt, prefix, namespace);
+    }
+
+    return(0);
+}
+
+/**
+ * xmlParseCRNG_preamble:
+ * @ctxt: a compact RNG parser context
+ *
+ * Parse preamble of the RELAX NG Compact Syntax Appendix A
+ *
+ * Returns 0 in case of success and -1 in case of error
+ */
+static int
+xmlParseCRNG_preamble(xmlCRelaxNGParserCtxtPtr ctxt)
+{
+    tokenPtr token;
+    
+    token = xmlParseCRNGGetToken(ctxt, 1);
+    while (token != NULL) {
+	if (token == NULL) return(-1);
+	if ((token->toktype == CRNG_KEYWORD) &&
+	    ((token->token == ctxt->key_default) ||
+	     (token->token == ctxt->key_namespace) ||
+	     (token->token == ctxt->key_datatypes))) {
+	    xmlParseCRNG_decl(ctxt);
+	} else
+	    break;
+	token = xmlParseCRNGGetToken(ctxt, 1);
+    }
+    return(0);
+}
+
+/**
+ * xmlParseCRNG_topLevel:
+ * @ctxt: a compact RNG parser context
+ *
+ * Parse topLevel of the RELAX NG Compact Syntax Appendix A
+ *
+ * Returns 0 in case of success and -1 in case of error
+ */
+static int
+xmlParseCRNG_topLevel(xmlCRelaxNGParserCtxtPtr ctxt)
+{
+    xmlParseCRNG_preamble(ctxt);
+    xmlParseCRNG_topLevelBody(ctxt);
+    return(0);
+}
+
+/**
+ * xmlParseCRNG:
+ * @schemas:  pointer to the text of the compact schemas
+ * @len:  length of the schemas in bytes (or 0)
+ *
+ * Compiles the schemas into the equivalent Relax-NG XML structure
+ *
+ * Returns the xmlDocPtr resulting from the compilation or
+ *         NULL in case of error
+ */
+static xmlDocPtr
+xmlParseCRNG(const xmlChar *schemas, int len) {
+    struct _xmlCRelaxNGParserCtxt ctxt;
+    xmlDocPtr ret = NULL;
+
+    if (schemas == NULL) return(NULL);
+    if (len <= 5) len = xmlStrlen(schemas);
+    if (len <= 0) return(NULL);
+
+    memset(&ctxt, 0, sizeof(ctxt));
+    ctxt.compact = schemas;
+    ctxt.cur = schemas;
+    ctxt.end = &schemas[len];
+    ctxt.dict = xmlDictCreate();
+    if (ctxt.dict == NULL)
+        return(NULL);
+    ctxt.doc = xmlNewDoc(NULL);
+    if (ctxt.doc == NULL) {
+	xmlDictFree(ctxt.dict);
+	return(NULL);
+    }
+    ctxt.doc->dict = ctxt.dict;
+    xmlDictReference(ctxt.dict);
+
+    ctxt.nbTokens = 0;
+    ctxt.firstToken = 0;
+    ctxt.key_attribute = xmlDictLookup(ctxt.dict, BAD_CAST "attribute", -1);
+    ctxt.key_default = xmlDictLookup(ctxt.dict, BAD_CAST "default", -1);
+    ctxt.key_datatypes = xmlDictLookup(ctxt.dict, BAD_CAST "datatypes", -1);
+    ctxt.key_div = xmlDictLookup(ctxt.dict, BAD_CAST "div", -1);
+    ctxt.key_element = xmlDictLookup(ctxt.dict, BAD_CAST "element", -1);
+    ctxt.key_empty = xmlDictLookup(ctxt.dict, BAD_CAST "empty", -1);
+    ctxt.key_external = xmlDictLookup(ctxt.dict, BAD_CAST "external", -1);
+    ctxt.key_grammar = xmlDictLookup(ctxt.dict, BAD_CAST "grammar", -1);
+    ctxt.key_include = xmlDictLookup(ctxt.dict, BAD_CAST "include", -1);
+    ctxt.key_inherit = xmlDictLookup(ctxt.dict, BAD_CAST "inherit", -1);
+    ctxt.key_list = xmlDictLookup(ctxt.dict, BAD_CAST "list", -1);
+    ctxt.key_mixed = xmlDictLookup(ctxt.dict, BAD_CAST "mixed", -1);
+    ctxt.key_namespace = xmlDictLookup(ctxt.dict, BAD_CAST "namespace", -1);
+    ctxt.key_notAllowed = xmlDictLookup(ctxt.dict, BAD_CAST "notAllowed", -1);
+    ctxt.key_parent = xmlDictLookup(ctxt.dict, BAD_CAST "parent", -1);
+    ctxt.key_start = xmlDictLookup(ctxt.dict, BAD_CAST "start", -1);
+    ctxt.key_string = xmlDictLookup(ctxt.dict, BAD_CAST "string", -1);
+    ctxt.key_text = xmlDictLookup(ctxt.dict, BAD_CAST "text", -1);
+    ctxt.key_token = xmlDictLookup(ctxt.dict, BAD_CAST "token", -1);
+    ctxt.key_equal = xmlDictLookup(ctxt.dict, BAD_CAST "=", 1);
+    ctxt.key_orequal = xmlDictLookup(ctxt.dict, BAD_CAST "|=", 2);
+    ctxt.key_andequal = xmlDictLookup(ctxt.dict, BAD_CAST "&=", 2);
+    ctxt.key_combine = xmlDictLookup(ctxt.dict, BAD_CAST "&=", 2);
+    ctxt.key_or = xmlDictLookup(ctxt.dict, BAD_CAST "|", 1);
+    ctxt.key_comma = xmlDictLookup(ctxt.dict, BAD_CAST ",", 1);
+    ctxt.key_and = xmlDictLookup(ctxt.dict, BAD_CAST "&", 1);
+    ctxt.key_choice = xmlDictLookup(ctxt.dict, BAD_CAST "choice", -1);
+    ctxt.key_group = xmlDictLookup(ctxt.dict, BAD_CAST "group", -1);
+    ctxt.key_interleave = xmlDictLookup(ctxt.dict, BAD_CAST "interleave", -1);
+    ctxt.key_ref = xmlDictLookup(ctxt.dict, BAD_CAST "ref", 3);
+    ctxt.key_define = xmlDictLookup(ctxt.dict, BAD_CAST "define", 6);
+
+    /* xmlParseCRNGTokenize(&ctxt); */
+    xmlParseCRNG_topLevel(&ctxt);
+
+    xmlDictFree(ctxt.dict);
+
+    ret = ctxt.doc;
+    return(ret);
+}
+
+const xmlChar *schemas = 
+"# RELAX NG XML syntax specified in compact syntax.\n\
+\n\
+default namespace rng = \"http://relaxng.org/ns/structure/1.0\"\n\
+namespace local = \"\"\n\
+datatypes xsd = \"http://www.w3.org/2001/XMLSchema-datatypes\"\n\
+\n\
+start = pattern\n\
+\n\
+pattern =\n\
+  element element { (nameQName | nameClass), (common & pattern+) }\n\
+  | element attribute { (nameQName | nameClass), (common & pattern?) }\n\
+  | element group|interleave|choice|optional\n\
+            |zeroOrMore|oneOrMore|list|mixed { common & pattern+ }\n\
+  | element ref|parentRef { nameNCName, common }\n\
+  | element empty|notAllowed|text { common }\n\
+  | element data { type, param*, (common & exceptPattern?) }\n\
+  | element value { commonAttributes, type?, xsd:string }\n\
+  | element externalRef { href, common }\n\
+  | element grammar { common & grammarContent* }\n\
+\n\
+param = element param { commonAttributes, nameNCName, xsd:string }\n\
+\n\
+exceptPattern = element except { common & pattern+ }\n\
+\n\
+grammarContent =\n\
+  definition\n\
+  | element div { common & grammarContent* }\n\
+  | element include { href, (common & includeContent*) }\n\
+\n\
+includeContent =\n\
+  definition\n\
+  | element div { common & includeContent* }\n\
+\n\
+definition =\n\
+  element start { combine?, (common & pattern+) }\n\
+  | element define { nameNCName, combine?, (common & pattern+) }\n\
+\n\
+combine = attribute combine { \"choice\" | \"interleave\" }\n\
+\n\
+nameClass =\n\
+  element name { commonAttributes, xsd:QName }\n\
+  | element anyName { common & exceptNameClass? }\n\
+  | element nsName { common & exceptNameClass? }\n\
+  | element choice { common & nameClass+ }\n\
+\n\
+exceptNameClass = element except { common & nameClass+ }\n\
+\n\
+nameQName = attribute name { xsd:QName }\n\
+nameNCName = attribute name { xsd:NCName }\n\
+href = attribute href { xsd:anyURI }\n\
+type = attribute type { xsd:NCName }\n\
+\n\
+common = commonAttributes, foreignElement*\n\
+\n\
+commonAttributes =\n\
+  attribute ns { xsd:string }?,\n\
+  attribute datatypeLibrary { xsd:anyURI }?,\n\
+  foreignAttribute*\n\
+\n\
+foreignElement = element * - rng:* { (anyAttribute | text | anyElement)* }\n\
+foreignAttribute = attribute * - (rng:*|local:*) { text }\n\
+anyElement = element * { (anyAttribute | text | anyElement)* }\n\
+anyAttribute = attribute * { text }\n\
+";
+
+int main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
+    xmlDocPtr res;
+
+    res = xmlParseCRNG(schemas, -1);
+    if (res != NULL) {
+        xmlDocFormatDump(stdout, res, 1);
+	xmlFreeDoc(res);
+    }
+    return(0);
+}
