bison-patches
[Top][All Lists]
Advanced

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

Re: [RFC] %language declaration


From: Paolo Bonzini
Subject: Re: [RFC] %language declaration
Date: Mon, 11 Sep 2006 11:05:36 +0200
User-agent: Thunderbird 1.5.0.5 (Macintosh/20060719)

Paolo Bonzini wrote:
Hi everybody,

I plan to implement a Java skeleton for bison; since (if I have time -- I don't guarantee anything on this part) I would also like to implement GLR parsing for Java, the attached patch attempts to provide a "%language" declaration that wraps over "%skeleton".

Together with %language, there is a -L option to determine the language from the command-line.

-L and -S are mutually exclusive, as are %language and %skeleton, but the command-line options override the grammar directives.

Would something similar, of course with documentation and against mainline rather than 2.0, be ok to apply? The copyright process is in the works.

The now attached patch...

Paolo
2006-09-11  Paolo Bonzini  <address@hidden>

        * src/getargs.c (skeleton_prio, language, valid_languages,
        language_argmatch, skeleton_arg): New.
        (getargs): Use language_argmatch and skeleton_arg.
        * src/getargs.h: Include location.h
        (struct bison_language): New.
        (language): Declare.
        * src/output.c (prepare): Fetch default skeleton names from language.
        * src/parse-gram.y (PERCENT_LANGUAGE): Declare and add rule for it.
        (PERCENT_SKELETON): Call skeleton_arg in its rule.
        * src/scan-gram.l (PERCENT_LANGUAGE): Recognize.

        * tests/calc.at (C++ tests): Test with %language, add a test using
        %skeleton.
        * tests/local.at (_AT_BISON_OPTION_PUSHDEFS): Recognize %language.

diff -rNu --exclude=ppp bison-2.0-orig/src/getargs.c bison-2.0/src/getargs.c
--- bison-2.0-orig/src/getargs.c        2004-06-21 22:20:30.000000000 +0200
+++ bison-2.0/src/getargs.c     2006-09-11 10:02:16.000000000 +0200
@@ -58,6 +58,8 @@
 bool glr_parser = false;
 bool pure_parser = false;
 
+static int skeleton_prio = 999;
+const struct bison_language *language = NULL;
 const char *skeleton = NULL;
 const char *include = NULL;
 
@@ -279,6 +280,75 @@
 }
 
 
+/*-------------------------------------.
+| --skeleton and --language handling.  |
+`--------------------------------------*/
+
+static const struct bison_language valid_languages[] = {
+  { "c", "yacc.c", "glr.c" },
+  { "c++", "lalr1.cc", NULL },
+  { "java", "lalr1.java", NULL },
+  { NULL, NULL, NULL }
+};
+
+void
+skeleton_arg (char *arg, int prio, location *loc)
+{
+  if (skeleton_prio < prio)
+    return;
+  if (skeleton_prio == prio)
+    {
+      const char *msg =
+       _("multiple language or skeleton declarations are invalid");
+      if (loc)
+       {
+         complain_at (*loc, msg);
+          return;
+       }
+      else
+       {
+         error (0, 0, msg);
+         usage (EXIT_FAILURE);
+       }
+    }
+
+  skeleton_prio = prio;
+  skeleton = arg;
+  language = NULL;
+}
+
+void
+language_argmatch (char *args, int prio, location *loc)
+{
+  int i;
+  if (skeleton_prio < prio)
+    return;
+  if (skeleton_prio == prio)
+    {
+      const char *msg =
+       _("multiple language or skeleton declarations are invalid");
+      if (loc)
+       {
+         complain_at (*loc, msg);
+          return;
+       }
+      else
+       {
+         error (0, 0, msg);
+         usage (EXIT_FAILURE);
+       }
+    }
+
+  for (i = 0; valid_languages[i].language; i++)
+    if (!strcasecmp (args, valid_languages[i].language))
+      {
+       skeleton_prio = prio;
+       skeleton = NULL;
+       language = &valid_languages[i];
+       break;
+      }
+}
+
 /*----------------------.
 | Process the options.  |
 `----------------------*/
