bison-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 15/17] multistart: allow tokens as start symbols


From: Akim Demaille
Subject: [PATCH 15/17] multistart: allow tokens as start symbols
Date: Sun, 20 Sep 2020 10:37:47 +0200

After all, why not?

* src/reader.c (switching_token): Use symbol_id_get.
(check_start_symbols): Require that the start symbol is a token only
if it's the only one.
* examples/c/lexcalc/parse.y: Let NUM be a start symbol.
---
 examples/c/lexcalc/parse.y |  2 +-
 src/reader.c               | 11 ++++++-----
 src/symtab.c               | 11 ++++++++---
 3 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/examples/c/lexcalc/parse.y b/examples/c/lexcalc/parse.y
index b3aaf476..59708115 100644
--- a/examples/c/lexcalc/parse.y
+++ b/examples/c/lexcalc/parse.y
@@ -79,7 +79,7 @@
 %type <int> exp expression line
 %printer { fprintf (yyo, "%d", $$); } <int>
 
-%start input expression
+%start input expression NUM
 
 // Precedence (from lowest to highest) and associativity.
 %left "+" "-"
diff --git a/src/reader.c b/src/reader.c
index 1daccc22..4b6575d4 100644
--- a/src/reader.c
+++ b/src/reader.c
@@ -322,7 +322,8 @@ grammar_rule_check_and_complete (symbol_list *r)
       const symbol *start = r->next->next->content.sym;
       if (start->content->type_name)
         obstack_printf (obstack_for_actions,
-                        "{ ]b4_accept([orig %d])[; }",
+                        "{ ]b4_accept([%s%d])[; }",
+                        start->content->class == nterm_sym ? "orig " : "",
                         start->content->number);
       else
         obstack_printf (obstack_for_actions,
@@ -828,9 +829,7 @@ switching_token (const symbol *start)
 {
   char buf[100];
   size_t len = sizeof buf;
-  char *name
-    = asnprintf (buf, &len,
-                 "YY_PARSE_%s", start->alias ? start->alias->tag : start->tag);
+  char *name = asnprintf (buf, &len, "YY_PARSE_%s", symbol_id_get (start));
   if (!name)
     xalloc_die ();
   // Setting the location ensures deterministic symbol numbers.
@@ -871,6 +870,7 @@ create_start_rules (void)
 static void
 check_start_symbols (void)
 {
+  const bool multistart = start_symbols && start_symbols->next;
   // Sanity checks on the start symbols.
   for (symbol_list *list = start_symbols; list; list = list->next)
     {
@@ -885,7 +885,8 @@ check_start_symbols (void)
           // defined as a token and has no rules".
           abort ();
         }
-      if (start->content->class == token_sym)
+      // If your only start symbol is a token, you're weird.
+      if (!multistart && start->content->class == token_sym)
         complain (&start->location, complaint,
                   _("the start symbol %s is a token"),
                   start->tag);
diff --git a/src/symtab.c b/src/symtab.c
index 31a3c048..d0ec50a9 100644
--- a/src/symtab.c
+++ b/src/symtab.c
@@ -305,9 +305,14 @@ is_identifier (uniqstr s)
 uniqstr
 symbol_id_get (symbol const *sym)
 {
-  if (sym->alias)
-    sym = sym->alias;
-  return is_identifier (sym->tag) ? sym->tag : 0;
+  // There's one weird case: YYerror is the alias, and error is the
+  // base symbol.  Return YYerror in that case.
+  if (sym->alias && is_identifier (sym->alias->tag))
+    return sym->alias->tag;
+  else if (is_identifier (sym->tag))
+    return sym->tag;
+  else
+    return NULL;
 }
 
 
-- 
2.28.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]