/*
 * [The "BSD license"]
 *  Copyright (c) 2010 Terence Parr
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *  1. Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in the
 *      documentation and/or other materials provided with the distribution.
 *  3. The name of the author may not be used to endorse or promote products
 *      derived from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 *  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 *  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 *  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package org.antlr.tool;

import org.antlr.runtime.SerializedGrammar;

import java.io.*;

Serialize a grammar into a highly compressed form with only the info needed to recognize sentences. FORMAT: file ::= $ANTLR<version:byte><grammartype:byte><name:string>;<numRules:short><rules> rule ::= R<rulename:string>;B<nalts:short><alts>. alt ::= A<elems>; elem ::= t<tokentype:short> | r<ruleIndex:short> | -<char:uchar><char:uchar> | ~<tokentype> | w
/** Serialize a grammar into a highly compressed form with * only the info needed to recognize sentences. * FORMAT: * * file ::= $ANTLR&lt;version:byte&gt;&lt;grammartype:byte&gt;&lt;name:string&gt;;&lt;numRules:short&gt;&lt;rules&gt; * rule ::= R&lt;rulename:string&gt;;B&lt;nalts:short&gt;&lt;alts&gt;. * alt ::= A&lt;elems&gt;; * elem ::= t&lt;tokentype:short&gt; | r&lt;ruleIndex:short&gt; | -&lt;char:uchar&gt;&lt;char:uchar&gt; | ~&lt;tokentype&gt; | w */
public class GrammarSerializerFoo { protected DataOutputStream out; protected String filename; protected Grammar g; protected ByteArrayOutputStream altBuf; protected int numElementsInAlt = 0; public GrammarSerializerFoo(Grammar g) { this.g = g; } public void open(String filename) throws IOException { this.filename = filename; FileOutputStream fos = new FileOutputStream(filename); BufferedOutputStream bos = new BufferedOutputStream(fos); out = new DataOutputStream(bos); writeString(out, SerializedGrammar.COOKIE); out.writeByte(SerializedGrammar.FORMAT_VERSION); } public void close() throws IOException { if ( out!=null ) out.close(); out = null; } // WRITE public void grammar(int grammarTokenType, String name) { try { /* switch ( grammarTokenType ) { case ANTLRParser.LEXER_GRAMMAR : out.writeByte('l'); break; case ANTLRParser.PARSER_GRAMMAR : out.writeByte('p'); break; case ANTLRParser.TREE_GRAMMAR: out.writeByte('t'); break; case ANTLRParser.COMBINED_GRAMMAR : out.writeByte('c'); break; } writeString(out, name); */ out.writeShort(g.getRules().size()); } catch (IOException ioe) { ErrorManager.error(ErrorManager.MSG_CANNOT_WRITE_FILE, filename); } } public void rule(String name) { try { out.writeByte('R'); writeString(out, name); } catch (IOException ioe) { ErrorManager.error(ErrorManager.MSG_CANNOT_WRITE_FILE, filename); } } public void endRule() { try { out.writeByte('.'); } catch (IOException ioe) { ErrorManager.error(ErrorManager.MSG_CANNOT_WRITE_FILE, filename); } } public void block(int nalts) { try { out.writeByte('B'); out.writeShort(nalts); } catch (IOException ioe) { ErrorManager.error(ErrorManager.MSG_CANNOT_WRITE_FILE, filename); } } public void alt(GrammarAST alt) { numElementsInAlt = 0; try { out.writeByte('A'); } catch (IOException ioe) { ErrorManager.error(ErrorManager.MSG_CANNOT_WRITE_FILE, filename); } //streams.push(out); //altBuf = new ByteArrayOutputStream(); //out = new DataOutputStream(altBuf); } public void endAlt() { try { //out.flush(); //out = (DataOutputStream)streams.pop(); // restore previous stream out.writeByte(';'); //out.writeShort(numElementsInAlt); //out.write(altBuf.toByteArray()); } catch (IOException ioe) { ErrorManager.error(ErrorManager.MSG_CANNOT_WRITE_FILE, filename); } } public void ruleRef(GrammarAST t) { numElementsInAlt++; try { out.writeByte('r'); out.writeShort(g.getRuleIndex(t.getText())); } catch (IOException ioe) { ErrorManager.error(ErrorManager.MSG_CANNOT_WRITE_FILE, filename); } } public void token(GrammarAST t) { numElementsInAlt++; try { out.writeByte('t'); int ttype = g.getTokenType(t.getText()); out.writeShort(ttype); } catch (IOException ioe) { ErrorManager.error(ErrorManager.MSG_CANNOT_WRITE_FILE, filename); } } public void charLiteral(GrammarAST t) { numElementsInAlt++; try { if ( g.type!=Grammar.LEXER ) { out.writeByte('t'); int ttype = g.getTokenType(t.getText()); out.writeShort(ttype); } // else lexer??? } catch (IOException ioe) { ErrorManager.error(ErrorManager.MSG_CANNOT_WRITE_FILE, filename); } } public void wildcard(GrammarAST t) { numElementsInAlt++; try { out.writeByte('w'); } catch (IOException ioe) { ErrorManager.error(ErrorManager.MSG_CANNOT_WRITE_FILE, filename); } } public void range() { // must be char range numElementsInAlt++; try { out.writeByte('-'); } catch (IOException ioe) { ErrorManager.error(ErrorManager.MSG_CANNOT_WRITE_FILE, filename); } } public void not() { try { out.writeByte('~'); } catch (IOException ioe) { ErrorManager.error(ErrorManager.MSG_CANNOT_WRITE_FILE, filename); } } public void writeString(DataOutputStream out, String s) throws IOException { out.writeBytes(s); out.writeByte(';'); } }