X-Git-Url: http://git.megacz.com/?p=sbp.git;a=blobdiff_plain;f=src%2Fedu%2Fberkeley%2Fsbp%2Ftib%2FTib.java;h=a86b3abd3e0db0de422483234709cba23e22ee1e;hp=df568553580204d1519ee30c80f23a8b5a19260b;hb=449c39e0dafd7c736bfcd8d56bbd08b7a99e25a4;hpb=0a0227b9180534d2a431f3d6e08a398bde2244c4 diff --git a/src/edu/berkeley/sbp/tib/Tib.java b/src/edu/berkeley/sbp/tib/Tib.java index df56855..a86b3ab 100644 --- a/src/edu/berkeley/sbp/tib/Tib.java +++ b/src/edu/berkeley/sbp/tib/Tib.java @@ -1,17 +1,12 @@ -// Copyright 2005 the Contributors, as shown in the revision logs. -// Licensed under the Apache Public Source License 2.0 ("the License"). -// You may not use this file except in compliance with the License. +// Copyright 2006 all rights reserved; see LICENSE file for BSD-style license package edu.berkeley.sbp.tib; -//import org.ibex.util.*; -//import org.ibex.io.*; +import edu.berkeley.sbp.*; +import edu.berkeley.sbp.misc.*; +import edu.berkeley.sbp.chr.*; import java.util.*; import java.io.*; -// TODO: multiple {{ }} for superquotation -// TODO: strings -// TODO: comments - /** * A slow, ugly, inefficient, inelegant, ad-hoc parser for TIB files. * @@ -21,226 +16,121 @@ import java.io.*; * * This was written as an ad-hoc parser to facilitate * experimentation with the TIB spec. Once the spec is finalized it - * should probably be rewritten using a parser-generator, if - * possible (it is unclear whether or not the associated grammar is - * context-free). + * should probably be rewritten. */ -public class Tib /*implements Token.Stream*/ { - /* - - private String str; +public class Tib implements Input { - public Tib(InputStream is) { this(new BufferedReader(new InputStreamReader(is))); } - public Tib(BufferedReader br) { - Block b = parse(br); - } + public String showRegion(Region r, int max) { return ""; } - public Token next() throws IOException { - if (pos >= str.length()) return Atom.EOF; - return Atom.fromChar(str.charAt(pos++)); + public Tib(String s) throws IOException { this(new StringReader(s)); } + public Tib(Reader r) throws IOException { this(new BufferedReader(r)); } + public Tib(InputStream is) throws IOException { this(new BufferedReader(new InputStreamReader(is))); } + public Tib(BufferedReader br) throws IOException { + this.br = br; + istack.add(-1); } - - public static Block parse(BufferedReader br) throws Invalid { - int row=0, col=0; - try { - boolean blankLine = false; - Block top = new Block.Root(); - for(String s = br.readLine(); s != null; s = br.readLine()) { - col = 0; - while (s.length() > 0 && - s.charAt(0) == ' ' && - (!(top instanceof Block.Literal) || col < top.col)) { col++; s = s.substring(1); } - if ((top instanceof Block.Literal) && col >= top.col) { top.add(s); continue; } - if (s.length()==0) { blankLine = true; continue; } - while (col < top.col) { - if (s.startsWith("{}") && top instanceof Block.Literal && ((Block.Literal)top).braceCol == col) break; - blankLine = false; - top = top.closeIndent(); - } - if (s.startsWith("{}")) { - int bc = col; - boolean append = top instanceof Block.Literal && ((Block.Literal)top).braceCol == bc; - s = s.substring(2); - col += 2; - while (s.length() > 0 && s.charAt(0) == ' ' && !(append && col >= top.col) ) { col++; s = s.substring(1); } - if (append) top.add(s); else (top = new Block.Literal(top, row, col, bc)).add(s); - continue; - } - while (s.length() > 0 && s.charAt(s.length()-1)==' ') { s = s.substring(0, s.length()-1); } - if (col > top.col) top = new Block.Indent(top, row, col); - else if (blankLine) { top = top.closeIndent(); top = new Block.Indent(top, row, col); } - blankLine = false; - for(int i=0; i istack = new ArrayList(); + private static boolean debug = "true".equals(System.getProperty("tib.debug", "false")); + public Character next() throws IOException { + Character ret = nextc(); + if (debug) { + if (ret==null) return null; + else if (ret==left) System.err.print("\033[31m{\033[0m"); + else if (ret==right) System.err.print("\033[31m}\033[0m"); + else System.err.print(ret); } + return ret; } - public static class Block implements Token { - Block parent; - public final int row; - public final int col; - private final Vec children = new Vec(); - private String pending = ""; - - public Tree result() { - // FIXME - } - - public Location getLocation() { return new Location.Cartesian(row, col); } - public boolean isEOF() { return false; } - - public int size() { return children.size(); } - public Object child(int i) { return children.elementAt(i); } - public boolean isLiteral() { return false; } - - protected Block(int row, int col) { this.row=row; this.col=col; parent = null; } - public Block(Block parent, int row, int col) { this.row=row; this.col=col; (this.parent = parent).add(this); } - - public void add(String s) { children.addElement(s); } - public void add(char c) { - if (c == '{' || c == '}') { finishWord(); return; } - if (c != ' ') { pending += c; return; } - if (pending.length() > 0) { finishWord(); add(" "); return; } - if (size()==0) return; - if (child(size()-1).equals(" ")) return; - add(" "); - return; - } - - public void add(Block b) { children.addElement(b); } - public Block promote() { parent.parent.replaceLast(this); return close(); } - public Object lastChild() { return children.lastElement(); } - public Block lastChildAsBlock() { return (Block)lastChild(); } - public void replaceLast(Block b) { children.setElementAt(b, children.size()-1); b.parent = this; } - - public void finishWord() { if (pending.length() > 0) { add(pending); pending = ""; } } - - public Block closeBrace() { throw new InternalException("attempt to closeBrace() a "+getClass().getName()); } - public Block closeIndent() { throw new InternalException("attempt to closeIndent() a "+getClass().getName()); } - public Block close() { - while(size() > 0 && child(size()-1).equals(" ")) children.setSize(children.size()-1); - if (size()==0) throw new InternalException("PARSER BUG: attempt to close an empty block (should never happen)"); - if (size() > 1 || !(lastChild() instanceof Block)) return parent; - return lastChildAsBlock().promote(); + Character waitingBrace = null; + public Character nextc() throws IOException { + char c; + if (waitingBrace != null) { + Character ret = waitingBrace; + waitingBrace = null; + return ret; } - public String toString() { return toString(80); } - public String toString(int justificationLimit) { return toString(0, 80); } - protected String toString(int indent, int justificationLimit) { - StringBuffer ret = new StringBuffer(); - StringBuffer line = new StringBuffer(); - for(int i=0; i0 && children.elementAt(i-1) instanceof Block && justificationLimit!=-1) ret.append("\n"); - if (o instanceof Block) { - ret.append(justify(line.toString(), indent, justificationLimit)); - line.setLength(0); - if (justificationLimit==-1) { - ret.append("{"); - ret.append(((Block)o).toString(indent+2, justificationLimit)); - ret.append("}"); - } else { - ret.append(((Block)o).toString(indent+2, justificationLimit)); - } - } else { - line.append(o.toString()); + if (waiting) { + waiting = false; + c = waitingChar; + } else { + int i = br.read(); + if (i==-1) { + if (istack.size() > 1) { + istack.remove(istack.size()-1); + return right; } + return null; } - ret.append(justify(line.toString(), indent, justificationLimit)); - return ret.toString(); - } - - private static class Root extends Block { - public Root() { super(0, Integer.MIN_VALUE); } - public Block close() { throw new InternalException("attempted to close top block"); } - public String toString(int justificationLimit) { return toString(-2, justificationLimit); } + c = (char)i; + _scalar++; + if (c=='\n') { _row++; _col=0; } + else _col++; } - - private static class Brace extends Block { - public Brace(Block parent, int row, int col) { super(parent, row, col); } - public Block closeBrace() { return super.close(); } - } - - private static class Indent extends Block { - public Indent(Block parent, int row, int col) { super(parent, row, col); } - public Block closeIndent() { return super.close(); } - } - - private static class Literal extends Block { - private StringBuffer content = new StringBuffer(); - public final int braceCol; - public Literal(Block parent, int row, int col, int braceCol) { super(parent,row,col); this.braceCol = braceCol; } - public boolean isLiteral() { return true; } - public int size() { return 1; } - public Object child(int i) { return i==0 ? content.toString() : null; } - public Block close() { return parent; } - public Block closeIndent() { return close(); } - public void add(String s) { if (content.length()>0) content.append('\n'); content.append(s); } - protected String toString(int indent, int justificationLimit) { - StringBuffer ret = new StringBuffer(); - String s = content.toString(); - while(s.length() > 0) { - int nl = s.indexOf('\n'); - if (nl==-1) nl = s.length(); - ret.append(spaces(indent)); - ret.append("{} "); - ret.append(s.substring(0, nl)); - s = s.substring(Math.min(s.length(),nl+1)); - ret.append('\n'); + if (indenting) { + if (c==' ') { indentation++; return done(c); } + if (c=='\n') { indentation = 0; if (blank) return nextc(); blank = true; waiting = true; waitingChar='\n'; return '\n'; } + int last = istack.size()==0 ? -1 : istack.get(istack.size()-1); + if (indentation==last) { + if (blank) { + indenting = false; + waitingChar = c; + waiting = true; + waitingBrace = left; + return right; + //return nextc(numstates); } - return ret.toString(); + blank = false; + indenting = false; + return done(c); } + blank = false; + waitingChar = c; + waiting = true; + if (indentation > last) { + indenting = false; + istack.add(indentation); + //System.out.print("\033[31m+"+indentation+"+\033[0m"); + return left; + } else /*if (indentation < last)*/ { + istack.remove(istack.size()-1); + //System.out.print("\033[31m-"+last+"-\033[0m"); + blank = true; + return right; + } + } else { + blank = false; + if (c=='\n') { indenting=true; indentation = 0; } + return done(c); } } - - // Exceptions ////////////////////////////////////////////////////////////////////////////// - - private static class InternalException extends RuntimeException { public InternalException(String s) { super(s); } } - public static class Invalid extends IOException { - public Invalid(InternalException ie, int row, int col) { - super(ie.getMessage() + " at " + row + ":" + col); + public Character done(char c) { + switch(c) { + case '{': return left; + case '}': return right; + default: return c; } } + boolean blank = false; - // Testing ////////////////////////////////////////////////////////////////////////////// - - public static void main(String[] s) throws Exception { System.out.println(parse(new Stream(System.in)).toString(-1)); } - - // Utilities ////////////////////////////////////////////////////////////////////////////// - - public static String spaces(int i) { if (i<=0) return ""; return " " + spaces(i-1); } - - private static String justify(String s, int indent, int justificationLimit) { - if (s.length() == 0) return ""; - if (justificationLimit==-1) return s; - StringBuffer ret = new StringBuffer(); - while(s.length() > 0) { - if (s.charAt(0) == ' ') { s = s.substring(1); continue; } - ret.append(spaces(indent)); - int i = s.indexOf(' '); - if (i==-1) i = s.length(); - while(s.indexOf(' ', i+1) != -1 && s.indexOf(' ', i+1) < justificationLimit-indent) i = s.indexOf(' ', i+1); - if (s.length() + indent < justificationLimit) i = s.length(); - ret.append(s.substring(0, i)); - s = s.substring(i); - ret.append('\n'); - } - return ret.toString(); - } - */ }