Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Adding a XML graph parser
[simgrid.git] / src / xbt / graphxml.l
diff --git a/src/xbt/graphxml.l b/src/xbt/graphxml.l
new file mode 100644 (file)
index 0000000..8384a8f
--- /dev/null
@@ -0,0 +1,586 @@
+/* Validating XML processor for graphxml.dtd.
+ * Generated 2006/03/20 16:15:21.
+ *
+ * This program was generated with the FleXML XML processor generator.
+ * FleXML is Copyright © 1999-2005 Kristoffer Rose.  All rights reserved.
+ * (Id: flexml.pl,v 1.45 2006/03/03 19:25:46 wdowling Exp).
+ * 
+ * There are two, intertwined parts to this program, part A and part B.
+ *
+ * Part A
+ * ------
+ * 
+ * Some parts, here collectively called "Part A", are found in the 
+ * FleXML package.  They are Copyright © 1999-2005 Kristoffer Rose. 
+ * All rights reserved.
+ *
+ * You can redistribute, use, perform, display and/or modify "Part A"
+ * provided the following two conditions hold:
+ *
+ * 1. The program is distributed WITHOUT ANY WARRANTY from the author of
+ *    FleXML; without even the implied warranty of MERCHANTABILITY or
+ *    FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * 2. The program distribution conditions do not in any way affect the
+ *    distribution conditions of the FleXML system used to generate this
+ *    file or any version of FleXML derived from that system.
+ *
+ * Notice that these are explicit rights granted to you for files
+ * generated by the FleXML system.  For your rights in connection with
+ * the FleXML system itself please consult the GNU General Public License.
+ * 
+ * Part B
+ * ------
+ * 
+ * The other parts, here collectively called "Part B", and which came 
+ * from the DTD used by FleXML to generate this program, can be 
+ * distributed (or not, as the case may be) under the terms of whoever
+ * wrote them, provided these terms respect and obey the two conditions 
+ * above under the heading "Part A".
+ *
+ * The author of and contributors to FleXML specifically disclaim
+ * any copyright interest in "Part B", unless "Part B" was written 
+ * by the author of or contributors to FleXML.
+ * 
+ */
+
+%{
+
+/* Version strings. */
+const char rcs_grahxml_flexml_skeleton[] =
+ "$" "Id: skel,v 1.26 2005/02/23 22:22:20 wdowling Exp $";
+const char rcs_grahxml_flexml[] =
+ "$" "Id: flexml.pl,v 1.45 2006/03/03 19:25:46 wdowling Exp $";
+
+/* ANSI headers. */
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <stdarg.h>
+#include <ctype.h>
+
+/* Generated definitions. */
+#define FLEXML_yylineno
+#define FLEXML_BUFFERSTACKSIZE 1000000
+
+/* XML processor api. */
+/* FleXML-provided data. */
+const char* pcdata;
+AT_edge_target A_edge_target;
+AT_node_name A_node_name;
+AT_node_label A_node_label;
+AT_edge_label A_edge_label;
+AT_edge_source A_edge_source;
+AT_edge_isDirected A_edge_isDirected;
+AT_edge_name A_edge_name;
+
+/* XML state. */
+#ifdef FLEX_DEBUG
+# define ENTER(state)  debug_enter(state,#state)
+# define LEAVE         debug_leave()
+# define SET(state)    debug_set(state,#state)
+  static void debug_enter(int, const char*);
+  static void debug_leave(void);
+  static void debug_set(int, const char*);
+#else
+# define ENTER(state)  (yy_push_state(state))
+# define LEAVE         (yy_pop_state())
+# define SET(state)    BEGIN(state)
+#endif
+
+/* Generic actions. */
+#define SKIP   /*skip*/
+#define SUCCEED        CLEANUP; return 0
+
+#define FAIL   return fail
+static int fail(const char*, ...);
+const char * grahxml_parse_err_msg(void);
+
+/* Cleanup */
+static void cleanup(void);
+#define CLEANUP  cleanup()
+
+/* Text buffer stack handling. */
+char bufferstack[FLEXML_BUFFERSTACKSIZE];
+static char* limit = bufferstack + FLEXML_BUFFERSTACKSIZE;
+typedef struct BufferLast_s {
+  struct BufferLast_s *old; char* saved; char new1[1];
+} BufferLast;
+#ifdef FLEXML_HasMixed
+static BufferLast* last = (BufferLast*)0;
+#endif
+static char* next = bufferstack;
+
+#define BUFFERSET(P)  (P = next)
+#define BUFFERPUTC(C) (assert(next<limit), *(next++) = (C))
+#define BUFFERDONE    (BUFFERPUTC('\0'))
+
+#define BUFFERLITERAL(C,P) bufferliteral(C,&(P),yytext)
+static void bufferliteral(char c, const char** pp, char* text)
+{
+  char *s = strchr(text,c), *e = strrchr(text,c);
+  assert(s <= e); BUFFERSET(*pp);
+  while (++s<e) {
+    if (isspace(*s)) { BUFFERPUTC(' '); while (isspace(*s)) ++s; }
+    else BUFFERPUTC(*s);
+  }
+  BUFFERDONE;
+}
+
+#ifdef FLEXML_HasMixed
+static void pushbuffer(char* p)
+{
+  BufferLast* l = (BufferLast*)next;
+  assert(next < limit);
+  l->old = last;
+  l->saved = p;
+  next = l->new1;
+  last = l;
+}
+
+static char* popbuffer(void)
+{
+  BufferLast* l = last;
+  assert(last != (BufferLast*)0);
+  last = l->old;
+  next = (char*)l;
+  return l->saved;
+}
+#endif
+
+/* General internal entities are `unput' back onto the input stream... */
+#define ENTITYTEXT(T) \
+  { char *s = (T), *e = s+strlen(s);\
+    while (--e >= s) { unput(*e); }}
+%}
+
+/* Flex standard options. */
+%option stack
+%option noyy_top_state
+%option noinput
+%option noreject
+%option noyymore
+%option noyywrap
+
+/* Flex user-requested options. */
+%option yylineno
+%option nounput
+
+/* XML character classes (currently restricted to ASCII). */
+
+/* "Common syntactic structures." */
+S              [ \t\n\r\f]+
+s              [ \t\n\r\f]*
+
+/* "Names and Tokens." */
+NameChar       [A-Za-z0-9.:_-]
+Name           [A-Za-z_:]{NameChar}*
+Names          {Name}({S}{Name})*
+Nmtoken                ({NameChar})+
+Nmtokens       {Nmtoken}({S}{Nmtoken})*
+
+/* Miscellaneous. */
+VersionNum     [a-zA-Z0-9_.:-]+
+Eq             {s}"="{s}
+Literal                \'[^'']*\'|\"[^""]*\"
+
+/* Parser states (flex `exclusive start conditions'):
+ *
+ * PROLOG      the XML prolog of the document before <?xml...>
+ * DOCTYPE     the XML prolog of the document after <?xml...>
+ * EPILOG      after the root element
+ * INCOMMENT   inside an XML comment <!--....-->
+ * INPI                inside an XML PI <?...?>
+ * VALUE1      inside a '...'-delimited literal
+ * VALUE2      inside a "..."-delimited literal
+ * CDATA       inside a <![CDATA[...]]> section.
+ * ROOT_<tag>  expect root element <tag>
+ * AL_<tag>    inside the attribute list for <tag>
+ * IN_<tag>    inside a <tag> with element contents (ready for end tag)
+ * IMPOSSIBLE  dummy to permit disabling rules; must be last
+ */
+%x PROLOG DOCTYPE EPILOG INCOMMENT INPI VALUE1 VALUE2 CDATA
+%x ROOT_graph AL_graph S_graph S_graph_1 S_graph_2 S_graph_3 S_graph_4 S_graph_5 E_graph
+%x ROOT_node AL_node E_node
+%x ROOT_edge AL_edge E_edge
+%x IMPOSSIBLE
+
+%{
+/* State names. */
+const char* *grahxml_statenames=NULL;
+%}
+
+%%
+
+ /* Bypass Flex's default INITIAL state and begin by parsing the XML prolog. */
+ SET(PROLOG);
+  /* FleXML_init */
+  next = bufferstack;
+  if(!grahxml_statenames) {grahxml_statenames= (const char **)calloc(IMPOSSIBLE,sizeof(char*));
+  grahxml_statenames[PROLOG] = NULL;
+  grahxml_statenames[DOCTYPE] = NULL;
+  grahxml_statenames[EPILOG] = NULL;
+  grahxml_statenames[INCOMMENT] = NULL;
+  grahxml_statenames[INPI] = NULL;
+  grahxml_statenames[VALUE1] = NULL;
+  grahxml_statenames[VALUE2] = NULL;
+  grahxml_statenames[CDATA] = NULL;
+  grahxml_statenames[ROOT_graph] = NULL;
+  grahxml_statenames[AL_graph] = NULL;
+  grahxml_statenames[S_graph] = "graph";
+  grahxml_statenames[S_graph_1] = "graph";
+  grahxml_statenames[S_graph_2] = "graph";
+  grahxml_statenames[S_graph_3] = "graph";
+  grahxml_statenames[S_graph_4] = "graph";
+  grahxml_statenames[S_graph_5] = "graph";
+  grahxml_statenames[E_graph] = "graph";
+  grahxml_statenames[ROOT_node] = NULL;
+  grahxml_statenames[AL_node] = NULL;
+  grahxml_statenames[E_node] = "node";
+  grahxml_statenames[ROOT_edge] = NULL;
+  grahxml_statenames[AL_edge] = NULL;
+  grahxml_statenames[E_edge] = "edge";
+  }
+
+ /* COMMENTS and PIs: handled uniformly for efficiency. */
+
+<ROOT_graph,AL_graph,S_graph,S_graph_1,S_graph_2,S_graph_3,S_graph_4,S_graph_5,E_graph,ROOT_node,AL_node,E_node,ROOT_edge,AL_edge,E_edge,PROLOG,DOCTYPE,EPILOG>{
+ "<!--" ENTER(INCOMMENT);
+ "<?" ENTER(INPI);
+}
+<INCOMMENT>{
+ "-->"         LEAVE;
+ "--"          |
+ .             |
+ \n            SKIP;
+ <<EOF>>       FAIL("EOF in comment.");
+}
+<INPI>{
+ "?>"          LEAVE;
+ .             |
+ \n            SKIP;
+ <<EOF>>       FAIL("EOF in PI (processing instruction).");
+}
+
+ /* SPACES: skipped uniformly */
+
+<ROOT_graph,AL_graph,S_graph,S_graph_1,S_graph_2,S_graph_3,S_graph_4,S_graph_5,E_graph,ROOT_node,AL_node,E_node,ROOT_edge,AL_edge,E_edge,PROLOG,DOCTYPE,EPILOG>{S} SKIP;
+
+ /* PROLOG: determine root element and process it. */
+
+<PROLOG>{
+ "<?xml"({S}version{Eq}(\'{VersionNum}\'|\"{VersionNum}\"))?({S}encoding{Eq}(\'[^']*\'|\"[^"]*\"))?"?>" SET(DOCTYPE); 
+ "<?xml"[^>]*">" FAIL("Bad declaration %s.",yytext);
+}
+
+<PROLOG,DOCTYPE>{
+ "<!DOCTYPE"{S}"edge"{S}SYSTEM{S}("'graphxml.dtd'"|"\"graphxml.dtd\""){s}">" SET(ROOT_edge);
+ "<!DOCTYPE"{S}"node"{S}SYSTEM{S}("'graphxml.dtd'"|"\"graphxml.dtd\""){s}">" SET(ROOT_node);
+ "<!DOCTYPE"{S}"graph"{S}SYSTEM{S}("'graphxml.dtd'"|"\"graphxml.dtd\""){s}">" SET(ROOT_graph);
+ "<!"[^>-][^>]*">" FAIL("Bad declaration %s.",yytext);
+ .             FAIL("Unexpected character `%c' in prolog.", yytext[0]);
+ <<EOF>>       FAIL("EOF in prolog.");
+}
+
+ /* RULES DERIVED FROM DTD. */
+
+ /* <!-- Small DTD for xbt graphs. -->  */
+
+<ROOT_graph>"<graph"{s} {
+  ENTER(AL_graph);
+  }
+
+<AL_graph>{
+ ">" {
+  LEAVE; STag_graph();pcdata = NULL; ENTER(S_graph);
+ }
+ "/>" {
+  LEAVE; STag_graph(); pcdata = NULL; ETag_graph();
+  switch (YY_START) {
+   case ROOT_graph: SET(EPILOG); break;
+  }
+ }
+ .       FAIL("Unexpected character `%c' in attribute list of graph element.", yytext[0]);
+ {Name} FAIL("Bad attribute `%s' in `graph' element start tag.",yytext);
+ <<EOF>> FAIL("EOF in attribute list of `graph' element.");
+}
+
+<S_graph_1,E_graph,S_graph_3,S_graph_5,S_graph>{
+ "</graph"{s}">" {
+  LEAVE;
+  ETag_graph();
+  switch (YY_START) {
+   case ROOT_graph: SET(EPILOG); break;
+  }
+ }
+ "</"{Name}{s}">" FAIL("Unexpected end-tag `%s': `</graph>' expected.",yytext);
+ .       FAIL("Unexpected character `%c': `</graph>' expected.",yytext[0]);
+ <<EOF>> FAIL("Premature EOF: `</graph>' expected.");
+}
+
+ /*     label           CDATA                ""
+  *     name            CDATA                #REQUIRED
+  * >  */
+
+<ROOT_node,S_graph_2,S_graph_3,S_graph>"<node"{s} {
+  A_node_label = NULL;
+  A_node_name = NULL;
+  ENTER(AL_node);
+  }
+
+<AL_node>{
+ "label"{Eq}\' ENTER(VALUE1); BUFFERSET(A_node_label);
+ "label"{Eq}\" ENTER(VALUE2); BUFFERSET(A_node_label);
+
+ "name"{Eq}\' ENTER(VALUE1); BUFFERSET(A_node_name);
+ "name"{Eq}\" ENTER(VALUE2); BUFFERSET(A_node_name);
+
+ ">" {
+  if (!A_node_name) FAIL("Required attribute `name' not set for `node' element.");
+  LEAVE; STag_node();pcdata = NULL; ENTER(E_node);
+ }
+ "/>" {
+  if (!A_node_name) FAIL("Required attribute `name' not set for `node' element.");
+  LEAVE; STag_node(); pcdata = NULL; ETag_node();
+  switch (YY_START) {
+   case S_graph_2: case S_graph_3: case S_graph: SET(S_graph_3); break;
+   case ROOT_node: SET(EPILOG); break;
+  }
+ }
+ .       FAIL("Unexpected character `%c' in attribute list of node element.", yytext[0]);
+ {Name} FAIL("Bad attribute `%s' in `node' element start tag.",yytext);
+ <<EOF>> FAIL("EOF in attribute list of `node' element.");
+}
+
+<E_node>{
+ "</node"{s}">" {
+  LEAVE;
+  ETag_node();
+  switch (YY_START) {
+   case S_graph_2: case S_graph_3: case S_graph: SET(S_graph_3); break;
+   case ROOT_node: SET(EPILOG); break;
+  }
+ }
+ "</"{Name}{s}">" FAIL("Unexpected end-tag `%s': `</node>' expected.",yytext);
+ .       FAIL("Unexpected character `%c': `</node>' expected.",yytext[0]);
+ <<EOF>> FAIL("Premature EOF: `</node>' expected.");
+}
+
+ /*     label           CDATA                ""
+  *     name       CDATA        #IMPLIED
+  *     source     CDATA        #REQUIRED
+  *     target     CDATA        #REQUIRED
+  *     isDirected (true|false) "true"
+  * >  */
+
+<ROOT_edge,S_graph_1,S_graph_3,S_graph_5,S_graph_4,S_graph>"<edge"{s} {
+  A_edge_label = NULL;
+  A_edge_name = NULL;
+  A_edge_source = NULL;
+  A_edge_target = NULL;
+  A_edge_isDirected = A_edge_isDirected_true;
+  ENTER(AL_edge);
+  }
+
+<AL_edge>{
+ "label"{Eq}\' ENTER(VALUE1); BUFFERSET(A_edge_label);
+ "label"{Eq}\" ENTER(VALUE2); BUFFERSET(A_edge_label);
+
+ "name"{Eq}\' ENTER(VALUE1); BUFFERSET(A_edge_name);
+ "name"{Eq}\" ENTER(VALUE2); BUFFERSET(A_edge_name);
+
+ "source"{Eq}\' ENTER(VALUE1); BUFFERSET(A_edge_source);
+ "source"{Eq}\" ENTER(VALUE2); BUFFERSET(A_edge_source);
+
+ "target"{Eq}\' ENTER(VALUE1); BUFFERSET(A_edge_target);
+ "target"{Eq}\" ENTER(VALUE2); BUFFERSET(A_edge_target);
+
+ "isDirected"{Eq}"'true'" |
+ "isDirected"{Eq}"\"true\"" A_edge_isDirected = A_edge_isDirected_true;
+ "isDirected"{Eq}"'false'" |
+ "isDirected"{Eq}"\"false\"" A_edge_isDirected = A_edge_isDirected_false;
+
+ ">" {
+  if (!A_edge_source) FAIL("Required attribute `source' not set for `edge' element.");
+  if (!A_edge_target) FAIL("Required attribute `target' not set for `edge' element.");
+  LEAVE; STag_edge();pcdata = NULL; ENTER(E_edge);
+ }
+ "/>" {
+  if (!A_edge_source) FAIL("Required attribute `source' not set for `edge' element.");
+  if (!A_edge_target) FAIL("Required attribute `target' not set for `edge' element.");
+  LEAVE; STag_edge(); pcdata = NULL; ETag_edge();
+  switch (YY_START) {
+   case S_graph_1: case S_graph_3: case S_graph_5: case S_graph_4: case S_graph: SET(S_graph_5); break;
+   case ROOT_edge: SET(EPILOG); break;
+  }
+ }
+ .       FAIL("Unexpected character `%c' in attribute list of edge element.", yytext[0]);
+ {Name} FAIL("Bad attribute `%s' in `edge' element start tag.",yytext);
+ <<EOF>> FAIL("EOF in attribute list of `edge' element.");
+}
+
+<E_edge>{
+ "</edge"{s}">" {
+  LEAVE;
+  ETag_edge();
+  switch (YY_START) {
+   case S_graph_1: case S_graph_3: case S_graph_5: case S_graph_4: case S_graph: SET(S_graph_5); break;
+   case ROOT_edge: SET(EPILOG); break;
+  }
+ }
+ "</"{Name}{s}">" FAIL("Unexpected end-tag `%s': `</edge>' expected.",yytext);
+ .       FAIL("Unexpected character `%c': `</edge>' expected.",yytext[0]);
+ <<EOF>> FAIL("Premature EOF: `</edge>' expected.");
+}
+
+ /* EPILOG: after the root element. */
+
+<EPILOG>{
+ . {SET(PROLOG); yyless(0); CLEANUP; return -1;}
+ <<EOF>>       SUCCEED;
+}
+
+ /* CHARACTER DATA. */
+
+<IMPOSSIBLE,VALUE1,VALUE2>{
+ /* Non-defined standard entities... */
+"&amp;"  BUFFERPUTC('&');
+"&lt;"   BUFFERPUTC('<');
+"&gt;"   BUFFERPUTC('>');
+"&apos;" BUFFERPUTC('\'');
+"&quot;" BUFFERPUTC('"');
+
+ /* Character entities. */
+ "&#"[[:digit:]]+";"   BUFFERPUTC((unsigned char)atoi(yytext+2));
+ "&#x"[[:xdigit:]]+";" BUFFERPUTC((unsigned char)strtol(yytext+3,NULL,16));
+}
+
+<IMPOSSIBLE,VALUE1,VALUE2,CDATA>{
+ "\n"          |
+ "\r"          |
+ "\r\n"                |
+ "\n\r"                BUFFERPUTC('\n');
+}
+
+<IMPOSSIBLE>{
+ "<![CDATA["   ENTER(CDATA);
+ "]""]>"               FAIL("Unexpected `]""]>' in character data.");
+}
+
+<VALUE1>{
+ \'            BUFFERDONE; LEAVE;
+ <<EOF>>       FAIL("EOF in literal (\"'\" expected).");
+}
+
+<VALUE2>{
+ \"            BUFFERDONE; LEAVE;
+ <<EOF>>       FAIL("EOF in literal (`\"' expected).");
+}
+
+<IMPOSSIBLE,VALUE1,VALUE2>{
+ [^<&]         BUFFERPUTC(yytext[0]);
+ [<&]          FAIL("Spurious `%c' in character data.",yytext[0]);
+}
+
+<CDATA>{
+ "]""]>"               LEAVE;
+ /* "]""]"             BUFFERPUTC(yytext[0]); BUFFERPUTC(yytext[1]); */
+ .             BUFFERPUTC(yytext[0]);
+ <<EOF>>       FAIL("EOF in CDATA section.");
+}
+
+ /* Impossible rules to avoid warnings from flex(1). */
+ /* Ideally, this should be replaced by code in flexml.pl that
+    generates just the states not covered by other rules. */
+<*>{
+ .|[\n] FAIL("Syntax error on character `%c'.", yytext[0]);
+}
+
+%%
+
+/* Element context stack lookup. */
+int grahxml_element_context(int i)
+{
+  return (0<i && i<yy_start_stack_depth
+         ? yy_start_stack[yy_start_stack_ptr - i]
+         : 0);
+}
+
+#ifdef FLEX_DEBUG
+void print_yy_stack(char* fmt, ...)
+{
+  int i = 0; va_list ap; va_start(ap, fmt);
+  vfprintf(stderr, fmt, ap);
+  for (i=1; i<yy_start_stack_ptr; i++)
+    fprintf(stderr, "%s/", grahxml_statenames[yy_start_stack[i] ]);
+  fprintf(stderr,"%s\n", grahxml_statenames[YY_START]);
+  va_end(ap);
+}
+
+static void debug_enter(int state, const char* statename) {
+  yy_push_state(state);
+  if (yy_flex_debug) print_yy_stack("--ENTER(%s) : ",statename);
+}
+
+static void debug_leave(void) {
+  if (yy_flex_debug) print_yy_stack("--LEAVE : ");
+  yy_pop_state();
+}
+
+static void debug_set(int state, const char* statename) {
+  BEGIN(state);
+  if (yy_flex_debug) print_yy_stack("--SET(%s) : ",statename);
+}
+#endif
+
+enum {flexml_max_err_msg_size = 512};
+
+static char flexml_err_msg[flexml_max_err_msg_size];
+const char * grahxml_parse_err_msg()
+{
+    return flexml_err_msg;
+}
+
+static void reset_grahxml_parse_err_msg()
+{
+    flexml_err_msg[0] = '\0';
+}
+
+
+static void cleanup(void)
+{
+    if (grahxml_statenames) {
+        free(grahxml_statenames);
+       grahxml_statenames = NULL;
+    }
+}
+
+
+static int fail(const char* fmt, ...)
+{
+    int chars_left, used;
+    va_list ap; va_start(ap, fmt);
+#ifdef FLEXML_yylineno
+    used = sprintf(flexml_err_msg,
+                  "Invalid XML (XML input line %d, state %d): ",
+                  yylineno, YY_START);
+#else
+    used = sprintf(flexml_err_msg,
+                  "Invalid XML (state %d): ",
+                  YY_START);
+#endif
+    chars_left = flexml_max_err_msg_size - used - 1;
+    vsnprintf(flexml_err_msg + used, chars_left, fmt, ap);
+    va_end(ap);
+
+#ifndef FLEXML_quiet_parser
+    /* print directly to sdterr */
+    fprintf(stderr, "%s\n", flexml_err_msg);
+    flexml_err_msg[0] = '\0';
+#endif
+
+    cleanup();
+
+    return 1;
+}