annotate src/luan/modules/parsers/LuanParser.java @ 1447:851b9a48cc44

Luan.parse
author Franklin Schmidt <fschmidt@gmail.com>
date Tue, 18 Feb 2020 14:54:35 -0700
parents
children b89212fd04b5
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1447
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
1 package luan.modules.parsers;
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
2
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
3 import goodjava.parser.Parser;
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
4 import goodjava.parser.ParseException;
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
5 import luan.Luan;
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
6 import luan.LuanTable;
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
7 import luan.LuanException;
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
8
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
9
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
10 public final class LuanParser {
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
11
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
12 public static Object parse(Luan luan,String text) throws ParseException {
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
13 return new LuanParser(luan,text).parse();
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
14 }
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
15
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
16 private static final Object NULL = new Object();
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
17 private final Luan luan;
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
18 private final Parser parser;
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
19
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
20 private LuanParser(Luan luan,String text) {
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
21 this.luan = luan;
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
22 this.parser = new Parser(text);
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
23 }
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
24
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
25 private ParseException exception(String msg) {
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
26 return new ParseException(parser,msg);
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
27 }
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
28
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
29 private Object parse() throws ParseException {
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
30 do { spaces(); } while( endOfLine() );
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
31 Object value = requiredValue();
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
32 do { spaces(); } while( endOfLine() );
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
33 if( !parser.endOfInput() )
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
34 throw exception("unexpected text");
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
35 return value;
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
36 }
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
37
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
38 private Object requiredValue() throws ParseException {
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
39 Object value = value();
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
40 if( value == null )
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
41 throw exception("invalid value");
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
42 if( value == NULL )
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
43 return null;
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
44 return value;
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
45 }
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
46
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
47 private Object value() throws ParseException {
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
48 if( parser.match("nil") )
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
49 return NULL;
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
50 if( parser.match("true") )
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
51 return Boolean.TRUE;
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
52 if( parser.match("false") )
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
53 return Boolean.FALSE;
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
54 String s = string();
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
55 if( s != null )
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
56 return s;
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
57 Number n = number();
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
58 if( n != null )
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
59 return n;
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
60 LuanTable tbl = table();
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
61 if( tbl != null )
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
62 return tbl;
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
63 return null;
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
64 }
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
65
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
66 private String string() throws ParseException {
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
67 parser.begin();
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
68 if( !parser.match('"') )
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
69 return parser.failure(null);
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
70 StringBuilder sb = new StringBuilder();
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
71 while( parser.anyChar() ) {
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
72 char c = parser.lastChar();
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
73 switch(c) {
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
74 case '"':
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
75 return parser.success(sb.toString());
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
76 case '\\':
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
77 if( parser.anyChar() ) {
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
78 c = parser.lastChar();
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
79 switch(c) {
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
80 case '"':
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
81 case '\'':
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
82 case '\\':
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
83 sb.append(c);
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
84 continue;
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
85 case 'b':
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
86 sb.append('\b');
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
87 continue;
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
88 case 'f':
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
89 sb.append('\f');
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
90 continue;
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
91 case 'n':
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
92 sb.append('\n');
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
93 continue;
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
94 case 'r':
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
95 sb.append('\r');
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
96 continue;
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
97 case 't':
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
98 sb.append('\t');
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
99 continue;
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
100 case 'u':
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
101 int n = 0;
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
102 for( int i=0; i<4; i++ ) {
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
103 int d;
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
104 if( parser.inCharRange('0','9') ) {
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
105 d = parser.lastChar() - '0';
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
106 } else if( parser.inCharRange('a','f') ) {
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
107 d = parser.lastChar() - 'a' + 10;
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
108 } else if( parser.inCharRange('A','F') ) {
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
109 d = parser.lastChar() - 'A' + 10;
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
110 } else {
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
111 throw exception("invalid hex digit");
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
112 }
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
113 n = 16*n + d;
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
114 }
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
115 sb.append((char)n);
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
116 continue;
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
117 }
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
118 }
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
119 throw exception("invalid escape char");
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
120 default:
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
121 sb.append(c);
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
122 }
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
123 }
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
124 parser.failure();
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
125 throw exception("unclosed string");
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
126 }
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
127
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
128 private Number number() {
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
129 parser.begin();
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
130 if( parser.match("double") ) {
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
131 Number n = inParens();
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
132 if( n==null )
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
133 return parser.failure(null);
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
134 n = Luan.asDouble(n);
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
135 if( n==null )
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
136 return parser.failure(null);
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
137 return n;
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
138 } else if( parser.match("float") ) {
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
139 Number n = inParens();
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
140 if( n==null )
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
141 return parser.failure(null);
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
142 n = Luan.asFloat(n);
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
143 if( n==null )
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
144 return parser.failure(null);
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
145 return n;
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
146 } else if( parser.match("integer") ) {
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
147 Number n = inParens();
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
148 if( n==null )
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
149 return parser.failure(null);
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
150 n = Luan.asInteger(n);
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
151 if( n==null )
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
152 return parser.failure(null);
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
153 return n;
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
154 } else if( parser.match("long") ) {
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
155 Number n = inParens();
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
156 if( n==null )
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
157 return parser.failure(null);
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
158 n = Luan.asLong(n);
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
159 if( n==null )
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
160 return parser.failure(null);
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
161 return n;
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
162 } else {
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
163 Number n = untypedNumber();
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
164 if( n != null )
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
165 return parser.success(n);
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
166 else
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
167 return parser.failure(null);
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
168 }
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
169 }
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
170
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
171 private Number inParens() {
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
172 spaces();
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
173 if( !parser.match('(') )
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
174 return null;
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
175 spaces();
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
176 Number n = untypedNumber();
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
177 if( n==null )
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
178 return null;
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
179 spaces();
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
180 if( !parser.match(')') )
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
181 return null;
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
182 return n;
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
183 }
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
184
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
185 private Number untypedNumber() {
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
186 int start = parser.begin();
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
187 boolean isFloat = false;
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
188 parser.match('-');
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
189 if( !parser.match('0') ) {
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
190 if( !parser.inCharRange('1','9') )
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
191 return parser.failure(null);
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
192 while( parser.inCharRange('0','9') );
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
193 }
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
194 if( parser.match('.') ) {
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
195 if( !parser.inCharRange('0','9') )
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
196 return parser.failure(null);
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
197 while( parser.inCharRange('0','9') );
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
198 isFloat = true;
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
199 }
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
200 if( parser.anyOf("eE") ) {
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
201 parser.anyOf("+-");
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
202 if( !parser.inCharRange('0','9') )
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
203 return parser.failure(null);
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
204 while( parser.inCharRange('0','9') );
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
205 isFloat = true;
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
206 }
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
207 String s = parser.textFrom(start);
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
208 Number n;
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
209 if(isFloat)
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
210 n = Double.valueOf(s);
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
211 else
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
212 n = Long.valueOf(s);
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
213 return parser.success(n);
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
214 }
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
215
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
216 private LuanTable table() throws ParseException {
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
217 parser.begin();
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
218 if( !parser.match('{') )
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
219 return parser.failure(null);
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
220 LuanTable tbl = new LuanTable(luan);
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
221 do {
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
222 spaces();
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
223 Object obj = value();
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
224 if( obj != null ) {
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
225 if( obj != NULL )
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
226 tbl.rawAdd(obj);
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
227 spaces();
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
228 continue;
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
229 }
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
230 Object key = key();
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
231 if( key != null ) {
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
232 spaces();
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
233 requiredMatch('=');
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
234 spaces();
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
235 Object value = requiredValue();
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
236 spaces();
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
237 try {
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
238 tbl.rawPut(key,value);
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
239 } catch(LuanException e) {
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
240 throw new RuntimeException(e);
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
241 }
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
242 }
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
243 } while( fieldSep() );
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
244 requiredMatch('}');
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
245 return parser.success(tbl);
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
246 }
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
247
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
248 private Object key() throws ParseException {
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
249 if( parser.match('[') ) {
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
250 spaces();
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
251 Object key = requiredValue();
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
252 spaces();
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
253 requiredMatch(']');
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
254 return key;
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
255 }
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
256 int start = parser.currentIndex();
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
257 if( nameFirstChar() ) {
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
258 while( nameChar() );
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
259 return parser.textFrom(start);
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
260 }
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
261 return null;
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
262 }
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
263
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
264 private boolean nameChar() {
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
265 return nameFirstChar() || parser.inCharRange('0','9');
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
266 }
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
267
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
268 private boolean nameFirstChar() {
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
269 return parser.inCharRange('a','z') || parser.inCharRange('A','Z') || parser.match('_');
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
270 }
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
271
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
272 private boolean fieldSep() throws ParseException {
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
273 return parser.anyOf(",;") || endOfLine();
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
274 }
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
275
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
276 private boolean endOfLine() {
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
277 return parser.match( "\r\n" ) || parser.match( '\r' ) || parser.match( '\n' );
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
278 }
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
279
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
280 private void requiredMatch(char c) throws ParseException {
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
281 if( !parser.match(c) )
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
282 throw exception("'"+c+"' expected");
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
283 }
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
284
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
285 private void spaces() {
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
286 while( parser.anyOf(" \t") );
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
287 }
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
288
851b9a48cc44 Luan.parse
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
289 }