add Input.getName()
[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 /**
11  *   A slow, ugly, inefficient, inelegant, ad-hoc parser for TIB files.
12  *
13  *   Despite being inelegant, this parser keeps all internal state on
14  *   the stack (the only heap objects created are those which are
15  *   returned).
16  *
17  *   This was written as an ad-hoc parser to facilitate
18  *   experimentation with the TIB spec.  Once the spec is finalized it
19  *   should probably be rewritten.
20  */
21 public class Tib implements Input<Character> {
22
23     public String showRegion(Region<Character> r) { return ""; }
24
25     public Tib(String s) throws IOException { this(new StringReader(s)); }
26     public Tib(Reader r) throws IOException { this(new BufferedReader(r)); }
27     public Tib(InputStream is) throws IOException { this(new BufferedReader(new InputStreamReader(is))); }
28     public Tib(BufferedReader br) throws IOException {
29         this.br = br;
30         istack.add(-1);
31         //cur = parse(br);
32         //System.out.println("\rparsing: \"" + cur.toString(0, -1) + "\"");
33     }
34     public String getName() { return null; }
35     private String s = "";
36     int pos = 0;
37     int spos = 0;
38
39     int _row = 1;
40     int _col = 0;
41     int _scalar = 0;
42     public Input.Location getLocation() { return new Cartesian.Location(_col, _row, _scalar); }
43     private BufferedReader br;
44
45     char left = CharAtom.left;
46     char right = CharAtom.right;
47
48     boolean waiting = false;
49     char waitingChar = ' ';
50     boolean indenting = true;
51     int indentation = 0;
52     private ArrayList<Integer> istack = new ArrayList<Integer>();
53     private static boolean debug = "true".equals(System.getProperty("tib.debug", "false"));
54     public Character next() throws IOException {
55         Character ret = nextc();
56         if (debug) {
57             if      (ret==null) return null;
58             else if (ret==left)  System.out.print("\033[31m{\033[0m");
59             else if (ret==right) System.out.print("\033[31m}\033[0m");
60             else System.out.print(ret);
61         }
62         return ret;
63     }
64
65     Character waitingBrace = null;
66     public Character nextc() throws IOException {
67         char c;
68         if (waitingBrace != null) {
69             Character ret = waitingBrace;
70             waitingBrace = null;
71             return ret;
72         }
73         if (waiting) {
74             waiting = false;
75             c = waitingChar;
76         } else {
77             int i = br.read();
78             if (i==-1) {
79                 if (istack.size() > 1) {
80                     istack.remove(istack.size()-1);
81                     return right;
82                 }
83                 return null;
84             }
85             c = (char)i;
86             _scalar++;
87             if (c=='\n') { _row++; _col=0; }
88             else         _col++;
89         }
90         if (indenting) {
91             if (c==' ') { indentation++; return done(c); }
92             if (c=='\n') { indentation = 0; if (blank) return nextc(); blank = true; waiting = true; waitingChar='\n'; return '\n'; }
93             int last = istack.size()==0 ? -1 : istack.get(istack.size()-1);
94             if (indentation==last) {
95                 if (blank) {
96                     indenting = false;
97                     waitingChar = c;
98                     waiting = true;
99                     waitingBrace = left;
100                     return right;
101                     //return nextc(numstates);
102                 }
103                 blank = false;
104                 indenting = false;
105                 return done(c);
106             }
107             blank = false;
108             waitingChar = c;
109             waiting = true;
110             if (indentation > last) {
111                 indenting = false;
112                 istack.add(indentation);
113                 //System.out.print("\033[31m+"+indentation+"+\033[0m");
114                 return left;
115             } else /*if (indentation < last)*/ {
116                 istack.remove(istack.size()-1);
117                 //System.out.print("\033[31m-"+last+"-\033[0m");
118                 blank = true;
119                 return right;
120             }
121         } else {
122             blank = false;
123             if (c=='\n') { indenting=true; indentation = 0; }
124             return done(c);
125         }
126     }
127
128     public Character done(char c) {
129         switch(c) {
130             case '{': return left;
131             case '}': return right;
132             default: return c;
133         }
134     }
135     boolean blank = false;
136
137     // Grammar //////////////////////////////////////////////////////////////////////////////
138
139     /*
140     public static class Grammar extends ReflectiveGrammar {
141         private int anon = 0;
142         private final Element ws = Sequence.maximal0(getNonTerminal("w"));
143         public Grammar(Class c) { super(c); dropAll.add(ws); }
144         public Object walk(Tree<String> tree) {
145             String head = tree.head();
146             if (tree.numChildren()==0) return super.walk(tree);
147             if ("{".equals(head)) {
148                 Union u = new Union("???");
149                 Union u2 = ((PreSequence)walk(tree, 0)).sparse(ws).buildUnion();
150                 u2.add(Sequence.singleton(new Element[] { u }, 0));
151                 return anonymousNonTerminal(new Sequence[][] {
152                     new Sequence[] {
153                         Sequence.singleton(new Element[] { CharAtom.leftBrace,
154                                                            ws,
155                                                            u2,
156                                                            ws,
157                                                            CharAtom.rightBrace
158                         }, 2)
159                     }
160                 });
161             }
162             return super.walk(tree);
163         }
164     }
165     */
166
167     /*
168 public class Braces extends Union {
169
170     private static final Element left  = string("{");
171     private static final Element right = string("}");
172     
173     public static String join(Object[] e) {
174         StringBuffer ret = new StringBuffer();
175         for(int i=0; i<e.length; i++) {
176             if (i>0) ret.append(" ");
177             ret.append(e[i]);
178         }
179         return ret.toString();
180     }
181
182     public Braces(Element[] e, Element sep) {
183         super("{"+join(e)+"}");
184         Element[] e2 = new Element[sep == null ? e.length+2 : e.length + 4];
185         e2[0]           = left;
186         e2[e2.length-1] = right;
187         if (sep != null) {
188             e2[1] = sep;
189             e2[e2.length-2] = sep;
190         }
191         for(int i=0; i<e.length; i++) e2[i+(sep==null ? 1 : 2)] = e[i];
192         addAlternative(new Sequence.Singleton(e2));
193         addAlternative(new Sequence.Singleton(sep==null ? new Element[] { left, this, right} : new Element[] { left, sep, this, sep, right }));
194     }
195 }
196                       */
197
198 }
199