remove more Tib junk
[sbp.git] / src / edu / berkeley / sbp / tib / Tib.java
1 // Copyright 2006 all rights reserved; see LICENSE file for BSD-style license
2
3 package edu.berkeley.sbp.tib;
4 import edu.berkeley.sbp.*;
5 import edu.berkeley.sbp.misc.*;
6 import edu.berkeley.sbp.chr.*;
7 import java.util.*;
8 import java.io.*;
9
10 // TODO: multiple {{ }} for superquotation
11 // TODO: strings
12 // TODO: comments
13
14 /**
15  *   A slow, ugly, inefficient, inelegant, ad-hoc parser for TIB files.
16  *
17  *   Despite being inelegant, this parser keeps all internal state on
18  *   the stack (the only heap objects created are those which are
19  *   returned).
20  *
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.
24  */
25 public class Tib implements Input<Character> {
26
27     public String showRegion(Region<Character> r) { return ""; }
28
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 {
33         this.br = br;
34         istack.add(-1);
35         //cur = parse(br);
36         //System.out.println("\rparsing: \"" + cur.toString(0, -1) + "\"");
37     }
38
39     private String s = "";
40     int pos = 0;
41     int spos = 0;
42
43     int _row = 1;
44     int _col = 0;
45     int _scalar = 0;
46     public Input.Location getLocation() { return new Cartesian.Location(_col, _row, _scalar); }
47     private BufferedReader br;
48
49     char left = CharAtom.left;
50     char right = CharAtom.right;
51
52     boolean waiting = false;
53     char waitingChar = ' ';
54     boolean indenting = true;
55     int indentation = 0;
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();
60         if (debug) {
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);
65         }
66         return ret;
67     }
68
69     Character waitingBrace = null;
70     public Character nextc() throws IOException {
71         char c;
72         if (waitingBrace != null) {
73             Character ret = waitingBrace;
74             waitingBrace = null;
75             return ret;
76         }
77         if (waiting) {
78             waiting = false;
79             c = waitingChar;
80         } else {
81             int i = br.read();
82             if (i==-1) {
83                 if (istack.size() > 1) {
84                     istack.remove(istack.size()-1);
85                     return right;
86                 }
87                 return null;
88             }
89             c = (char)i;
90             _scalar++;
91             if (c=='\n') { _row++; _col=0; }
92             else         _col++;
93         }
94         if (indenting) {
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) {
99                 if (blank) {
100                     indenting = false;
101                     waitingChar = c;
102                     waiting = true;
103                     waitingBrace = left;
104                     return right;
105                     //return nextc(numstates);
106                 }
107                 blank = false;
108                 indenting = false;
109                 return done(c);
110             }
111             blank = false;
112             waitingChar = c;
113             waiting = true;
114             if (indentation > last) {
115                 indenting = false;
116                 istack.add(indentation);
117                 //System.out.print("\033[31m+"+indentation+"+\033[0m");
118                 return left;
119             } else /*if (indentation < last)*/ {
120                 istack.remove(istack.size()-1);
121                 //System.out.print("\033[31m-"+last+"-\033[0m");
122                 blank = true;
123                 return right;
124             }
125         } else {
126             blank = false;
127             if (c=='\n') { indenting=true; indentation = 0; }
128             return done(c);
129         }
130     }
131
132     public Character done(char c) {
133         switch(c) {
134             case '{': return left;
135             case '}': return right;
136             default: return c;
137         }
138     }
139     boolean blank = false;
140
141     // Grammar //////////////////////////////////////////////////////////////////////////////
142
143     /*
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[][] {
156                     new Sequence[] {
157                         Sequence.singleton(new Element[] { CharAtom.leftBrace,
158                                                            ws,
159                                                            u2,
160                                                            ws,
161                                                            CharAtom.rightBrace
162                         }, 2)
163                     }
164                 });
165             }
166             return super.walk(tree);
167         }
168     }
169     */
170
171     /*
172 public class Braces extends Union {
173
174     private static final Element left  = string("{");
175     private static final Element right = string("}");
176     
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(" ");
181             ret.append(e[i]);
182         }
183         return ret.toString();
184     }
185
186     public Braces(Element[] e, Element sep) {
187         super("{"+join(e)+"}");
188         Element[] e2 = new Element[sep == null ? e.length+2 : e.length + 4];
189         e2[0]           = left;
190         e2[e2.length-1] = right;
191         if (sep != null) {
192             e2[1] = sep;
193             e2[e2.length-2] = sep;
194         }
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 }));
198     }
199 }
200                       */
201
202 }
203