1 // Copyright 2006 all rights reserved; see LICENSE file for BSD-style license
3 package edu.berkeley.sbp.tib;
4 import edu.berkeley.sbp.*;
5 import edu.berkeley.sbp.misc.*;
6 import edu.berkeley.sbp.chr.*;
10 // TODO: multiple {{ }} for superquotation
15 * A slow, ugly, inefficient, inelegant, ad-hoc parser for TIB files.
17 * Despite being inelegant, this parser keeps all internal state on
18 * the stack (the only heap objects created are those which are
21 * This was written as an ad-hoc parser to facilitate
22 * experimentation with the TIB spec. Once the spec is finalized it
23 * should probably be rewritten.
25 public class Tib implements Input<Character> {
27 public String showRegion(Region<Character> r) { return ""; }
29 public Tib(String s) throws IOException { this(new StringReader(s)); }
30 public Tib(Reader r) throws IOException { this(new BufferedReader(r)); }
31 public Tib(InputStream is) throws IOException { this(new BufferedReader(new InputStreamReader(is))); }
32 public Tib(BufferedReader br) throws IOException {
36 //System.out.println("\rparsing: \"" + cur.toString(0, -1) + "\"");
39 private String s = "";
46 public Input.Location getLocation() { return new Cartesian.Location(_col, _row, _scalar); }
47 private BufferedReader br;
49 char left = CharAtom.left;
50 char right = CharAtom.right;
52 boolean waiting = false;
53 char waitingChar = ' ';
54 boolean indenting = true;
56 private ArrayList<Integer> istack = new ArrayList<Integer>();
57 private static boolean debug = "true".equals(System.getProperty("tib.debug", "false"));
58 public Character next() throws IOException {
59 Character ret = nextc();
61 if (ret==null) return null;
62 else if (ret==left) System.out.print("\033[31m{\033[0m");
63 else if (ret==right) System.out.print("\033[31m}\033[0m");
64 else System.out.print(ret);
69 Character waitingBrace = null;
70 public Character nextc() throws IOException {
72 if (waitingBrace != null) {
73 Character ret = waitingBrace;
83 if (istack.size() > 1) {
84 istack.remove(istack.size()-1);
91 if (c=='\n') { _row++; _col=0; }
95 if (c==' ') { indentation++; return done(c); }
96 if (c=='\n') { indentation = 0; if (blank) return nextc(); blank = true; waiting = true; waitingChar='\n'; return '\n'; }
97 int last = istack.size()==0 ? -1 : istack.get(istack.size()-1);
98 if (indentation==last) {
105 //return nextc(numstates);
114 if (indentation > last) {
116 istack.add(indentation);
117 //System.out.print("\033[31m+"+indentation+"+\033[0m");
119 } else /*if (indentation < last)*/ {
120 istack.remove(istack.size()-1);
121 //System.out.print("\033[31m-"+last+"-\033[0m");
127 if (c=='\n') { indenting=true; indentation = 0; }
132 public Character done(char c) {
134 case '{': return left;
135 case '}': return right;
139 boolean blank = false;
141 // Grammar //////////////////////////////////////////////////////////////////////////////
144 public static class Grammar extends ReflectiveGrammar {
145 private int anon = 0;
146 private final Element ws = Sequence.maximal0(getNonTerminal("w"));
147 public Grammar(Class c) { super(c); dropAll.add(ws); }
148 public Object walk(Tree<String> tree) {
149 String head = tree.head();
150 if (tree.numChildren()==0) return super.walk(tree);
151 if ("{".equals(head)) {
152 Union u = new Union("???");
153 Union u2 = ((PreSequence)walk(tree, 0)).sparse(ws).buildUnion();
154 u2.add(Sequence.singleton(new Element[] { u }, 0));
155 return anonymousNonTerminal(new Sequence[][] {
157 Sequence.singleton(new Element[] { CharAtom.leftBrace,
166 return super.walk(tree);
172 public class Braces extends Union {
174 private static final Element left = string("{");
175 private static final Element right = string("}");
177 public static String join(Object[] e) {
178 StringBuffer ret = new StringBuffer();
179 for(int i=0; i<e.length; i++) {
180 if (i>0) ret.append(" ");
183 return ret.toString();
186 public Braces(Element[] e, Element sep) {
187 super("{"+join(e)+"}");
188 Element[] e2 = new Element[sep == null ? e.length+2 : e.length + 4];
190 e2[e2.length-1] = right;
193 e2[e2.length-2] = sep;
195 for(int i=0; i<e.length; i++) e2[i+(sep==null ? 1 : 2)] = e[i];
196 addAlternative(new Sequence.Singleton(e2));
197 addAlternative(new Sequence.Singleton(sep==null ? new Element[] { left, this, right} : new Element[] { left, sep, this, sep, right }));