logo

live-bootstrap

Mirror of <https://github.com/fosslinux/live-bootstrap>

parse-gram.c (29442B)


  1. // SPDX-License-Identifier: GPL-3.0-or-later
  2. /*
  3. * This file is based on parse-gram.y from GNU Bison 3.4.1. It
  4. * implements a subset of the grammar described by parse-gram.y, just
  5. * enough to provide a bootstrapping path for Bison.
  6. *
  7. * Copyright (c) 2020, Giovanni Mascellani <gio@debian.org>
  8. *
  9. * The copyright notice of the original file follows. This file is
  10. * distributed under the same license and with the same conditions.
  11. */
  12. /* Bison Grammar Parser -*- C -*-
  13. Copyright (C) 2002-2015, 2018-2019 Free Software Foundation, Inc.
  14. This file is part of Bison, the GNU Compiler Compiler.
  15. This program is free software: you can redistribute it and/or modify
  16. it under the terms of the GNU General Public License as published by
  17. the Free Software Foundation, either version 3 of the License, or
  18. (at your option) any later version.
  19. This program is distributed in the hope that it will be useful,
  20. but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22. GNU General Public License for more details.
  23. You should have received a copy of the GNU General Public License
  24. along with this program. If not, see <http://www.gnu.org/licenses/>. */
  25. /*
  26. * Since this code is intended to provide a bootstrapping path for GNU
  27. * Bison, it is important that it is as easy to understand as
  28. * possible. Fortunately Bison's grammar is rather simple. I believe
  29. * that if you know how Bison works, you should not find it hard to
  30. * follow the logic in this file and compare it with the original
  31. * grammar.
  32. *
  33. * Apart from the code literally copied from the grammar file
  34. * (prologues and epilogue), this file basically contains a few
  35. * wrappers over the lexer interface (the functions gram_*), basically
  36. * adding the feature to give back one lexeme and a lot of functions
  37. * parse_* or maybe_parse_*, parsing the corresponding grammar
  38. * rule. Functions maybe_parse_* are allowed to fail, and return
  39. * accordingly.
  40. *
  41. * Error checking is very simple and just made of assertions. This is
  42. * just boostrapping code, not meant for end users, so it should not
  43. * be a problem.
  44. */
  45. /* %code top */
  46. /* On column 0 to please syntax-check. */
  47. #include <config.h>
  48. #include <assert.h>
  49. #define YYLTYPE GRAM_LTYPE
  50. #include "parse-gram.h"
  51. /* %code */
  52. #include "system.h"
  53. #include <errno.h>
  54. #include "c-ctype.h"
  55. #include "complain.h"
  56. #include "conflicts.h"
  57. #include "files.h"
  58. #include "getargs.h"
  59. #include "gram.h"
  60. #include "named-ref.h"
  61. #include "quotearg.h"
  62. #include "reader.h"
  63. #include "scan-code.h"
  64. #include "scan-gram.h"
  65. #include "vasnprintf.h"
  66. #include "xmemdup0.h"
  67. static int current_prec = 0;
  68. static location current_lhs_loc;
  69. static named_ref *current_lhs_named_ref;
  70. static symbol *current_lhs_symbol;
  71. static symbol_class current_class = unknown_sym;
  72. /** Set the new current left-hand side symbol, possibly common
  73. * to several right-hand side parts of rule.
  74. */
  75. static void current_lhs (symbol *sym, location loc, named_ref *ref);
  76. #define YYLLOC_DEFAULT(Current, Rhs, N) \
  77. (Current) = lloc_default (Rhs, N)
  78. static YYLTYPE lloc_default (YYLTYPE const *, int);
  79. #define YY_LOCATION_PRINT(File, Loc) \
  80. location_print (Loc, File)
  81. /* Strip initial '{' and final '}' (must be first and last characters).
  82. Return the result. */
  83. static char *strip_braces (char *code);
  84. /* Convert CODE by calling code_props_plain_init if PLAIN, otherwise
  85. code_props_symbol_action_init. Call
  86. gram_scanner_last_string_free to release the latest string from
  87. the scanner (should be CODE). */
  88. static char const *translate_code (char *code, location loc, bool plain);
  89. /* Convert CODE by calling code_props_plain_init after having
  90. stripped the first and last characters (expected to be '{', and
  91. '}'). Call gram_scanner_last_string_free to release the latest
  92. string from the scanner (should be CODE). */
  93. static char const *translate_code_braceless (char *code, location loc);
  94. /* Handle a %error-verbose directive. */
  95. static void handle_error_verbose (location const *loc, char const *directive);
  96. /* Handle a %file-prefix directive. */
  97. static void handle_file_prefix (location const *loc,
  98. location const *dir_loc,
  99. char const *directive, char const *value);
  100. /* Handle a %name-prefix directive. */
  101. static void handle_name_prefix (location const *loc,
  102. char const *directive, char const *value);
  103. /* Handle a %pure-parser directive. */
  104. static void handle_pure_parser (location const *loc, char const *directive);
  105. /* Handle a %require directive. */
  106. static void handle_require (location const *loc, char const *version);
  107. /* Handle a %skeleton directive. */
  108. static void handle_skeleton (location const *loc, char const *skel);
  109. /* Handle a %yacc directive. */
  110. static void handle_yacc (location const *loc, char const *directive);
  111. static void gram_error (location const *, char const *);
  112. /* A string that describes a char (e.g., 'a' -> "'a'"). */
  113. static char const *char_name (char);
  114. #define YYTYPE_INT16 int_fast16_t
  115. #define YYTYPE_INT8 int_fast8_t
  116. #define YYTYPE_UINT16 uint_fast16_t
  117. #define YYTYPE_UINT8 uint_fast8_t
  118. /* Add style to semantic values in traces. */
  119. static void tron (FILE *yyo);
  120. static void troff (FILE *yyo);
  121. int gram_debug;
  122. typedef struct {
  123. GRAM_STYPE s;
  124. GRAM_LTYPE l;
  125. int t;
  126. } gram_lex_ctx;
  127. static int gram_lex_wrap(gram_lex_ctx *ctx, GRAM_STYPE *sx, GRAM_LTYPE *lx) {
  128. int type;
  129. if (ctx->t == 0) {
  130. type = gram_lex(&ctx->s, &ctx->l);
  131. } else {
  132. type = ctx->t;
  133. }
  134. /*fprintf(stderr, "%s %d from %s:%d:%d:%d to %s:%d:%d:%d\n",
  135. ctx->t == 0 ? "Scanned" : "Rescanned", type,
  136. ctx->l.start.file, ctx->l.start.line, ctx->l.start.column, ctx->l.start.byte,
  137. ctx->l.end.file, ctx->l.end.line, ctx->l.end.column, ctx->l.end.byte);*/
  138. ctx->t = 0;
  139. if (sx) *sx = ctx->s;
  140. if (lx) *lx = ctx->l;
  141. return type;
  142. }
  143. static int gram_unlex_wrap(gram_lex_ctx *ctx, int t, GRAM_STYPE *s, GRAM_LTYPE *l) {
  144. assert(ctx->t == 0);
  145. ctx->t = t;
  146. ctx->s = *s;
  147. ctx->l = *l;
  148. /*fprintf(stderr, "Unscanned %d from %s:%d:%d:%d to %s:%d:%d:%d\n",
  149. t,
  150. ctx->l.start.file, ctx->l.start.line, ctx->l.start.column, ctx->l.start.byte,
  151. ctx->l.end.file, ctx->l.end.line, ctx->l.end.column, ctx->l.end.byte);*/
  152. }
  153. static void gram_get_last_loc(gram_lex_ctx *ctx, GRAM_LTYPE *l) {
  154. *l = ctx->l;
  155. }
  156. static void parse_value(gram_lex_ctx *ctx, GRAM_STYPE *sx, GRAM_LTYPE *lx) {
  157. GRAM_STYPE s[2];
  158. GRAM_LTYPE l[2];
  159. gram_get_last_loc(ctx, &l[0]);
  160. int t = gram_lex_wrap(ctx, &s[1], &l[1]);
  161. switch (t) {
  162. case ID:
  163. YYLLOC_DEFAULT(*lx, l, 1);
  164. sx->value.kind = muscle_keyword;
  165. sx->value.chars = s[1].ID;
  166. break;
  167. case STRING:
  168. YYLLOC_DEFAULT(*lx, l, 1);
  169. sx->value.kind = muscle_string;
  170. sx->value.chars = s[1].STRING;
  171. break;
  172. case BRACED_CODE:
  173. YYLLOC_DEFAULT(*lx, l, 1);
  174. sx->value.kind = muscle_code;
  175. sx->value.chars = strip_braces(s[1].BRACED_CODE);
  176. break;
  177. default:
  178. gram_unlex_wrap(ctx, t, &s[1], &l[1]);
  179. YYLLOC_DEFAULT(*lx, l, 0);
  180. sx->value.kind = muscle_keyword;
  181. sx->value.chars = "";
  182. break;
  183. }
  184. }
  185. static void parse_int_opt(gram_lex_ctx *ctx, GRAM_STYPE *sx, GRAM_LTYPE *lx) {
  186. GRAM_STYPE s[2];
  187. GRAM_LTYPE l[2];
  188. gram_get_last_loc(ctx, &l[0]);
  189. int t = gram_lex_wrap(ctx, &s[1], &l[1]);
  190. if (t == INT) {
  191. YYLLOC_DEFAULT(*lx, l, 1);
  192. sx->int_opt = s[1].INT;
  193. } else {
  194. gram_unlex_wrap(ctx, t, &s[1], &l[1]);
  195. YYLLOC_DEFAULT(*lx, l, 0);
  196. sx->int_opt = -1;
  197. }
  198. }
  199. static int maybe_parse_string_as_id(gram_lex_ctx *ctx, GRAM_STYPE *sx, GRAM_LTYPE *lx) {
  200. GRAM_STYPE s[2];
  201. GRAM_LTYPE l[2];
  202. int t = gram_lex_wrap(ctx, &s[1], &l[1]);
  203. if (t == STRING) {
  204. YYLLOC_DEFAULT(*lx, l, 1);
  205. sx->string_as_id = symbol_get(quotearg_style(c_quoting_style, s[1].STRING), l[1]);
  206. symbol_class_set(sx->string_as_id, token_sym, l[1], false);
  207. return 1;
  208. } else {
  209. gram_unlex_wrap(ctx, t, &s[1], &l[1]);
  210. return 0;
  211. }
  212. }
  213. static void parse_string_as_id(gram_lex_ctx *ctx, GRAM_STYPE *sx, GRAM_LTYPE *lx) {
  214. int x = maybe_parse_string_as_id(ctx, sx, lx);
  215. assert(x);
  216. }
  217. static void parse_string_as_id_opt(gram_lex_ctx *ctx, GRAM_STYPE *sx, GRAM_LTYPE *lx) {
  218. GRAM_STYPE s[2];
  219. GRAM_LTYPE l[2];
  220. gram_get_last_loc(ctx, &l[0]);
  221. int x = maybe_parse_string_as_id(ctx, &s[1], &l[1]);
  222. if (x) {
  223. YYLLOC_DEFAULT(*lx, l, 1);
  224. sx->string_as_id_opt = s[1].string_as_id;
  225. } else {
  226. YYLLOC_DEFAULT(*lx, l, 0);
  227. sx->string_as_id_opt = NULL;
  228. }
  229. }
  230. static int maybe_parse_id(gram_lex_ctx *ctx, GRAM_STYPE *sx, GRAM_LTYPE *lx) {
  231. GRAM_STYPE s[2];
  232. GRAM_LTYPE l[2];
  233. gram_get_last_loc(ctx, &l[0]);
  234. int t = gram_lex_wrap(ctx, &s[1], &l[1]);
  235. if (t == ID) {
  236. YYLLOC_DEFAULT(*lx, l, 1);
  237. sx->id = symbol_from_uniqstr(s[1].ID, l[1]);
  238. return 1;
  239. } else {
  240. gram_unlex_wrap(ctx, t, &s[1], &l[1]);
  241. return 0;
  242. }
  243. }
  244. static void parse_id(gram_lex_ctx *ctx, GRAM_STYPE *sx, GRAM_LTYPE *lx) {
  245. int x = maybe_parse_id(ctx, sx, lx);
  246. assert(x);
  247. }
  248. static void parse_token_decl(gram_lex_ctx *ctx, GRAM_STYPE *sx, GRAM_LTYPE *lx) {
  249. GRAM_STYPE s[4];
  250. GRAM_LTYPE l[4];
  251. parse_id(ctx, &s[1], &l[1]);
  252. parse_int_opt(ctx, &s[2], &l[2]);
  253. parse_string_as_id_opt(ctx, &s[3], &l[3]);
  254. YYLLOC_DEFAULT(*lx, l, 3);
  255. sx->token_decl = s[1].id;
  256. symbol_class_set(s[1].id, current_class, l[1], true);
  257. if (0 <= s[2].int_opt)
  258. symbol_user_token_number_set(s[1].id, s[2].int_opt, l[2]);
  259. if (s[3].string_as_id_opt)
  260. symbol_make_alias(s[1].id, s[3].string_as_id_opt, l[3]);
  261. }
  262. static int maybe_parse_token_decl_1(gram_lex_ctx *ctx, GRAM_STYPE *sx, GRAM_LTYPE *lx) {
  263. GRAM_STYPE s[3];
  264. GRAM_LTYPE l[3];
  265. int t = gram_lex_wrap(ctx, &s[1], &l[1]);
  266. gram_unlex_wrap(ctx, t, &s[1], &l[1]);
  267. if (t != ID) {
  268. return 0;
  269. }
  270. parse_token_decl(ctx, &s[1], &l[1]);
  271. YYLLOC_DEFAULT(*lx, l, 1);
  272. sx->token_decl_1 = symbol_list_sym_new(s[1].token_decl, l[1]);
  273. while (1) {
  274. int t = gram_lex_wrap(ctx, &s[1], &l[1]);
  275. gram_unlex_wrap(ctx, t, &s[1], &l[1]);
  276. if (t != ID) {
  277. return 1;
  278. }
  279. s[1] = *sx;
  280. l[1] = *lx;
  281. parse_token_decl(ctx, &s[2], &l[2]);
  282. YYLLOC_DEFAULT(*lx, l, 2);
  283. sx->token_decl_1 = symbol_list_append(s[1].token_decl_1, symbol_list_sym_new(s[2].token_decl, l[2]));
  284. }
  285. }
  286. static void parse_token_decl_1(gram_lex_ctx *ctx, GRAM_STYPE *sx, GRAM_LTYPE *lx) {
  287. int x = maybe_parse_token_decl_1(ctx, sx, lx);
  288. assert(x);
  289. }
  290. static void parse_token_decls(gram_lex_ctx *ctx, GRAM_STYPE *sx, GRAM_LTYPE *lx) {
  291. GRAM_STYPE s[4];
  292. GRAM_LTYPE l[4];
  293. int begin_with_tokens = maybe_parse_token_decl_1(ctx, &s[1], &l[1]);
  294. if (begin_with_tokens) {
  295. YYLLOC_DEFAULT(*lx, l, 1);
  296. sx->token_decls = s[1].token_decl_1;
  297. } else {
  298. int t = gram_lex_wrap(ctx, &s[1], &l[1]);
  299. assert(t == TAG);
  300. parse_token_decl_1(ctx, &s[2], &l[2]);
  301. YYLLOC_DEFAULT(*lx, l, 2);
  302. sx->token_decls = symbol_list_type_set(s[2].token_decl_1, s[1].TAG, l[1]);
  303. }
  304. while (1) {
  305. s[1] = *sx;
  306. l[1] = *lx;
  307. int t = gram_lex_wrap(ctx, &s[2], &l[2]);
  308. if (t != TAG) {
  309. gram_unlex_wrap(ctx, t, &s[2], &l[2]);
  310. return;
  311. }
  312. parse_token_decl_1(ctx, &s[3], &l[3]);
  313. YYLLOC_DEFAULT(*lx, l, 3);
  314. sx->token_decls = symbol_list_append(s[1].token_decls, symbol_list_type_set(s[3].token_decl_1, s[2].TAG, l[2]));
  315. }
  316. }
  317. static int maybe_parse_symbol(gram_lex_ctx *ctx, GRAM_STYPE *sx, GRAM_LTYPE *lx) {
  318. GRAM_STYPE s[2];
  319. GRAM_LTYPE l[2];
  320. int x = maybe_parse_string_as_id(ctx, &s[1], &l[1]);
  321. if (x) {
  322. YYLLOC_DEFAULT(*lx, l, 1);
  323. sx->symbol = s[1].string_as_id;
  324. return 1;
  325. }
  326. x = maybe_parse_id(ctx, &s[1], &l[1]);
  327. if (x) {
  328. YYLLOC_DEFAULT(*lx, l, 1);
  329. sx->symbol = s[1].id;
  330. return 1;
  331. }
  332. return 0;
  333. }
  334. static void parse_symbol(gram_lex_ctx *ctx, GRAM_STYPE *sx, GRAM_LTYPE *lx) {
  335. int x = maybe_parse_symbol(ctx, sx, lx);
  336. assert(x);
  337. }
  338. static int maybe_parse_symbol_decl_1(gram_lex_ctx *ctx, GRAM_STYPE *sx, GRAM_LTYPE *lx) {
  339. GRAM_STYPE s[3];
  340. GRAM_LTYPE l[3];
  341. int x = maybe_parse_symbol(ctx, &s[1], &l[1]);
  342. if (!x) {
  343. return 0;
  344. }
  345. YYLLOC_DEFAULT(*lx, l, 1);
  346. sx->symbol_decl_1 = symbol_list_sym_new(s[1].symbol, l[1]);
  347. while (1) {
  348. s[1] = *sx;
  349. l[1] = *lx;
  350. x = maybe_parse_symbol(ctx, &s[2], &l[2]);
  351. if (!x) {
  352. return 1;
  353. }
  354. YYLLOC_DEFAULT(*lx, l, 2);
  355. sx->symbol_decl_1 = symbol_list_append(s[1].symbol_decl_1, symbol_list_sym_new(s[2].symbol, l[2]));
  356. }
  357. }
  358. static void parse_symbol_decl_1(gram_lex_ctx *ctx, GRAM_STYPE *sx, GRAM_LTYPE *lx) {
  359. int x = maybe_parse_symbol_decl_1(ctx, sx, lx);
  360. assert(x);
  361. }
  362. static void parse_symbol_decls(gram_lex_ctx *ctx, GRAM_STYPE *sx, GRAM_LTYPE *lx) {
  363. GRAM_STYPE s[4];
  364. GRAM_LTYPE l[4];
  365. int begin_with_tokens = maybe_parse_symbol_decl_1(ctx, &s[1], &l[1]);
  366. if (begin_with_tokens) {
  367. YYLLOC_DEFAULT(*lx, l, 1);
  368. sx->symbol_decls = s[1].symbol_decl_1;
  369. } else {
  370. int t = gram_lex_wrap(ctx, &s[1], &l[1]);
  371. assert(t == TAG);
  372. parse_symbol_decl_1(ctx, &s[2], &l[2]);
  373. YYLLOC_DEFAULT(*lx, l, 2);
  374. sx->symbol_decls = symbol_list_type_set(s[2].symbol_decl_1, s[1].TAG, l[1]);
  375. }
  376. while (1) {
  377. s[1] = *sx;
  378. l[1] = *lx;
  379. int t = gram_lex_wrap(ctx, &s[2], &l[2]);
  380. if (t != TAG) {
  381. gram_unlex_wrap(ctx, t, &s[2], &l[2]);
  382. return;
  383. }
  384. parse_symbol_decl_1(ctx, &s[3], &l[3]);
  385. YYLLOC_DEFAULT(*lx, l, 3);
  386. sx->symbol_decls = symbol_list_append(s[1].symbol_decls, symbol_list_type_set(s[3].symbol_decl_1, s[2].TAG, l[2]));
  387. }
  388. }
  389. static int maybe_parse_declaration(gram_lex_ctx *ctx, int prologue) {
  390. GRAM_STYPE s[4];
  391. GRAM_LTYPE l[4];
  392. int t[4];
  393. t[1] = gram_lex_wrap(ctx, &s[1], &l[1]);
  394. if (prologue) {
  395. switch (t[1]) {
  396. /* Prologue declarations */
  397. case PERCENT_DEFINE:
  398. t[2] = gram_lex_wrap(ctx, &s[2], &l[2]);
  399. assert(t[2] == ID);
  400. parse_value(ctx, &s[3], &l[3]);
  401. YYLLOC_DEFAULT(l[0], l, 3);
  402. muscle_percent_define_insert(s[2].ID, l[0], s[3].value.kind, s[3].value.chars,
  403. MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE);
  404. return 1;
  405. case PERCENT_DEFINES:
  406. defines_flag = true;
  407. return 1;
  408. case PERCENT_EXPECT:
  409. t[2] = gram_lex_wrap(ctx, &s[2], &l[2]);
  410. assert(t[2] == INT);
  411. expected_sr_conflicts = s[2].INT;
  412. return 1;
  413. case PERCENT_INITIAL_ACTION:
  414. t[2] = gram_lex_wrap(ctx, &s[2], &l[2]);
  415. assert(t[2] == BRACED_CODE);
  416. muscle_code_grow("initial_action", translate_code(s[2].BRACED_CODE, l[2], false), l[2]);
  417. code_scanner_last_string_free();
  418. return 1;
  419. case PERCENT_VERBOSE:
  420. report_flag |= report_states;
  421. return 1;
  422. case SEMICOLON:
  423. return 1;
  424. }
  425. }
  426. switch (t[1]) {
  427. /* Grammar declarations */
  428. case PERCENT_CODE:
  429. t[2] = gram_lex_wrap(ctx, &s[2], &l[2]);
  430. if (t[2] == ID) {
  431. t[3] = gram_lex_wrap(ctx, &s[3], &l[3]);
  432. assert(t[3] == BRACED_CODE);
  433. muscle_percent_code_grow(s[2].ID, l[2], translate_code_braceless(s[3].BRACED_CODE, l[3]), l[3]);
  434. code_scanner_last_string_free();
  435. } else {
  436. assert(t[2] == BRACED_CODE);
  437. muscle_code_grow("percent_code()", translate_code_braceless(s[2].BRACED_CODE, l[2]), l[2]);
  438. code_scanner_last_string_free();
  439. }
  440. return 1;
  441. /* Symbol declarations */
  442. case PERCENT_TOKEN:
  443. current_class = token_sym;
  444. parse_token_decls(ctx, &s[2], &l[2]);
  445. current_class = unknown_sym;
  446. symbol_list_free(s[2].token_decls);
  447. return 1;
  448. case PERCENT_TYPE:
  449. parse_symbol_decls(ctx, &s[2], &l[2]);
  450. symbol_list_free(s[2].symbol_decls);
  451. return 1;
  452. case PERCENT_PERCENT:
  453. return 2;
  454. default:
  455. gram_unlex_wrap(ctx, t[1], &s[1], &l[1]);
  456. return 0;
  457. }
  458. }
  459. static void parse_prologue_declarations(gram_lex_ctx *ctx) {
  460. while (1) {
  461. int x = maybe_parse_declaration(ctx, 1);
  462. assert(x);
  463. if (x == 2) {
  464. return;
  465. }
  466. }
  467. }
  468. static void parse_id_colon(gram_lex_ctx *ctx, GRAM_STYPE *sx, GRAM_LTYPE *lx) {
  469. GRAM_STYPE s[2];
  470. GRAM_LTYPE l[2];
  471. int t = gram_lex_wrap(ctx, &s[1], &l[1]);
  472. assert(t == ID_COLON);
  473. YYLLOC_DEFAULT(*lx, l, 1);
  474. sx->id_colon = symbol_from_uniqstr(s[1].ID_COLON, l[1]);
  475. }
  476. static void parse_named_ref_opt(gram_lex_ctx *ctx, GRAM_STYPE *sx, GRAM_LTYPE *lx) {
  477. GRAM_STYPE s[2];
  478. GRAM_LTYPE l[2];
  479. gram_get_last_loc(ctx, &l[0]);
  480. int t = gram_lex_wrap(ctx, &s[1], &l[1]);
  481. if (t == BRACKETED_ID) {
  482. YYLLOC_DEFAULT(*lx, l, 1);
  483. sx->named_ref_opt = named_ref_new(s[1].BRACKETED_ID, l[1]);
  484. } else {
  485. gram_unlex_wrap(ctx, t, &s[1], &l[1]);
  486. YYLLOC_DEFAULT(*lx, l, 0);
  487. sx->named_ref_opt = NULL;
  488. }
  489. }
  490. static void parse_rhs(gram_lex_ctx *ctx, GRAM_STYPE *sx, GRAM_LTYPE *lx) {
  491. GRAM_STYPE s[5];
  492. GRAM_LTYPE l[5];
  493. gram_get_last_loc(ctx, &l[0]);
  494. YYLLOC_DEFAULT(*lx, l, 0);
  495. grammar_current_rule_begin(current_lhs_symbol, current_lhs_loc, current_lhs_named_ref);
  496. while (1) {
  497. s[1] = *sx;
  498. l[1] = *lx;
  499. int x = maybe_parse_symbol(ctx, &s[2], &l[2]);
  500. if (x) {
  501. parse_named_ref_opt(ctx, &s[3], &l[3]);
  502. YYLLOC_DEFAULT(*lx, l, 3);
  503. grammar_current_rule_symbol_append(s[2].symbol, l[2], s[3].named_ref_opt);
  504. } else {
  505. int t = gram_lex_wrap(ctx, &s[2], &l[2]);
  506. switch (t) {
  507. case BRACED_CODE:
  508. /* Probably good */
  509. s[3] = s[2];
  510. l[3] = l[2];
  511. s[2].tag_opt = NULL;
  512. l[2] = l[1];
  513. parse_named_ref_opt(ctx, &s[4], &l[4]);
  514. YYLLOC_DEFAULT(*lx, l, 4);
  515. grammar_current_rule_action_append(s[3].BRACED_CODE, l[3], s[4].named_ref_opt, s[2].tag_opt);
  516. break;
  517. case PERCENT_EMPTY:
  518. YYLLOC_DEFAULT(*lx, l, 2);
  519. grammar_current_rule_empty_set(l[2]);
  520. break;
  521. default:
  522. gram_unlex_wrap(ctx, t, &s[2], &l[2]);
  523. return;
  524. }
  525. }
  526. }
  527. }
  528. static void parse_rhses_1(gram_lex_ctx *ctx, GRAM_STYPE *sx, GRAM_LTYPE *lx) {
  529. GRAM_STYPE s[4];
  530. GRAM_LTYPE l[4];
  531. parse_rhs(ctx, &s[1], &l[1]);
  532. YYLLOC_DEFAULT(*lx, l, 1);
  533. grammar_current_rule_end(l[1]);
  534. while (1) {
  535. s[1] = *sx;
  536. l[1] = *lx;
  537. int t = gram_lex_wrap(ctx, &s[2], &l[2]);
  538. switch (t) {
  539. case PIPE:
  540. parse_rhs(ctx, &s[3], &l[3]);
  541. YYLLOC_DEFAULT(*lx, l, 3);
  542. grammar_current_rule_end(l[3]);
  543. break;
  544. case SEMICOLON:
  545. YYLLOC_DEFAULT(*lx, l, 2);
  546. break;
  547. default:
  548. gram_unlex_wrap(ctx, t, &s[2], &l[2]);
  549. return;
  550. }
  551. }
  552. }
  553. static void parse_rules(gram_lex_ctx *ctx) {
  554. GRAM_STYPE s[6];
  555. GRAM_LTYPE l[6];
  556. parse_id_colon(ctx, &s[1], &l[1]);
  557. parse_named_ref_opt(ctx, &s[2], &l[2]);
  558. gram_get_last_loc(ctx, &l[3]);
  559. current_lhs(s[1].id_colon, l[1], s[2].named_ref_opt);
  560. int t = gram_lex_wrap(ctx, &s[4], &l[4]);
  561. assert(t == COLON);
  562. parse_rhses_1(ctx, &s[5], &l[5]);
  563. current_lhs(0, l[1], 0);
  564. }
  565. static void parse_grammar(gram_lex_ctx *ctx) {
  566. while (1) {
  567. int x = maybe_parse_declaration(ctx, 0);
  568. if (x == 1) {
  569. int t = gram_lex_wrap(ctx, NULL, NULL);
  570. assert(t == SEMICOLON);
  571. } if (x == 2) {
  572. return;
  573. } else if (x == 0) {
  574. parse_rules(ctx);
  575. }
  576. }
  577. }
  578. static void parse_epilogue(gram_lex_ctx *ctx) {
  579. GRAM_STYPE s;
  580. GRAM_LTYPE l;
  581. int t = gram_lex_wrap(ctx, &s, &l);
  582. assert(t == EPILOGUE);
  583. muscle_code_grow("epilogue", translate_code(s.EPILOGUE, l, true), l);
  584. code_scanner_last_string_free();
  585. }
  586. int gram_parse(void) {
  587. gram_lex_ctx ctx = {};
  588. boundary_set(&ctx.l.start, current_file, 1, 1, 1);
  589. boundary_set(&ctx.l.end, current_file, 1, 1, 1);
  590. parse_prologue_declarations(&ctx);
  591. parse_grammar(&ctx);
  592. parse_epilogue(&ctx);
  593. assert(gram_lex_wrap(&ctx, NULL, NULL) == 0);
  594. return 0;
  595. }
  596. // Epilogue
  597. /* Return the location of the left-hand side of a rule whose
  598. right-hand side is RHS[1] ... RHS[N]. Ignore empty nonterminals in
  599. the right-hand side, and return an empty location equal to the end
  600. boundary of RHS[0] if the right-hand side is empty. */
  601. static YYLTYPE
  602. lloc_default (YYLTYPE const *rhs, int n)
  603. {
  604. YYLTYPE loc;
  605. /* SGI MIPSpro 7.4.1m miscompiles "loc.start = loc.end = rhs[n].end;".
  606. The bug is fixed in 7.4.2m, but play it safe for now. */
  607. loc.start = rhs[n].end;
  608. loc.end = rhs[n].end;
  609. /* Ignore empty nonterminals the start of the right-hand side.
  610. Do not bother to ignore them at the end of the right-hand side,
  611. since empty nonterminals have the same end as their predecessors. */
  612. for (int i = 1; i <= n; i++)
  613. if (! equal_boundaries (rhs[i].start, rhs[i].end))
  614. {
  615. loc.start = rhs[i].start;
  616. break;
  617. }
  618. return loc;
  619. }
  620. static
  621. char *strip_braces (char *code)
  622. {
  623. code[strlen (code) - 1] = 0;
  624. return code + 1;
  625. }
  626. static
  627. char const *
  628. translate_code (char *code, location loc, bool plain)
  629. {
  630. code_props plain_code;
  631. if (plain)
  632. code_props_plain_init (&plain_code, code, loc);
  633. else
  634. code_props_symbol_action_init (&plain_code, code, loc);
  635. code_props_translate_code (&plain_code);
  636. gram_scanner_last_string_free ();
  637. return plain_code.code;
  638. }
  639. static
  640. char const *
  641. translate_code_braceless (char *code, location loc)
  642. {
  643. return translate_code (strip_braces (code), loc, true);
  644. }
  645. static void
  646. add_param (param_type type, char *decl, location loc)
  647. {
  648. static char const alphanum[26 + 26 + 1 + 10 + 1] =
  649. "abcdefghijklmnopqrstuvwxyz"
  650. "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  651. "_"
  652. "0123456789";
  653. char const *name_start = NULL;
  654. {
  655. char *p;
  656. /* Stop on last actual character. */
  657. for (p = decl; p[1]; p++)
  658. if ((p == decl
  659. || ! memchr (alphanum, p[-1], sizeof alphanum - 1))
  660. && memchr (alphanum, p[0], sizeof alphanum - 10 - 1))
  661. name_start = p;
  662. /* Strip the surrounding '{' and '}', and any blanks just inside
  663. the braces. */
  664. --p;
  665. while (c_isspace ((unsigned char) *p))
  666. --p;
  667. p[1] = '\0';
  668. ++decl;
  669. while (c_isspace ((unsigned char) *decl))
  670. ++decl;
  671. }
  672. if (! name_start)
  673. complain (&loc, complaint, _("missing identifier in parameter declaration"));
  674. else
  675. {
  676. char *name = xmemdup0 (name_start, strspn (name_start, alphanum));
  677. if (type & param_lex)
  678. muscle_pair_list_grow ("lex_param", decl, name);
  679. if (type & param_parse)
  680. muscle_pair_list_grow ("parse_param", decl, name);
  681. free (name);
  682. }
  683. gram_scanner_last_string_free ();
  684. }
  685. static void
  686. handle_error_verbose (location const *loc, char const *directive)
  687. {
  688. bison_directive (loc, directive);
  689. muscle_percent_define_insert (directive, *loc, muscle_keyword, "",
  690. MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE);
  691. }
  692. static void
  693. handle_file_prefix (location const *loc,
  694. location const *dir_loc,
  695. char const *directive, char const *value)
  696. {
  697. bison_directive (loc, directive);
  698. bool warned = false;
  699. if (location_empty (spec_file_prefix_loc))
  700. {
  701. spec_file_prefix_loc = *loc;
  702. spec_file_prefix = value;
  703. }
  704. else
  705. {
  706. duplicate_directive (directive, spec_file_prefix_loc, *loc);
  707. warned = true;
  708. }
  709. if (!warned
  710. && STRNEQ (directive, "%file-prefix"))
  711. deprecated_directive (dir_loc, directive, "%file-prefix");
  712. }
  713. static void
  714. handle_name_prefix (location const *loc,
  715. char const *directive, char const *value)
  716. {
  717. bison_directive (loc, directive);
  718. char buf1[1024];
  719. size_t len1 = sizeof (buf1);
  720. char *old = asnprintf (buf1, &len1, "%s\"%s\"", directive, value);
  721. if (!old)
  722. xalloc_die ();
  723. if (location_empty (spec_name_prefix_loc))
  724. {
  725. spec_name_prefix = value;
  726. spec_name_prefix_loc = *loc;
  727. char buf2[1024];
  728. size_t len2 = sizeof (buf2);
  729. char *new = asnprintf (buf2, &len2, "%%define api.prefix {%s}", value);
  730. if (!new)
  731. xalloc_die ();
  732. deprecated_directive (loc, old, new);
  733. if (new != buf2)
  734. free (new);
  735. }
  736. else
  737. duplicate_directive (old, spec_file_prefix_loc, *loc);
  738. if (old != buf1)
  739. free (old);
  740. }
  741. static void
  742. handle_pure_parser (location const *loc, char const *directive)
  743. {
  744. bison_directive (loc, directive);
  745. deprecated_directive (loc, directive, "%define api.pure");
  746. muscle_percent_define_insert ("api.pure", *loc, muscle_keyword, "",
  747. MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE);
  748. }
  749. static void
  750. handle_require (location const *loc, char const *version)
  751. {
  752. /* Changes of behavior are only on minor version changes, so "3.0.5"
  753. is the same as "3.0". */
  754. errno = 0;
  755. char* cp = NULL;
  756. unsigned long major = strtoul (version, &cp, 10);
  757. if (errno || *cp != '.')
  758. {
  759. complain (loc, complaint, _("invalid version requirement: %s"),
  760. version);
  761. return;
  762. }
  763. ++cp;
  764. unsigned long minor = strtoul (cp, NULL, 10);
  765. if (errno)
  766. {
  767. complain (loc, complaint, _("invalid version requirement: %s"),
  768. version);
  769. return;
  770. }
  771. required_version = major * 100 + minor;
  772. /* Pretend to be at least 3.4, to check features published in 3.4
  773. while developping it. */
  774. const char* api_version = "3.4";
  775. const char* package_version =
  776. strverscmp (api_version, PACKAGE_VERSION) > 0
  777. ? api_version : PACKAGE_VERSION;
  778. if (strverscmp (version, package_version) > 0)
  779. {
  780. complain (loc, complaint, _("require bison %s, but have %s"),
  781. version, package_version);
  782. exit (EX_MISMATCH);
  783. }
  784. }
  785. static void
  786. handle_skeleton (location const *loc, char const *skel)
  787. {
  788. char const *skeleton_user = skel;
  789. if (strchr (skeleton_user, '/'))
  790. {
  791. size_t dir_length = strlen (current_file);
  792. while (dir_length && current_file[dir_length - 1] != '/')
  793. --dir_length;
  794. while (dir_length && current_file[dir_length - 1] == '/')
  795. --dir_length;
  796. char *skeleton_build =
  797. xmalloc (dir_length + 1 + strlen (skeleton_user) + 1);
  798. if (dir_length > 0)
  799. {
  800. memcpy (skeleton_build, current_file, dir_length);
  801. skeleton_build[dir_length++] = '/';
  802. }
  803. strcpy (skeleton_build + dir_length, skeleton_user);
  804. skeleton_user = uniqstr_new (skeleton_build);
  805. free (skeleton_build);
  806. }
  807. skeleton_arg (skeleton_user, grammar_prio, *loc);
  808. }
  809. static void
  810. handle_yacc (location const *loc, char const *directive)
  811. {
  812. bison_directive (loc, directive);
  813. bool warned = false;
  814. if (location_empty (yacc_loc))
  815. yacc_loc = *loc;
  816. else
  817. {
  818. duplicate_directive (directive, yacc_loc, *loc);
  819. warned = true;
  820. }
  821. if (!warned
  822. && STRNEQ (directive, "%fixed-output-files")
  823. && STRNEQ (directive, "%yacc"))
  824. deprecated_directive (loc, directive, "%fixed-output-files");
  825. }
  826. static void
  827. gram_error (location const *loc, char const *msg)
  828. {
  829. complain (loc, complaint, "%s", msg);
  830. }
  831. static char const *
  832. char_name (char c)
  833. {
  834. if (c == '\'')
  835. return "'\\''";
  836. else
  837. {
  838. char buf[4];
  839. buf[0] = '\''; buf[1] = c; buf[2] = '\''; buf[3] = '\0';
  840. return quotearg_style (escape_quoting_style, buf);
  841. }
  842. }
  843. static
  844. void
  845. current_lhs (symbol *sym, location loc, named_ref *ref)
  846. {
  847. current_lhs_symbol = sym;
  848. current_lhs_loc = loc;
  849. if (sym)
  850. symbol_location_as_lhs_set (sym, loc);
  851. /* In order to simplify memory management, named references for lhs
  852. are always assigned by deep copy into the current symbol_list
  853. node. This is because a single named-ref in the grammar may
  854. result in several uses when the user factors lhs between several
  855. rules using "|". Therefore free the parser's original copy. */
  856. free (current_lhs_named_ref);
  857. current_lhs_named_ref = ref;
  858. }
  859. static void tron (FILE *yyo)
  860. {
  861. begin_use_class ("value", yyo);
  862. }
  863. static void troff (FILE *yyo)
  864. {
  865. end_use_class ("value", yyo);
  866. }