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

[enh][patch] Multiple sablecc on single JVM



Hi,

Correct me please if I am wrong, but it seems to me that SableCC does not
rely on any tricks with static code/classes, and as such it is safe to run
it sequentially multiple times using single JVM. Right? 

There are two major obvious advantages for running parser generator on
multiple grammar files on single JVM
1) there is no overhead with loading JVM itself all over again
2) easy integration with other Java-based tools, in particular build tools

I did small and trivial change to:
ca.mcgill.sable.sablecc.SableCC.java
to enable calling parser generation mutliple times from single JVM,
with the propagation of exceptions to the calling entity. 
With the current version of SableCC 2.13 (and earlier) it is not possible,
as:

 finally
 {
      System.exit(0);
 }

forces JVM to quit after succesfull parser generation and
ca.mcgill.sable.sablecc..SableCC.main() catches all exceptions and
forces JVM to quit as well. Btw what is the rationale for doing:

 finally
 {         
      System.exit(0);
 }     

?

If the proposed patch will be incorporated into SableCC, I have working
task definition for ANT, which can be of interest to people 
using both ANT and SableCC. (And as soon SableCC can be used this way I
will post the patch for ANT here and to the ANT effort).

ps.
ANT is a part of jakarta project and it is pure Java-based build tool with
easy integration of other tools and extensions based on Java classes. We
are using it in local projects as a build tool for automatic 
* idl compilation
* parser generation (of course using SableCC)
* class compilation
* javadoc generation
* preparing jars, packing 
* copying files, preparing distributions, etc, etc...

My patch for ANT enables developers to use SableCC in their projects for
parser generation in easy and unified way, and gives easy to use
enhancement for their build tool of choice (i.e. ANT  ;o) with their
compiler compiler of choice (i.e. SableCC ;o)


with best regards

Mariusz Nowostawski
Research Fellow -- Information Science Dep  -- University of Otago, NZ
Phone (work): +64 3 479 8317   Phone (home): +64 3 473 8693
Fax: +64 3 479 8311
*** old/ca/mcgill/sable/sablecc/SableCC.java	Sat Mar  4 21:43:00 2000
--- new/ca/mcgill/sable/sablecc/SableCC.java	Wed May  3 11:21:41 2000
***************
*** 39,48 ****
--- 39,49 ----
      {
          System.out.println("Usage:");
          System.out.println("  java SableCC [-d destination] filename");
          System.out.println("  java SableCC -license");
      }
+ 
      public static void main(String[] arguments)
      {
          String d_option = null;
          String filename = null;
  
***************
*** 97,173 ****
              }
          }
  
          try
          {
!             // Get the grammar description file
! 
!             File in;
!             File dir;
! 
!             in = new File(filename);
!             in = new File(in.getAbsolutePath());
! 
!             if(d_option == null)
!             {
!                 dir = new File(in.getParent());
!             }
!             else
!             {
!                 dir = new File(d_option);
!                 dir = new File(dir.getAbsolutePath());
!             }
! 
!             FileReader temp;
! 
!             // Build the AST
!             Start tree = new Parser(new Lexer(new BufferedReader(
!                 temp = new FileReader(in)))).parse();
! 
!             temp.close();
! 
!             System.out.println("Verifying identifiers.");
!             ResolveIds ids = new ResolveIds(dir);
!             tree.apply(ids);
! 
!             // Create the node.* and analysis.* files
!             System.out.println("Generating token classes.");
!             tree.apply(new GenTokens(ids));
! 
!             System.out.println("Generating production classes.");
!             tree.apply(new GenProds(ids));
! 
!             System.out.println("Generating alternative classes.");
!             tree.apply(new GenAlts(ids));
! 
!             System.out.println("Generating analysis classes.");
!             tree.apply(new GenAnalyses(ids));
! 
!             System.out.println("Generating utility classes.");
!             tree.apply(new GenUtils(ids));
! 
!             try
!             {
!                 System.out.println("Generating the lexer.");
!                 tree.apply(new GenLexer(ids));
!             }
!             catch(Exception e)
!             {
!                 System.out.println(e.getMessage());
!             }
! 
!             try
!             {
!                 System.out.println("Generating the parser.");
!                 tree.apply(new GenParser(ids));
!             }
!             catch(Exception e)
!             {
!                 System.out.println(e.getMessage());
!             }
!         }
!         catch(Exception e)
          {
              System.out.println(e);
              System.exit(1);
          }
          catch(Throwable e)
--- 98,109 ----
              }
          }
  
          try
          {
!           processGrammar(filename, d_option);
!         }catch(Exception e)
          {
              System.out.println(e);
              System.exit(1);
          }
          catch(Throwable e)
***************
*** 178,184 ****
--- 114,205 ----
          finally
          {
              System.exit(0);
          }
      }
+ 
+   /**
+    * The main method for processing grammar file and generating the parser/lexer. 
+    * @param in input grammar file
+    * @param dir output directory
+    */
+   public static void processGrammar(String grammar, String destDir) throws Exception, Throwable 
+   {
+       File in;
+       File dir;
+ 
+       in = new File(grammar);
+       in = new File(in.getAbsolutePath());
+     
+       if(destDir == null)
+       {
+           dir = new File(in.getParent());
+       }
+       else
+       {
+           dir = new File(destDir);
+           dir = new File(dir.getAbsolutePath());
+       }
+     
+       processGrammar(in, dir);
+   }
+ 
+   /**
+    * The main method for processing grammar file and generating the parser/lexer. 
+    * @param in input grammar file
+    * @param dir output directory
+    */
+   public static void processGrammar(File in,  File dir) throws Exception, Throwable 
+   {
+       FileReader temp;
+     
+       // Build the AST
+       Start tree = new Parser(new Lexer(new BufferedReader(
+                  temp = new FileReader(in)))).parse();
+       temp.close();
+ 
+       System.out.println("Verifying identifiers.");
+       ResolveIds ids = new ResolveIds(dir);
+       tree.apply(ids);
+ 
+       // Create the node.* and analysis.* files
+       System.out.println("Generating token classes.");
+       tree.apply(new GenTokens(ids));
+ 
+       System.out.println("Generating production classes.");
+       tree.apply(new GenProds(ids));
+ 
+       System.out.println("Generating alternative classes.");
+       tree.apply(new GenAlts(ids));
+ 
+       System.out.println("Generating analysis classes.");
+       tree.apply(new GenAnalyses(ids));
+ 
+       System.out.println("Generating utility classes.");
+       tree.apply(new GenUtils(ids));
+ 
+       try
+       {
+           System.out.println("Generating the lexer.");
+           tree.apply(new GenLexer(ids));
+       }
+       catch(Exception e)
+       {
+           System.out.println(e.getMessage());
+           throw e;
+       }
+ 
+       try
+       {
+           System.out.println("Generating the parser.");
+           tree.apply(new GenParser(ids));
+       }
+       catch(Exception e)
+       {
+           System.out.println(e.getMessage());
+           throw e;
+       }
+   }
+   
+ 
  }