@@ -327,6 +397,7 @@
   { "no-parser",      no_argument,               0,   'n' },
   { "raw",            no_argument,               0,     0 },
   { "skeleton",       required_argument,         0,   'S' },
+  { "language",       required_argument,         0,   'L' },
   { "token-table",    no_argument,               0,   'k' },
 
   {0, 0, 0, 0}
@@ -375,8 +446,12 @@
        report_flag |= report_states;
        break;
 
+      case 'L':
+       language_argmatch (optarg, 0, NULL);
+       break;
+
       case 'S':
-       skeleton = AS_FILE_NAME (optarg);
+       skeleton_arg (AS_FILE_NAME (optarg), 0, NULL);
        break;
 
       case 'I':
@@ -444,4 +519,10 @@
     }
 
   current_file = grammar_file = uniqstr_new (argv[optind]);
+
+  if (!skeleton && !language)
+    {
+      skeleton_prio = 0;
+      language = &valid_languages[0];
+    }
 }
diff -rNu --exclude=ppp bison-2.0-orig/src/getargs.h bison-2.0/src/getargs.h
--- bison-2.0-orig/src/getargs.h        2004-06-21 22:20:30.000000000 +0200
+++ bison-2.0/src/getargs.h     2006-09-11 10:01:42.000000000 +0200
@@ -22,6 +22,8 @@
 #ifndef GETARGS_H_
 # define GETARGS_H_
 
+#include "location.h"
+
 /* flags set by % directives */
 extern const char *skeleton;           /* for -S */
 extern const char *include;            /* for -I */
@@ -52,6 +54,16 @@
 
 extern bool nondeterministic_parser;
 
