annotate src/luan/modules/parsers/LuanParser.java @ 1574:f118ead273a1

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