1 33 34 package edu.rice.cs.util.sexp; 35 36 import java.io.File ; 37 import java.io.Reader ; 38 import java.io.FileReader ; 39 import java.io.StringReader ; 40 import java.io.IOException ; 41 import java.util.List ; 42 import java.util.ArrayList ; 43 import java.util.LinkedList ; 44 45 52 public class SExpParser { 53 54 public static List <SEList> parse(File f) throws SExpParseException, IOException { 55 return parse(new FileReader (f)); 56 } 57 58 public static List <SEList> parse(String s) throws SExpParseException { 59 return parse(new StringReader (s)); 60 } 61 62 public static List <SEList> parse(Reader r) throws SExpParseException { 63 try { 64 return new ParseHelper(r).parseMultiple(); 65 } 66 catch(LexingException e) { 67 throw new SExpParseException(e.getMessage()); 68 } 69 catch(PrivateParseException e) { 70 throw new SExpParseException(e.getMessage()); 71 } 72 } 73 74 80 private static class ParseHelper { 81 82 private Lexer _lex; 83 84 public ParseHelper(Reader r) { 85 _lex = new Lexer(r); 86 } 87 88 92 public List <SEList> parseMultiple() { 93 ArrayList <SEList> l = new ArrayList <SEList>(); 94 SEList exp; 95 while ( (exp = parseTopLevelExp()) != null) { 96 l.add(exp); 97 } 98 return l; 99 } 100 101 107 public SEList parseTopLevelExp() { 108 Tokens.SExpToken t = _lex.readToken(); 109 if (t == Tokens.LeftParenToken.ONLY) { 110 return parseList(); 111 } 112 else if (t == null) { 113 return null; 114 } 115 else { 116 throw new PrivateParseException("A top-level s-expression must be a list. "+ 117 "Invalid start of list: " + t); 118 } 119 } 120 121 126 public SExp parseExp() { 127 Tokens.SExpToken t = _lex.readToken(); 128 assertNotEOF(t); 129 if (t == Tokens.LeftParenToken.ONLY) { 130 return parseList(); 131 } 132 else { 133 return parseAtom(t); 134 } 135 } 136 137 142 private SEList parseList() { 143 LinkedList <SExp> list = new LinkedList <SExp>(); 144 Tokens.SExpToken t = _lex.peek(); 145 assertNotEOF(t); 146 147 while (t != Tokens.RightParenToken.ONLY) { 148 list.addFirst(parseExp()); 149 t = _lex.peek(); 150 } 151 152 _lex.readToken(); 155 156 SEList cons = Empty.ONLY; 158 for (SExp exp : list) { 159 cons = new Cons(exp, cons); 160 } 161 return cons; 162 } 163 164 172 private Atom parseAtom(Tokens.SExpToken t) { 173 if (t instanceof Tokens.BooleanToken) { 174 if (((Tokens.BooleanToken)t).getValue()) 175 return BoolAtom.TRUE; 176 else 177 return BoolAtom.FALSE; 178 } 179 else if (t instanceof Tokens.NumberToken) { 180 return new NumberAtom(((Tokens.NumberToken)t).getValue()); 181 } 182 else if (t instanceof Tokens.QuotedTextToken) { 183 return new QuotedTextAtom(t.getText()); 184 } 185 else { 186 return new TextAtom(t.getText()); 187 } 188 } 189 190 194 private void assertNotEOF(Tokens.SExpToken t) { 195 if (t == null) { 196 throw new PrivateParseException("Unexpected <EOF> at line " + _lex.lineno()); 197 } 198 } 199 } 200 201 206 private static class PrivateParseException extends RuntimeException { 207 212 public PrivateParseException(String msg) { super(msg); } 213 } 214 } | Popular Tags |