PageRenderTime 39ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/utils/mep/cfg.y

https://bitbucket.org/tari/prizm-binutils
Happy | 170 lines | 145 code | 25 blank | 0 comment | 0 complexity | 28da8bbad46cb9f69b1f8aa800c4e0f5 MD5 | raw file
Possible License(s): LGPL-2.0, BSD-3-Clause, GPL-3.0, AGPL-3.0, LGPL-2.1, GPL-2.0, 0BSD, Unlicense, MPL-2.0-no-copyleft-exception
  1. %{
  2. #include <stdio.h>
  3. #include <stdarg.h>
  4. #include <unistd.h>
  5. #define YYDEBUG 1
  6. #define YYERROR_VERBOSE 1
  7. #include "mepcfgtool.h"
  8. /* Just to be paranoid. */
  9. #ifndef X_OK
  10. #define X_OK 1
  11. #endif
  12. extern int cfglineno;
  13. extern Node *currentcfg;
  14. extern char *cfgfilename;
  15. static int hide_errors = 0;
  16. Node *
  17. new_node (const char *name, Node *sub)
  18. {
  19. Node *n;
  20. n = (Node *) calloc (sizeof (Node), 1);
  21. n->type = N_NONE;
  22. n->id = name;
  23. n->sub = sub;
  24. n->filename = cfgfilename;
  25. n->lineno = cfglineno;
  26. return n;
  27. }
  28. static Node *
  29. intnode (Node *n, int val)
  30. {
  31. n->type = N_NUM;
  32. n->ival = val;
  33. return n;
  34. }
  35. static Node *
  36. strnode (Node *n, char *val)
  37. {
  38. n->type = N_QSTR;
  39. n->val = val;
  40. return n;
  41. }
  42. static Node *
  43. wordnode (Node *n, char *val)
  44. {
  45. n->type = N_WORD;
  46. n->val = val;
  47. return n;
  48. }
  49. static Node *
  50. subnode (Node *n, Node *s, char *name)
  51. {
  52. n->type = N_SUB;
  53. n->sub = s;
  54. n->val = name;
  55. return n;
  56. }
  57. #define CHAIN(up, one, two) if (one) { one->next = two; up = one; } else { up = two; }
  58. %}
  59. %union {
  60. unsigned long num;
  61. char *str;
  62. Node *node;
  63. }
  64. %token <str> STR WORD
  65. %token <num> NUM
  66. %type <node> nodes node word
  67. %%
  68. file:
  69. nodes { currentcfg->sub = $1; currentcfg->type = N_SUB; }
  70. | error
  71. ;
  72. nodes:
  73. node ';' nodes { CHAIN ($$, $1, $3); }
  74. | { $$ = 0; }
  75. ;
  76. node:
  77. word '=' STR { $$ = strnode ($1, $3); }
  78. | word '=' WORD { $$ = wordnode ($1, $3); }
  79. | word '=' NUM { $$ = intnode ($1, $3); }
  80. | word '=' '-' NUM { error ("%s must not be negative", $1->id); $$ = intnode ($1, $4);}
  81. | word '[' WORD ']' '{' nodes '}' { $$ = subnode ($1, $6, $3); }
  82. | word '{' nodes '}' { $$ = subnode ($1, $3, 0); }
  83. ;
  84. word:
  85. WORD { $$ = new_node ($1, 0); }
  86. ;
  87. %%
  88. /* New string must be no longer than old string. */
  89. static const char *swap_strings[][2] = {
  90. { " `$' or `error' or ", " " },
  91. { " `error' or ", " " },
  92. { " `$' or ", " " },
  93. { "`'", "\"" },
  94. { "''", "\"" },
  95. { "'", "\"" },
  96. { "`", "\"" },
  97. { 0, 0 }
  98. };
  99. int
  100. cfgerror (char *s)
  101. {
  102. int ssi, ol, nl;
  103. if (strncmp (s, "parse error", 11) == 0)
  104. {
  105. s += 11;
  106. for (ssi=0; swap_strings[ssi][0]; ssi++)
  107. {
  108. char *old = strstr (s, swap_strings[ssi][0]);
  109. if (old)
  110. {
  111. ol = strlen (swap_strings[ssi][0]);
  112. nl = strlen (swap_strings[ssi][1]);
  113. memcpy (old, swap_strings[ssi][1], nl);
  114. strcpy (old+nl, old+ol);
  115. ssi --;
  116. }
  117. }
  118. switch (yychar)
  119. {
  120. case 0:
  121. error ("Unexpected end-of-file%s", s);
  122. break;
  123. case STR:
  124. error ("Quoted string \"%s\" unexpected here%s", yylval.str, s);
  125. break;
  126. case NUM:
  127. error ("Value \"%s\" unexpected here%s", hex_pr (yylval.num), s);
  128. break;
  129. default:
  130. if (yychar < 255)
  131. {
  132. error ("\"%c\" unexpected here%s", yychar, s);
  133. /* Cause an immediate exit to cfgparse() to avoid
  134. multiple errors; bad punctuation tends to cause them. */
  135. if (*s)
  136. yychar = YYEOF;
  137. }
  138. else
  139. error ("\"%s\" unexpected here%s", yylval.str, s);
  140. break;
  141. }
  142. }
  143. else
  144. error (s);
  145. }