+/* --language.  */
+struct bison_language
+{
+  const char *language;
+  const char *lalr1_skeleton;
+  const char *glr_skeleton;
+};
+
+extern const struct bison_language *language;
+
 /* --trace.  */
 enum trace
   {
@@ -84,4 +96,8 @@
 
 void getargs (int argc, char *argv[]);
 
+/* Used by parse-gram.y.  */
+void language_argmatch (char *arg, int prio, location *loc);
+void skeleton_arg (char *arg, int prio, location *loc);
+
 #endif /* !GETARGS_H_ */
diff -rNu --exclude=ppp bison-2.0-orig/src/output.c bison-2.0/src/output.c
--- bison-2.0-orig/src/output.c 2004-12-17 20:56:45.000000000 +0100
+++ bison-2.0/src/output.c      2006-09-11 10:27:53.000000000 +0200
@@ -614,9 +614,14 @@
   if (!skeleton)
     {
       if (glr_parser || nondeterministic_parser)
-       skeleton = "glr.c";
+       {
+         skeleton = language->glr_skeleton;
+         if (!skeleton)
+           error (EXIT_FAILURE, 0,
+                  _("GLR parsing not supported for the selected language"));
+       }
       else
-       skeleton = "yacc.c";
+       skeleton = language->lalr1_skeleton;
     }
 
   /* Parse the skeleton file and output the needed parsers.  */
diff -rNu --exclude=ppp bison-2.0-orig/src/parse-gram.y 
bison-2.0/src/parse-gram.y
--- bison-2.0-orig/src/parse-gram.y     2004-10-09 19:50:26.000000000 +0200
+++ bison-2.0/src/parse-gram.y  2006-09-11 09:50:50.000000000 +0200
@@ -125,6 +125,7 @@
   PERCENT_FILE_PREFIX     "%file-prefix"
   PERCENT_GLR_PARSER      "%glr-parser"
   PERCENT_INITIAL_ACTION  "%initial-action {...}"
+  PERCENT_LANGUAGE        "%language"
   PERCENT_LEX_PARAM       "%lex-param {...}"
   PERCENT_LOCATIONS       "%locations"
   PERCENT_NAME_PREFIX     "%name-prefix"
@@ -203,6 +204,7 @@
   {
     muscle_code_grow ("initial_action", $1, @1);
   }
+| "%language" string_content               { language_argmatch ($2, 1, &@1); }
 | "%lex-param {...}"                      { add_param ("lex_param", $1, @1); }
 | "%locations"                             { locations_flag = true; }
 | "%name-prefix" "=" string_content        { spec_name_prefix = $3; }
@@ -211,7 +213,7 @@
 | "%output" "=" string_content             { spec_outfile = $3; }
 | "%parse-param {...}"                    { add_param ("parse_param", $1, @1); 
}
 | "%pure-parser"                           { pure_parser = true; }
-| "%skeleton" string_content               { skeleton = $2; }
+| "%skeleton" string_content               { skeleton_arg ($2, 1, &@1); }
 | "%token-table"                           { token_table_flag = true; }
 | "%verbose"                               { report_flag = report_states; }
 | "%yacc"                                  { yacc_flag = true; }
diff -rNu --exclude=ppp bison-2.0-orig/src/scan-gram.l bison-2.0/src/scan-gram.l
--- bison-2.0-orig/src/scan-gram.l      2004-08-08 06:57:06.000000000 +0200
+++ bison-2.0/src/scan-gram.l   2006-09-11 09:39:07.000000000 +0200
@@ -195,6 +195,7 @@
   "%fixed"[-_]"output"[-_]"files"   return PERCENT_YACC;
   "%initial-action"       token_type = PERCENT_INITIAL_ACTION; BEGIN 
SC_PRE_CODE;
   "%glr-parser"           return PERCENT_GLR_PARSER;
+  "%language"             return PERCENT_LANGUAGE;
   "%left"                 return PERCENT_LEFT;
   "%lex-param"           token_type = PERCENT_LEX_PARAM; BEGIN SC_PRE_CODE;
   "%locations"            return PERCENT_LOCATIONS;
diff -rNu --exclude=ppp bison-2.0-orig/tests/calc.at bison-2.0/tests/calc.at
--- bison-2.0-orig/tests/calc.at        2004-12-20 21:14:57.000000000 +0100
+++ bison-2.0/tests/calc.at     2006-09-11 10:14:39.000000000 +0200
@@ -596,12 +596,15 @@
 
 AT_BANNER([[Simple LALR1 C++ Calculator.]])
 
+# First let's try using %skeleton.
+AT_CHECK_CALC([%skeleton "lalr1.cc" %defines])
+
 # AT_CHECK_CALC_LALR1_CC([BISON-OPTIONS])
 # ---------------------------------------
 # Start a testing chunk which compiles `calc' grammar with
 # the C++ skeleton, and performs several tests over the parser.
 m4_define([AT_CHECK_CALC_LALR1_CC],
-[AT_CHECK_CALC([%skeleton "lalr1.cc"] $@)])
+[AT_CHECK_CALC([%language "C++"] $@)])
 
 # AT_CHECK_CALC_LALR1_CC()
 
diff -rNu --exclude=ppp bison-2.0-orig/tests/local.at bison-2.0/tests/local.at
--- bison-2.0-orig/tests/local.at       2004-05-30 02:56:56.000000000 +0200
+++ bison-2.0/tests/local.at    2006-09-11 10:32:48.000000000 +0200
@@ -42,12 +42,12 @@
 [m4_if([$1$2], $[1]$[2], [],
        [m4_fatal([$0: Invalid arguments: address@hidden)])dnl
 m4_pushdef([AT_LALR1_CC_IF],
-[m4_bmatch([$3], ["lalr1.cc"], [$1], [$2])])
+[m4_bmatch([$3], [%language "[cC]\+\+"\|%skeleton "lalr1.cc"], [$1], [$2])])
 m4_pushdef([AT_GLR_IF],
 [m4_bmatch([$3], [%glr-parser], [$1], [$2])])
 # Using yacc.c?
 m4_pushdef([AT_YACC_IF],
-[m4_bmatch([$3], [%glr-parser\|%skeleton], [$2], [$1])])
+[m4_bmatch([$3], [%glr-parser\|%language\|%skeleton], [$2], [$1])])
 m4_pushdef([AT_PARAM_IF],
 [m4_bmatch([$3], [%parse-param], [$1], [$2])])
 m4_pushdef([AT_LOCATION_IF],

reply via email to

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