9
|
1 package plparser;
|
|
2
|
|
3 import java.io.FileNotFoundException;
|
|
4 import java.io.FileReader;
|
|
5 import java.io.InputStream;
|
|
6 import java.io.InputStreamReader;
|
|
7 import java.io.Reader;
|
|
8 import java.io.StringReader;
|
|
9 import java.util.Scanner;
|
|
10 import java.util.regex.Pattern;
|
|
11
|
|
12 /**
|
|
13 * delimiter に何を設定しても動いてくれない。
|
|
14 * */
|
|
15
|
|
16 public class PropertyListStreamScanner<T> extends PLScannerImpl<T> implements
|
|
17 PLScanner<T> {
|
|
18
|
|
19 private Scanner scan;
|
|
20
|
|
21 public PropertyListStreamScanner(
|
|
22 PLScanner<T> s,
|
|
23 Dictionary<T> dict, Token<T> nullToken) {
|
11
|
24 super(s,dict,nullToken);
|
9
|
25 }
|
|
26
|
|
27 public void init() {
|
|
28 String pattern = ".";
|
|
29 scan.useDelimiter(pattern);
|
|
30 }
|
|
31
|
|
32 // Pattern must contain exact 1 group
|
|
33 private static Pattern tokenPat = Pattern.compile(
|
|
34 "([={}(),;])"
|
|
35 );
|
|
36 private static Pattern namePat = Pattern.compile("([_a-zA-Z][\\@\\w]*)");
|
|
37 private static final Pattern numPat = Pattern.compile("([0-9]+)");
|
|
38 private static final Pattern stringPat1 = Pattern.compile("\\\"([^\"]*)\\\"");
|
|
39 private static final Pattern stringPat = Pattern.compile("\\'([^\\']*)\\'");
|
|
40 private static final Pattern stringPat1cont = Pattern.compile("\\\"([^\"]*)$");
|
|
41 private static final Pattern stringPatCont = Pattern.compile("\\'([^\\']*)$");
|
|
42 private static final Pattern stringPat1End = Pattern.compile("([^\"]*)\\\"");
|
|
43 private static final Pattern stringPatEnd = Pattern.compile("([^\\']*)\'");
|
|
44 private static final Pattern commentPat = Pattern.compile("(//.*)");
|
|
45 private static final Pattern commentPat1 = Pattern.compile("(/\\*)");
|
|
46 private static final Pattern commentPat1End = Pattern.compile("(.*\\*/)");
|
|
47 private static final Pattern errorPat = Pattern.compile("([^\\s])");
|
|
48 private static final Pattern anyPat = Pattern.compile("(.)");
|
|
49
|
|
50 @Override
|
|
51 public Token<T> nextToken() {
|
|
52 String s;
|
|
53 nextToken = nullToken;
|
|
54 while(hasRemaining()) {
|
|
55 if ((s=scan.next(tokenPat))!=null) {
|
|
56 Token<T> t;
|
|
57 if ((t = dict.get(s))==null) {
|
|
58 dict.put(s, t = new Token<T>(s,TokenID.Any));
|
|
59 }
|
|
60 return nextToken = t;
|
|
61 } else if ((s=scan.next(stringPatCont))!=null) {
|
|
62 // non terminated string
|
|
63 String s1;
|
|
64 while((s1=scan.next(stringPatEnd))==null) {
|
|
65 s += scan.nextLine();
|
|
66 lineno++;
|
|
67 }
|
|
68 s += s1;
|
|
69 Token<T> t;
|
|
70 if ((t = dict.get(s))==null) {
|
|
71 dict.put(s, t = new Token<T>(s,TokenID.VARIABLE));
|
|
72 }
|
|
73 return nextToken = t;
|
|
74 } else if ((s=scan.next(stringPat1cont))!=null) {
|
|
75 // non terminated string
|
|
76 String s1;
|
|
77 while((s1=scan.next(stringPat1End))==null) {
|
|
78 s += scan.nextLine();
|
|
79 lineno++;
|
|
80 }
|
|
81 s += s1;
|
|
82 Token<T> t;
|
|
83 if ((t = dict.get(s))==null) {
|
|
84 dict.put(s, t = new Token<T>(s,TokenID.VARIABLE));
|
|
85 }
|
|
86 return nextToken = t;
|
|
87 } else if ((s=scan.next(stringPat))!=null||(s=scan.next(stringPat1))!=null||(s=scan.next(namePat))!=null) {
|
|
88 Token<T> t;
|
|
89 if ((t = dict.get(s))==null) {
|
|
90 dict.put(s, t = new Token<T>(s,TokenID.VARIABLE));
|
|
91 }
|
|
92 if (t.type!=TokenID.VARIABLE) {
|
|
93 t = new Token<T>(s,TokenID.VARIABLE);
|
|
94 }
|
|
95 return nextToken = t;
|
|
96 } else if ((s=scan.next(numPat))!=null) {
|
|
97 return nextToken = new Token<T>(s,TokenID.NUMBER);
|
|
98 } else if ((s=scan.next(commentPat))!=null) {
|
|
99 scan.nextLine();
|
|
100 continue;
|
|
101 } else if ((s=scan.next(commentPat1))!=null) {
|
|
102 while(scan.next(commentPat1End)==null) {
|
|
103 scan.nextLine();
|
|
104 lineno++;
|
|
105 }
|
|
106 continue;
|
|
107 } else if ((s=scan.next(errorPat))!=null) {
|
|
108 error("Don't understand '"+s+"'");
|
|
109 continue;
|
|
110 } else if ((s=scan.next(anyPat))!=null) {
|
|
111 // skip space
|
|
112 continue;
|
|
113 } else {
|
|
114 lineno++;
|
|
115 }
|
|
116 }
|
|
117 return nextToken;
|
|
118 }
|
|
119
|
|
120
|
|
121 @Override
|
|
122 public boolean hasRemaining() {
|
|
123 return scan.hasNext(anyPat);
|
|
124 }
|
|
125
|
|
126 @Override
|
|
127 public PLScanner<T> pushScannerFile(InputStream newfile,
|
|
128 String prompt) {
|
|
129 return new PropertyListStreamScanner<T>(this,dict,nullToken).setFile(newfile,prompt);
|
|
130 }
|
|
131
|
|
132 @Override
|
|
133 public PLScanner<T> pushScanner(String exp) {
|
|
134 return new PropertyListStreamScanner<T>(this,dict,nullToken).set(exp);
|
|
135 }
|
|
136
|
|
137 @Override
|
|
138 public PLScanner<T> pushScannerFile(String file)
|
|
139 throws FileNotFoundException {
|
|
140 return new PropertyListStreamScanner<T>(this,dict,nullToken).setFile(file);
|
|
141 }
|
|
142
|
|
143 @Override
|
|
144 public PLScanner<T> set(String exp) {
|
|
145 Reader reader = new StringReader(exp);
|
|
146 scan = new Scanner(reader);
|
|
147 return this;
|
|
148 }
|
|
149
|
|
150 @Override
|
|
151 public PLScanner<T> setFile(String file)
|
|
152 throws FileNotFoundException {
|
|
153 Reader reader = new FileReader(file);
|
|
154 scan = new Scanner(reader);
|
|
155 return this;
|
|
156 }
|
|
157
|
|
158 @Override
|
|
159 public PLScanner<T> set(InputStreamReader reader) {
|
|
160 scan = new Scanner(reader);
|
|
161 return this;
|
|
162 }
|
|
163
|
|
164
|
|
165
|
|
166 }
|