gmlscan.l 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. /* By default, Flex emits a lexer using symbols prefixed with "yy". Graphviz
  2. * contains multiple Flex-generated lexers, so we alter this prefix to avoid
  3. * symbol clashes.
  4. */
  5. %option prefix="gml"
  6. /* Avoid generating an unused input function. See
  7. https://westes.github.io/flex/manual/Scanner-Options.html
  8. */
  9. %option noinput
  10. %{
  11. #include <assert.h>
  12. #include <stdlib.h>
  13. #include <string.h>
  14. #include <gml2gv.h>
  15. #include <gmlparse.h>
  16. #include <util/alloc.h>
  17. #include "config.h"
  18. #define GRAPH_EOF_TOKEN '@' /* lex class must be defined below */
  19. static int line_num = 1;
  20. static int errors;
  21. static FILE* Ifile;
  22. void initgmlscan(FILE *ifile)
  23. {
  24. if (ifile) {
  25. Ifile = ifile;
  26. line_num = 1;
  27. }
  28. errors = 0;
  29. }
  30. #ifndef YY_INPUT
  31. #define YY_INPUT(buf,result,max_size) \
  32. if ((result = fread(buf, 1, max_size, Ifile)) < 0) \
  33. YY_FATAL_ERROR( "input in flex scanner failed" )
  34. #endif
  35. /* buffer for arbitrary length strings (longer than BUFSIZ) */
  36. static char *Sbuf;
  37. static void beginstr(void) {
  38. assert(Sbuf == NULL && "leaking memory");
  39. Sbuf = gv_strdup("");
  40. }
  41. static void addstr(const char *src) {
  42. assert(Sbuf != NULL && "missing beginstr()");
  43. // enlarge the buffer to make room for the suffix
  44. {
  45. size_t old_size = strlen(Sbuf) + 1;
  46. size_t new_size = old_size + strlen(src);
  47. Sbuf = gv_realloc(Sbuf, old_size, new_size);
  48. }
  49. strcat(Sbuf, src);
  50. }
  51. static void endstr(void) {
  52. assert(Sbuf != NULL && "missing beginstr()");
  53. // take ownership of the Sbuf backing memory
  54. gmllval.str = Sbuf;
  55. Sbuf = NULL;
  56. }
  57. %}
  58. GRAPH_EOF_TOKEN [@]
  59. ASCII [ !#$%\047-\177]
  60. DIGIT [0-9]
  61. L_INT [-+]?{DIGIT}+
  62. MANTISSA E[-+]?{DIGIT}
  63. L_REAL [-+]?{DIGIT}*\.{DIGIT}*{MANTISSA}?
  64. L_ID [a-zA-Z_][_a-zA-Z0-9]*
  65. %x qstring
  66. %%
  67. {GRAPH_EOF_TOKEN} return(EOF);
  68. <INITIAL,qstring>\n line_num++;
  69. ^"#".* /* ignore # line */
  70. [ \t\r] /* ignore whitespace */
  71. "graph" return (GRAPH);
  72. "node" return (NODE);
  73. "edge" return (EDGE);
  74. "directed" return (DIRECTED);
  75. "id" return (ID);
  76. "source" return (SOURCE);
  77. "target" return (TARGET);
  78. "x" return (XVAL);
  79. "y" return (YVAL);
  80. "w" return (WVAL);
  81. "h" return (HVAL);
  82. "label" return (LABEL);
  83. "graphics" return (GRAPHICS);;
  84. "LabelGraphics" return (LABELGRAPHICS);
  85. "type" return (TYPE);
  86. "fill" return (FILL);
  87. "outline" return (OUTLINE);
  88. "outlineStyle" return (OUTLINESTYLE);
  89. "outlineWidth" return (OUTLINEWIDTH);
  90. "width" return (WIDTH);
  91. "style" return (STYLE);
  92. "Line" return (LINE);
  93. "point" return (POINT);
  94. "text" return (TEXT);
  95. "fontSize" return (FONTSIZE);
  96. "fontName" return (FONTNAME);
  97. "color" return (COLOR);
  98. {L_INT} { gmllval.str = gv_strdup(yytext); return (INTEGER); }
  99. {L_REAL} { gmllval.str = gv_strdup(yytext); return (REAL); }
  100. {L_ID} { gmllval.str = gv_strdup(yytext); return (NAME); }
  101. ["] BEGIN(qstring); beginstr();
  102. <qstring>["] BEGIN(INITIAL); endstr(); return (STRING);
  103. <qstring>([^"]+) addstr(yytext);
  104. . return (yytext[0]);
  105. %%
  106. void gmlerror(const char *str)
  107. {
  108. if (errors)
  109. return;
  110. errors = 1;
  111. agwarningf(" %s in line %d near '%s'\n", str,line_num,yytext);
  112. }
  113. int gmlerrors(void)
  114. {
  115. return errors;
  116. }
  117. void gmllexeof(void) { unput(GRAPH_EOF_TOKEN); }
  118. #ifndef YY_CALL_ONLY_ARG
  119. # define YY_CALL_ONLY_ARG void
  120. #endif
  121. int yywrap(YY_CALL_ONLY_ARG)
  122. {
  123. return 1;
  124. }