1 // Copyright 2005 the Contributors, as shown in the revision logs.
2 // Licensed under the Apache Public Source License 2.0 ("the License").
3 // You may not use this file except in compliance with the License.
5 package edu.berkeley.sbp.tib;
6 import edu.berkeley.sbp.*;
7 import edu.berkeley.sbp.misc.*;
11 // TODO: multiple {{ }} for superquotation
16 * A slow, ugly, inefficient, inelegant, ad-hoc parser for TIB files.
18 * Despite being inelegant, this parser keeps all internal state on
19 * the stack (the only heap objects created are those which are
22 * This was written as an ad-hoc parser to facilitate
23 * experimentation with the TIB spec. Once the spec is finalized it
24 * should probably be rewritten.
26 public class Tib implements Token.Stream<Character> {
28 public Tib(String s) throws IOException { this(new StringReader(s)); }
29 public Tib(Reader r) throws IOException { this(new BufferedReader(r)); }
30 public Tib(InputStream is) throws IOException { this(new BufferedReader(new InputStreamReader(is))); }
31 public Tib(BufferedReader br) throws IOException {
35 //System.out.println("\rparsing: \"" + cur.toString(0, -1) + "\"");
38 private String s = "";
44 public Token.Location getLocation() { return new CartesianInput.Location(_row, _col); }
45 private BufferedReader br;
47 boolean waiting = false;
48 char waitingChar = ' ';
49 boolean indenting = true;
51 private ArrayList<Integer> istack = new ArrayList<Integer>();
52 public Character next(int numstates, int resets, int waits) throws IOException {
53 Character ret = nextc(numstates, resets);
54 if (ret==CharToken.left) System.out.print("\033[31m{\033[0m");
55 else if (ret==CharToken.right) System.out.print("\033[31m}\033[0m");
56 else if (ret==null) return null;
57 else System.out.print(ret);
61 Character waitingBrace = null;
62 public Character nextc(int numstates, int resets) throws IOException {
64 if (waitingBrace != null) {
65 Character ret = waitingBrace;
75 if (istack.size() > 1) {
76 istack.remove(istack.size()-1);
77 return CharToken.right;
83 if (c=='\n') { _row++; _col=0; }
86 if (c==' ') { indentation++; return done(c); }
87 if (c=='\n') { indentation = 0; if (blank) return nextc(numstates, resets); blank = true; waiting = true; waitingChar='\n'; return '\n'; }
88 int last = istack.size()==0 ? -1 : istack.get(istack.size()-1);
89 if (indentation==last) {
94 waitingBrace = CharToken.left;
95 return CharToken.right;
96 //return nextc(numstates);
105 if (indentation > last) {
107 istack.add(indentation);
108 //System.out.print("\033[31m+"+indentation+"+\033[0m");
109 return CharToken.left;
110 } else /*if (indentation < last)*/ {
111 istack.remove(istack.size()-1);
112 //System.out.print("\033[31m-"+last+"-\033[0m");
114 return CharToken.right;
118 if (c=='\n') { indenting=true; indentation = 0; }
123 public Character done(char c) {
125 case '{': return CharToken.left;
126 case '}': return CharToken.right;
130 boolean blank = false;
132 // Grammar //////////////////////////////////////////////////////////////////////////////
134 public static class Grammar extends MetaGrammar {
135 private int anon = 0;
136 private final Element ws = Repeat.maximal0(nonTerminal("w"));
137 public Grammar() { dropAll.add(ws); }
138 public Object walk(Tree<String> tree) {
139 String head = tree.head();
140 if (tree.numChildren()==0) return super.walk(tree);
141 if ("{".equals(head)) {
142 String s = "braced"+(anon++);
143 Union u = nonTerminal(s);
144 Union u2 = ((PreSequence)walk(tree, 0)).sparse(ws).buildUnion();
145 u2.add(Sequence.singleton(new Element[] { u }, 0, null, null));
146 return nonTerminal(s,
147 new PreSequence[][] {
149 new PreSequence(new Element[] { CharToken.leftBrace,
160 return super.walk(tree);
165 public class Braces extends Union {
167 private static final Element left = CharToken.string("{");
168 private static final Element right = CharToken.string("}");
170 public static String join(Object[] e) {
171 StringBuffer ret = new StringBuffer();
172 for(int i=0; i<e.length; i++) {
173 if (i>0) ret.append(" ");
176 return ret.toString();
179 public Braces(Element[] e, Element sep) {
180 super("{"+join(e)+"}");
181 Element[] e2 = new Element[sep == null ? e.length+2 : e.length + 4];
183 e2[e2.length-1] = right;
186 e2[e2.length-2] = sep;
188 for(int i=0; i<e.length; i++) e2[i+(sep==null ? 1 : 2)] = e[i];
189 addAlternative(new Sequence.Singleton(e2));
190 addAlternative(new Sequence.Singleton(sep==null ? new Element[] { left, this, right} : new Element[] { left, sep, this, sep, right }));