00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 package org.antlr.runtime;
00030
00031 import java.io.IOException;
00032 import java.io.FileInputStream;
00033 import java.io.BufferedInputStream;
00034 import java.io.DataInputStream;
00035 import java.util.List;
00036 import java.util.ArrayList;
00037
00038 public class SerializedGrammar {
00039 public static final String COOKIE = "$ANTLR";
00040 public static final int FORMAT_VERSION = 1;
00041
00042
00043 public String name;
00044 public char type;
00045 public List rules;
00046
00047 class Rule {
00048 String name;
00049 Block block;
00050 public Rule(String name, Block block) {
00051 this.name = name;
00052 this.block = block;
00053 }
00054 public String toString() {
00055 return name+":"+block;
00056 }
00057 }
00058
00059 class Block {
00060 List[] alts;
00061 public Block(List[] alts) {
00062 this.alts = alts;
00063 }
00064 public String toString() {
00065 StringBuffer buf = new StringBuffer();
00066 buf.append("(");
00067 for (int i = 0; i < alts.length; i++) {
00068 List alt = alts[i];
00069 if ( i>0 ) buf.append("|");
00070 buf.append(alt.toString());
00071 }
00072 buf.append(")");
00073 return buf.toString();
00074 }
00075 }
00076
00077 class TokenRef {
00078 int ttype;
00079 public TokenRef(int ttype) { this.ttype = ttype; }
00080 public String toString() { return String.valueOf(ttype); }
00081 }
00082
00083 class RuleRef {
00084 int ruleIndex;
00085 public RuleRef(int ruleIndex) { this.ruleIndex = ruleIndex; }
00086 public String toString() { return String.valueOf(ruleIndex); }
00087 }
00088
00089 public SerializedGrammar(String filename) throws IOException {
00090 System.out.println("loading "+filename);
00091 FileInputStream fis = new FileInputStream(filename);
00092 BufferedInputStream bos = new BufferedInputStream(fis);
00093 DataInputStream in = new DataInputStream(bos);
00094 readFile(in);
00095 in.close();
00096 }
00097
00098 protected void readFile(DataInputStream in) throws IOException {
00099 String cookie = readString(in);
00100 if ( !cookie.equals(COOKIE) ) throw new IOException("not a serialized grammar file");
00101 int version = in.readByte();
00102 char grammarType = (char)in.readByte();
00103 this.type = grammarType;
00104 String grammarName = readString(in);
00105 this.name = grammarName;
00106 System.out.println(grammarType+" grammar "+grammarName);
00107 int numRules = in.readShort();
00108 System.out.println("num rules = "+numRules);
00109 rules = readRules(in, numRules);
00110 }
00111
00112 protected List readRules(DataInputStream in, int numRules) throws IOException {
00113 List rules = new ArrayList();
00114 for (int i=0; i<numRules; i++) {
00115 Rule r = readRule(in);
00116 rules.add(r);
00117 }
00118 return rules;
00119 }
00120
00121 protected Rule readRule(DataInputStream in) throws IOException {
00122 byte R = in.readByte();
00123 if ( R!='R' ) throw new IOException("missing R on start of rule");
00124 String name = readString(in);
00125 System.out.println("rule: "+name);
00126 byte B = in.readByte();
00127 Block b = readBlock(in);
00128 byte period = in.readByte();
00129 if ( period!='.' ) throw new IOException("missing . on end of rule");
00130 return new Rule(name, b);
00131 }
00132
00133 protected Block readBlock(DataInputStream in) throws IOException {
00134 int nalts = in.readShort();
00135 List[] alts = new List[nalts];
00136
00137 for (int i=0; i<nalts; i++) {
00138 List alt = readAlt(in);
00139 alts[i] = alt;
00140 }
00141
00142 return new Block(alts);
00143 }
00144
00145 protected List readAlt(DataInputStream in) throws IOException {
00146 List alt = new ArrayList();
00147 byte A = in.readByte();
00148 if ( A!='A' ) throw new IOException("missing A on start of alt");
00149 byte cmd = in.readByte();
00150 while ( cmd!=';' ) {
00151 switch (cmd) {
00152 case 't' :
00153 int ttype = in.readShort();
00154 alt.add(new TokenRef(ttype));
00155
00156 break;
00157 case 'r' :
00158 int ruleIndex = in.readShort();
00159 alt.add(new RuleRef(ruleIndex));
00160
00161 break;
00162 case '.' :
00163 break;
00164 case '-' :
00165 int from = in.readChar();
00166 int to = in.readChar();
00167 break;
00168 case '~' :
00169 int notThisTokenType = in.readShort();
00170 break;
00171 case 'B' :
00172 Block b = readBlock(in);
00173 alt.add(b);
00174 break;
00175 }
00176 cmd = in.readByte();
00177 }
00178
00179 return alt;
00180 }
00181
00182 protected String readString(DataInputStream in) throws IOException {
00183 byte c = in.readByte();
00184 StringBuffer buf = new StringBuffer();
00185 while ( c!=';' ) {
00186 buf.append((char)c);
00187 c = in.readByte();
00188 }
00189 return buf.toString();
00190 }
00191
00192 public String toString() {
00193 StringBuffer buf = new StringBuffer();
00194 buf.append(type+" grammar "+name);
00195 buf.append(rules);
00196 return buf.toString();
00197 }
00198 }