001: package fri.patterns.interpreter.parsergenerator.builder;
002:
003: import java.io.File;
004: import fri.patterns.interpreter.parsergenerator.ParserTables;
005: import fri.patterns.interpreter.parsergenerator.parsertables.*;
006: import fri.patterns.interpreter.parsergenerator.syntax.Syntax;
007:
008: /**
009: Buffering ParserTables. SerializedParserTables will build the ParserTables from scratch
010: only the first time. Every following call will load the serialized ParserTables
011: from filesystem.
012: <p>
013: The time to build parser tables from scratch is less or equal to deserializing it
014: for little syntaxes. Use it only for big tables (e.g. for Java syntax).
015: <p>
016: Mind that this factory accepts a parser syntax, NOT a syntax where parser and lexer rules were mixed!
017: <p>
018: Example (with syntax input from a file):
019: <pre>
020: File syntaxInput = ...;
021: ParserTables tables = new SerializedTables().get(syntaxInput);
022: </pre>
023: or (syntax input from a Reader):
024: <pre>
025: Reader syntaxInput = ...;
026: ParserTables tables = new SerializedTables().get(syntaxInput, "MyTables.ser");
027: </pre>
028:
029: @author (c) 2000, Fritz Ritzberger
030: */
031:
032: public class SerializedTables extends SerializedObject {
033: private boolean PRODUCTION; // setting this to false in constructor will prevent the ParserTables from being serialized
034:
035: /** Create a ParserTables factory that buffers created parser tables. */
036: public SerializedTables() {
037: this (true);
038: }
039:
040: /** Create a ParserTables factory that buffers tables once created. @param production when false the tables will not be buffered. */
041: public SerializedTables(boolean production) {
042: this .PRODUCTION = production;
043: }
044:
045: /**
046: Creates parser tables for passed syntax input from scratch or loads serialized tables from filesystem.
047: LALRParserTables.class wil be the type of created parser tables.
048: @param syntaxInput the Parser syntax as File, InputStream, List of Lists, String [][] or Syntax.
049: @return deserialized ParserTables, or one built from scratch that gets written to filesystem.
050: */
051: public AbstractParserTables get(Object syntaxInput)
052: throws Exception {
053: return get(syntaxInput, null);
054: }
055:
056: /**
057: Creates parser tables for passed syntax input from scratch or loads serialized tables from filesystem.
058: LALRParserTables.class will be the type of created parser tables.
059: @param syntaxInput the Parser syntax as File, InputStream, List of Lists, String [][] or Syntax.
060: @param baseName name of serialization file, can be null when syntaxInput is a File
061: @return deserialized ParserTables, or one built from scratch that gets written to filesystem.
062: */
063: public AbstractParserTables get(Object syntaxInput, String baseName)
064: throws Exception {
065: return get(null, syntaxInput, baseName);
066: }
067:
068: /**
069: Creates parser tables for passed syntax input from scratch or loads serialized tables from filesystem.
070: @param parserType the ParserTables class, e.g. SLRParserTables.class.
071: @param syntaxInput the Parser syntax as File, InputStream, List of Lists, String [][] or Syntax.
072: @param baseName name of serialization file, can be null when syntaxInput is a File
073: @return deserialized ParserTables, or one built from scratch that gets written to filesystem.
074: */
075: public AbstractParserTables get(Class parserType,
076: Object syntaxInput, String baseName) throws Exception {
077: AbstractParserTables parserTables = readParserTables(
078: syntaxInput, baseName);
079: if (parserTables == null)
080: parserTables = buildAndStoreParserTables(parserType, null,
081: syntaxInput, baseName);
082: return parserTables;
083: }
084:
085: private String ensureFileName(Object syntaxInput, String baseName) {
086: if (baseName == null)
087: baseName = baseNameFromSyntax(syntaxInput);
088: return baseName + "ParserTables.ser";
089: }
090:
091: public AbstractParserTables readParserTables(Object syntaxInput,
092: String baseName) {
093: if (PRODUCTION)
094: return (AbstractParserTables) read(ensureFileName(
095: syntaxInput, baseName));
096: return null;
097: }
098:
099: public AbstractParserTables buildAndStoreParserTables(
100: Class parserType, Syntax parserSyntax, Object syntaxInput,
101: String baseName) throws Exception {
102: if (parserType == null)
103: parserType = LALRParserTables.class;
104:
105: Syntax syntax = parserSyntax == null ? toSyntax(syntaxInput)
106: : parserSyntax;
107:
108: fri.util.TimeStopper ts = new fri.util.TimeStopper();
109: AbstractParserTables parserTables = AbstractParserTables
110: .construct(parserType, syntax);
111: System.err.println("ParserTables scratch construction took "
112: + ts.getTimeMillis() + " millis");
113:
114: if (PRODUCTION)
115: write(ensureFileName(syntaxInput, baseName), parserTables);
116:
117: return parserTables;
118: }
119:
120: /** Test main. Building serialized ParserTables takes 170, building from scratch takes 59 millis !!! */
121: public static void main(String[] args) {
122: try {
123: File syntaxFile = new File(
124: "fri/patterns/interpreter/parsergenerator/syntax/builder/examples/SyntaxBuilder.syntax");
125: Syntax syntax = new fri.patterns.interpreter.parsergenerator.syntax.builder.SyntaxBuilder(
126: syntaxFile).getParserSyntax();
127: fri.util.TimeStopper ts = new fri.util.TimeStopper();
128: ParserTables parserTables = new SerializedTables().get(
129: syntax, "SyntaxBuilder");
130: System.err.println("ParserTables were built in "
131: + ts.getTimeMillis() + " millis");
132: } catch (Exception e) {
133: e.printStackTrace();
134: }
135: }
136:
137: }
|