Mercurial Hosting > luan
diff src/luan/modules/parsers/Json.java @ 1112:490f77bb2ad1
add JsonParser
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Wed, 02 Aug 2017 17:37:59 -0600 |
parents | 88b5b81cad4a |
children |
line wrap: on
line diff
--- a/src/luan/modules/parsers/Json.java Wed Aug 02 15:19:47 2017 -0600 +++ b/src/luan/modules/parsers/Json.java Wed Aug 02 17:37:59 2017 -0600 @@ -13,215 +13,6 @@ public final class Json { - public static Object parse(String text) throws ParseException { - return new Json(text).parse(); - } - - private final Parser parser; - - private Json(String text) { - this.parser = new Parser(text); - } - - private ParseException exception(String msg) { - return new ParseException(parser,msg); - } - - private Object parse() throws ParseException { - spaces(); - Object value = value(); - spaces(); - if( !parser.endOfInput() ) - throw exception("unexpected text"); - return value; - } - - private Object value() throws ParseException { - if( parser.match("null") ) - return null; - if( parser.match("true") ) - return Boolean.TRUE; - if( parser.match("false") ) - return Boolean.FALSE; - String s = string(); - if( s != null ) - return s; - Number n = number(); - if( n != null ) - return n; - LuanTable a = array(); - if( a != null ) - return a; - LuanTable o = object(); - if( o != null ) - return o; - throw exception("invalid value"); - } - - private String string() throws ParseException { - parser.begin(); - if( !parser.match('"') ) - return parser.failure(null); - StringBuilder sb = new StringBuilder(); - while( parser.anyChar() ) { - char c = parser.lastChar(); - switch(c) { - case '"': - return parser.success(sb.toString()); - case '\\': - if( parser.anyChar() ) { - c = parser.lastChar(); - switch(c) { - case '"': - case '\\': - case '/': - sb.append(c); - continue; - case 'b': - sb.append('\b'); - continue; - case 'f': - sb.append('\f'); - continue; - case 'n': - sb.append('\n'); - continue; - case 'r': - sb.append('\r'); - continue; - case 't': - sb.append('\t'); - continue; - case 'u': - int n = 0; - for( int i=0; i<4; i++ ) { - int d; - if( parser.inCharRange('0','9') ) { - d = parser.lastChar() - '0'; - } else if( parser.inCharRange('a','f') ) { - d = parser.lastChar() - 'a' + 10; - } else if( parser.inCharRange('A','F') ) { - d = parser.lastChar() - 'A' + 10; - } else { - throw exception("invalid hex digit"); - } - n = 16*n + d; - } - sb.append((char)n); - continue; - } - } - throw exception("invalid escape char"); - default: - sb.append(c); - } - } - parser.failure(); - throw exception("unclosed string"); - } - - private Number number() { - int start = parser.begin(); - boolean isFloat = false; - parser.match('-'); - if( !parser.match('0') ) { - if( !parser.inCharRange('1','9') ) - return parser.failure(null); - while( parser.inCharRange('0','9') ); - } - if( parser.match('.') ) { - if( !parser.inCharRange('0','9') ) - return parser.failure(null); - while( parser.inCharRange('0','9') ); - isFloat = true; - } - if( parser.anyOf("eE") ) { - parser.anyOf("+-"); - if( !parser.inCharRange('0','9') ) - return parser.failure(null); - while( parser.inCharRange('0','9') ); - isFloat = true; - } - String s = parser.textFrom(start); - Number n; - if(isFloat) - n = Double.valueOf(s); - else - n = Long.valueOf(s); - return parser.success(n); - } - - private LuanTable array() throws ParseException { - parser.begin(); - if( !parser.match('[') ) - return parser.failure(null); - spaces(); - if( parser.match(']') ) - return parser.success(new LuanTable()); - List list = new ArrayList(); - list.add( value() ); - spaces(); - while( parser.match(',') ) { - spaces(); - list.add( value() ); - spaces(); - } - if( parser.match(']') ) - return parser.success(new LuanTable(list)); - if( parser.endOfInput() ) { - parser.failure(); - throw exception("unclosed array"); - } - throw exception("unexpected text in array"); - } - - private LuanTable object() throws ParseException { - parser.begin(); - if( !parser.match('{') ) - return parser.failure(null); - spaces(); - if( parser.match('}') ) - return parser.success(new LuanTable()); - Map map = new LinkedHashMap(); - addEntry(map); - while( parser.match(',') ) { - spaces(); - addEntry(map); - } - if( parser.match('}') ) - return parser.success(new LuanTable(map)); - if( parser.endOfInput() ) { - parser.failure(); - throw exception("unclosed object"); - } - throw exception("unexpected text in object"); - } - - private void addEntry(Map map) throws ParseException { - String key = string(); - if( key==null ) - throw exception("invalid object key"); - spaces(); - if( !parser.match(':') ) - throw exception("':' expected"); - spaces(); - Object value = value(); - spaces(); - map.put(key,value); - } - - private void spaces() { - while( parser.anyOf(" \t\r\n") ); - } - - - - - - - - - public static String toString(Object obj) throws LuanException { StringBuilder sb = new StringBuilder(); toString(obj,sb);