1 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
---|
2 | * JFlex 1.4.3 *
|
---|
3 | * Copyright (C) 1998-2009 Gerwin Klein <[email protected]> *
|
---|
4 | * All rights reserved. *
|
---|
5 | * *
|
---|
6 | * This program is free software; you can redistribute it and/or modify *
|
---|
7 | * it under the terms of the GNU General Public License. See the file *
|
---|
8 | * COPYRIGHT for more information. *
|
---|
9 | * *
|
---|
10 | * This program is distributed in the hope that it will be useful, *
|
---|
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
---|
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
---|
13 | * GNU General Public License for more details. *
|
---|
14 | * *
|
---|
15 | * You should have received a copy of the GNU General Public License along *
|
---|
16 | * with this program; if not, write to the Free Software Foundation, Inc., *
|
---|
17 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
|
---|
18 | * *
|
---|
19 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
---|
20 |
|
---|
21 | package JFlex;
|
---|
22 |
|
---|
23 | import java.util.*;
|
---|
24 |
|
---|
25 | /* customizing code */
|
---|
26 |
|
---|
27 | action code {:
|
---|
28 |
|
---|
29 | LexScan scanner;
|
---|
30 | CharClasses charClasses = new CharClasses(Options.jlex ? 127 : 0xFFFF);
|
---|
31 | RegExps regExps = new RegExps();
|
---|
32 | Macros macros = new Macros();
|
---|
33 | Integer stateNumber;
|
---|
34 | Timer t = new Timer();
|
---|
35 | EOFActions eofActions = new EOFActions();
|
---|
36 |
|
---|
37 | void fatalError(ErrorMessages message, int line, int col) {
|
---|
38 | syntaxError(message, line, col);
|
---|
39 | throw new GeneratorException();
|
---|
40 | }
|
---|
41 |
|
---|
42 | void fatalError(ErrorMessages message) {
|
---|
43 | fatalError(message, scanner.currentLine(), -1);
|
---|
44 | throw new GeneratorException();
|
---|
45 | }
|
---|
46 |
|
---|
47 | void syntaxError(ErrorMessages message) {
|
---|
48 | Out.error(scanner.file, message, scanner.currentLine(), -1);
|
---|
49 | }
|
---|
50 |
|
---|
51 | void syntaxError(ErrorMessages message, int line) {
|
---|
52 | Out.error(scanner.file, message, line, -1);
|
---|
53 | }
|
---|
54 |
|
---|
55 | void syntaxError(ErrorMessages message, int line, int col) {
|
---|
56 | Out.error(scanner.file, message, line, col);
|
---|
57 | }
|
---|
58 |
|
---|
59 |
|
---|
60 | private boolean check(int type, char c) {
|
---|
61 | switch (type) {
|
---|
62 | case sym.JLETTERCLASS:
|
---|
63 | return Character.isJavaIdentifierStart(c);
|
---|
64 |
|
---|
65 | case sym.JLETTERDIGITCLASS:
|
---|
66 | return Character.isJavaIdentifierPart(c);
|
---|
67 |
|
---|
68 | case sym.LETTERCLASS:
|
---|
69 | return Character.isLetter(c);
|
---|
70 |
|
---|
71 | case sym.DIGITCLASS:
|
---|
72 | return Character.isDigit(c);
|
---|
73 |
|
---|
74 | case sym.UPPERCLASS:
|
---|
75 | return Character.isUpperCase(c);
|
---|
76 |
|
---|
77 | case sym.LOWERCLASS:
|
---|
78 | return Character.isLowerCase(c);
|
---|
79 |
|
---|
80 | default: return false;
|
---|
81 | }
|
---|
82 | }
|
---|
83 |
|
---|
84 | private Vector makePreClass(int type) {
|
---|
85 |
|
---|
86 | Vector result = new Vector();
|
---|
87 |
|
---|
88 | char c = 0;
|
---|
89 | char start = 0;
|
---|
90 | char last = charClasses.getMaxCharCode();
|
---|
91 |
|
---|
92 | boolean prev, current;
|
---|
93 |
|
---|
94 | prev = check(type,'\u0000');
|
---|
95 |
|
---|
96 | for (c = 1; c < last; c++) {
|
---|
97 |
|
---|
98 | current = check(type,c);
|
---|
99 |
|
---|
100 | if (!prev && current) start = c;
|
---|
101 | if (prev && !current) {
|
---|
102 | result.addElement(new Interval(start, (char)(c-1)));
|
---|
103 | }
|
---|
104 |
|
---|
105 | prev = current;
|
---|
106 | }
|
---|
107 |
|
---|
108 | // the last iteration is moved out of the loop to
|
---|
109 | // avoid an endless loop if last == maxCharCode and
|
---|
110 | // last+1 == 0
|
---|
111 | current = check(type,c);
|
---|
112 |
|
---|
113 | if (!prev && current) result.addElement(new Interval(c,c));
|
---|
114 | if (prev && current) result.addElement(new Interval(start, c));
|
---|
115 | if (prev && !current) result.addElement(new Interval(start, (char)(c-1)));
|
---|
116 |
|
---|
117 | return result;
|
---|
118 | }
|
---|
119 |
|
---|
120 | private RegExp makeRepeat(RegExp r, int n1, int n2, int line, int col) {
|
---|
121 |
|
---|
122 | if (n1 <= 0 && n2 <= 0) {
|
---|
123 | syntaxError(ErrorMessages.REPEAT_ZERO, line, col);
|
---|
124 | return null;
|
---|
125 | }
|
---|
126 |
|
---|
127 | if (n1 > n2) {
|
---|
128 | syntaxError(ErrorMessages.REPEAT_GREATER, line, col);
|
---|
129 | return null;
|
---|
130 | }
|
---|
131 |
|
---|
132 | int i;
|
---|
133 | RegExp result;
|
---|
134 |
|
---|
135 | if (n1 > 0) {
|
---|
136 | result = r;
|
---|
137 | n1--; n2--; // we need one concatenation less than the number of expressions to match
|
---|
138 | }
|
---|
139 | else {
|
---|
140 | result = new RegExp1(sym.QUESTION,r);
|
---|
141 | n2--;
|
---|
142 | }
|
---|
143 |
|
---|
144 | for (i = 0; i < n1; i++)
|
---|
145 | result = new RegExp2(sym.CONCAT, result, r);
|
---|
146 |
|
---|
147 | n2-= n1;
|
---|
148 | for (i = 0; i < n2; i++)
|
---|
149 | result = new RegExp2(sym.CONCAT, result, new RegExp1(sym.QUESTION,r));
|
---|
150 |
|
---|
151 | return result;
|
---|
152 | }
|
---|
153 |
|
---|
154 | private RegExp makeNL() {
|
---|
155 | Vector list = new Vector();
|
---|
156 | list.addElement(new Interval('\n','\r'));
|
---|
157 | list.addElement(new Interval('\u0085','\u0085'));
|
---|
158 | list.addElement(new Interval('\u2028','\u2029'));
|
---|
159 |
|
---|
160 | // assumption: line feeds are caseless
|
---|
161 | charClasses.makeClass(list, false);
|
---|
162 | charClasses.makeClass('\n', false);
|
---|
163 | charClasses.makeClass('\r', false);
|
---|
164 |
|
---|
165 | RegExp1 c = new RegExp1(sym.CCLASS, list);
|
---|
166 | Character n = new Character('\n');
|
---|
167 | Character r = new Character('\r');
|
---|
168 |
|
---|
169 | return new RegExp2(sym.BAR,
|
---|
170 | c,
|
---|
171 | new RegExp2(sym.CONCAT,
|
---|
172 | new RegExp1(sym.CHAR, r),
|
---|
173 | new RegExp1(sym.CHAR, n)));
|
---|
174 | }
|
---|
175 |
|
---|
176 | :};
|
---|
177 |
|
---|
178 | parser code {:
|
---|
179 | public LexScan scanner;
|
---|
180 |
|
---|
181 | public LexParse(LexScan scanner) {
|
---|
182 | super(scanner);
|
---|
183 | this.scanner = scanner;
|
---|
184 | }
|
---|
185 |
|
---|
186 | public CharClasses getCharClasses() {
|
---|
187 | return action_obj.charClasses;
|
---|
188 | }
|
---|
189 |
|
---|
190 | public EOFActions getEOFActions() {
|
---|
191 | return action_obj.eofActions;
|
---|
192 | }
|
---|
193 |
|
---|
194 | public void report_error(String message, Object info) {
|
---|
195 | if ( info instanceof java_cup.runtime.Symbol ) {
|
---|
196 | java_cup.runtime.Symbol s = (java_cup.runtime.Symbol) info;
|
---|
197 |
|
---|
198 | if (s.sym == sym.EOF)
|
---|
199 | Out.error(ErrorMessages.UNEXPECTED_EOF);
|
---|
200 | else
|
---|
201 | Out.error(scanner.file, ErrorMessages.SYNTAX_ERROR, s.left, s.right);
|
---|
202 | }
|
---|
203 | else
|
---|
204 | Out.error(ErrorMessages.UNKNOWN_SYNTAX);
|
---|
205 | }
|
---|
206 |
|
---|
207 | public void report_fatal_error(String message, Object info) {
|
---|
208 | // report_error(message, info);
|
---|
209 | throw new GeneratorException();
|
---|
210 | }
|
---|
211 |
|
---|
212 | :};
|
---|
213 |
|
---|
214 | init with {:
|
---|
215 | action_obj.scanner = this.scanner;
|
---|
216 | :};
|
---|
217 |
|
---|
218 | /* token declarations */
|
---|
219 |
|
---|
220 | terminal OPENBRACKET, CLOSEBRACKET, HAT, DOLLAR, OPENCLASS,
|
---|
221 | CLOSECLASS, DASH, DELIMITER, EQUALS, COMMA, LESSTHAN,
|
---|
222 | MORETHAN, LBRACE, RBRACE, ASCII, FULL, UNICODE, REGEXPEND;
|
---|
223 |
|
---|
224 | terminal JLETTERCLASS, JLETTERDIGITCLASS, LETTERCLASS, DIGITCLASS,
|
---|
225 | UPPERCLASS, LOWERCLASS, EOFRULE, NOACTION, LOOKAHEAD;
|
---|
226 |
|
---|
227 | terminal Action ACTION;
|
---|
228 | terminal String IDENT, USERCODE;
|
---|
229 | terminal Integer REPEAT;
|
---|
230 |
|
---|
231 | /* tokens used in RegExp parse tree */
|
---|
232 | terminal STAR, PLUS, BAR, QUESTION, POINT, BANG, TILDE;
|
---|
233 |
|
---|
234 | terminal Character CHAR;
|
---|
235 | terminal String STRING, MACROUSE;
|
---|
236 |
|
---|
237 | /* symbols *only* used in the parse tree (not in the grammar) */
|
---|
238 | terminal CCLASS, CCLASSNOT, CONCAT;
|
---|
239 | terminal STRING_I, CHAR_I; /* case insensitive strings/chars */
|
---|
240 |
|
---|
241 |
|
---|
242 | non terminal macros, macro;
|
---|
243 | non terminal Integer rule;
|
---|
244 | non terminal NFA specification;
|
---|
245 | non terminal RegExp series, concs, nregexp, regexp, charclass, lookahead;
|
---|
246 | non terminal Interval classcontentelem;
|
---|
247 | non terminal Vector states, statesOPT, classcontent, preclass, rules;
|
---|
248 | non terminal Boolean hatOPT;
|
---|
249 | non terminal Action act, actions;
|
---|
250 |
|
---|
251 |
|
---|
252 | /* grammar specification */
|
---|
253 | start with specification;
|
---|
254 |
|
---|
255 | specification ::= USERCODE
|
---|
256 | /* delimiter is checked in lexer */
|
---|
257 | macros
|
---|
258 | DELIMITER
|
---|
259 | rules
|
---|
260 | {:
|
---|
261 | scanner.t.stop();
|
---|
262 |
|
---|
263 | Out.checkErrors();
|
---|
264 |
|
---|
265 | Out.time(ErrorMessages.PARSING_TOOK, t);
|
---|
266 |
|
---|
267 | macros.expand();
|
---|
268 | Enumeration unused = macros.unused();
|
---|
269 | while ( unused.hasMoreElements() ) {
|
---|
270 | Out.warning("Macro \""+unused.nextElement()+"\" has been declared but never used.");
|
---|
271 | }
|
---|
272 |
|
---|
273 | SemCheck.check(regExps, macros, scanner.file);
|
---|
274 |
|
---|
275 | regExps.checkActions();
|
---|
276 | regExps.checkLookAheads();
|
---|
277 |
|
---|
278 | Out.checkErrors();
|
---|
279 |
|
---|
280 | if (Options.dump) charClasses.dump();
|
---|
281 |
|
---|
282 | Out.print("Constructing NFA : ");
|
---|
283 |
|
---|
284 | t.start();
|
---|
285 | int num = regExps.getNum();
|
---|
286 |
|
---|
287 | RESULT = new NFA(charClasses.getNumClasses(),
|
---|
288 | scanner, regExps, macros, charClasses);
|
---|
289 |
|
---|
290 | eofActions.setNumLexStates(scanner.states.number());
|
---|
291 |
|
---|
292 | for (int i = 0; i < num; i++) {
|
---|
293 | if (regExps.isEOF(i))
|
---|
294 | eofActions.add( regExps.getStates(i), regExps.getAction(i) );
|
---|
295 | else
|
---|
296 | RESULT.addRegExp(i);
|
---|
297 | }
|
---|
298 |
|
---|
299 | if (scanner.standalone) RESULT.addStandaloneRule();
|
---|
300 | t.stop();
|
---|
301 |
|
---|
302 | Out.time("");
|
---|
303 | Out.time(ErrorMessages.NFA_TOOK, t);
|
---|
304 |
|
---|
305 | :}
|
---|
306 | | /* emtpy spec. error */
|
---|
307 | {:
|
---|
308 | fatalError(ErrorMessages.NO_LEX_SPEC);
|
---|
309 | :}
|
---|
310 | ;
|
---|
311 |
|
---|
312 | macros ::= /* empty, most switches & state declarations are parsed in lexer */
|
---|
313 | | macros macro
|
---|
314 | | error;
|
---|
315 |
|
---|
316 | macro ::= ASCII
|
---|
317 | {: charClasses.setMaxCharCode(127); :}
|
---|
318 | | FULL
|
---|
319 | {: charClasses.setMaxCharCode(255); :}
|
---|
320 | | UNICODE
|
---|
321 | {: charClasses.setMaxCharCode(0xFFFF); :}
|
---|
322 | | IDENT:name EQUALS series:definition REGEXPEND
|
---|
323 | {: macros.insert(name, definition); :}
|
---|
324 | | IDENT EQUALS:e
|
---|
325 | {: syntaxError(ErrorMessages.REGEXP_EXPECTED, eleft, eright); :}
|
---|
326 | ;
|
---|
327 |
|
---|
328 |
|
---|
329 | rules ::= rules:rlist rule:r
|
---|
330 | {: rlist.addElement(r); RESULT = rlist; :}
|
---|
331 | | rules:rlist1 LESSTHAN states:states MORETHAN LBRACE rules:rlist2 RBRACE
|
---|
332 | {:
|
---|
333 | Enumeration rs = rlist2.elements();
|
---|
334 | while ( rs.hasMoreElements() ) {
|
---|
335 | Integer elem = (Integer) rs.nextElement();
|
---|
336 | // might be null for error case of "rule"
|
---|
337 | if (elem != null) {
|
---|
338 | regExps.addStates( elem.intValue(), states );
|
---|
339 | }
|
---|
340 | rlist1.addElement( elem );
|
---|
341 | }
|
---|
342 | RESULT = rlist1;
|
---|
343 | :}
|
---|
344 | | LESSTHAN states:states MORETHAN LBRACE rules:rlist RBRACE
|
---|
345 | {:
|
---|
346 | Enumeration rs = rlist.elements();
|
---|
347 | while ( rs.hasMoreElements() ) {
|
---|
348 | Integer elem = (Integer) rs.nextElement();
|
---|
349 | // might be null for error case of "rule"
|
---|
350 | if (elem != null) {
|
---|
351 | regExps.addStates( elem.intValue(), states );
|
---|
352 | }
|
---|
353 | }
|
---|
354 | RESULT = rlist;
|
---|
355 | :}
|
---|
356 | | rule:r
|
---|
357 | {: RESULT = new Vector(); RESULT.addElement(r); :}
|
---|
358 | ;
|
---|
359 |
|
---|
360 | rule ::= statesOPT:s hatOPT:bol series:r actions:a
|
---|
361 | {: RESULT = new Integer(regExps.insert(rleft, s, r, a, bol, null)); :}
|
---|
362 | | statesOPT:s hatOPT:bol series:r lookahead:l act:a
|
---|
363 | {: RESULT = new Integer(regExps.insert(rleft, s, r, a, bol, l)); :}
|
---|
364 | | statesOPT:s hatOPT:bol series:r lookahead:l NOACTION:a
|
---|
365 | {: syntaxError(ErrorMessages.LOOKAHEAD_NEEDS_ACTION, aleft, aright+1); :}
|
---|
366 | | statesOPT:s EOFRULE ACTION:a
|
---|
367 | {: RESULT = new Integer(regExps.insert(s, a)); :}
|
---|
368 | | error
|
---|
369 | ;
|
---|
370 |
|
---|
371 | lookahead ::= DOLLAR
|
---|
372 | {: RESULT = makeNL(); :}
|
---|
373 | | LOOKAHEAD series:r
|
---|
374 | {: RESULT = r; :}
|
---|
375 | | LOOKAHEAD series:s DOLLAR
|
---|
376 | {: RESULT = new RegExp2(sym.CONCAT, s, makeNL()); :}
|
---|
377 | ;
|
---|
378 |
|
---|
379 | act ::= REGEXPEND ACTION:a
|
---|
380 | {: RESULT = a; :}
|
---|
381 | ;
|
---|
382 |
|
---|
383 | actions ::= act:a
|
---|
384 | {: RESULT = a; :}
|
---|
385 | | NOACTION
|
---|
386 | ;
|
---|
387 |
|
---|
388 |
|
---|
389 | statesOPT ::= LESSTHAN states:list MORETHAN
|
---|
390 | {: RESULT = list; :}
|
---|
391 | | /* empty */
|
---|
392 | {: RESULT = new Vector(); :}
|
---|
393 | ;
|
---|
394 |
|
---|
395 | states ::= IDENT:id COMMA states:list
|
---|
396 | {:
|
---|
397 | stateNumber = scanner.states.getNumber( id );
|
---|
398 | if ( stateNumber != null )
|
---|
399 | list.addElement( stateNumber );
|
---|
400 | else {
|
---|
401 | throw new ScannerException(scanner.file, ErrorMessages.LEXSTATE_UNDECL,
|
---|
402 | idleft, idright);
|
---|
403 | }
|
---|
404 | RESULT = list;
|
---|
405 | :}
|
---|
406 | | IDENT:id
|
---|
407 | {:
|
---|
408 | Vector list = new Vector();
|
---|
409 | stateNumber = scanner.states.getNumber( id );
|
---|
410 | if ( stateNumber != null )
|
---|
411 | list.addElement( stateNumber );
|
---|
412 | else {
|
---|
413 | throw new ScannerException(scanner.file, ErrorMessages.LEXSTATE_UNDECL,
|
---|
414 | idleft, idright);
|
---|
415 | }
|
---|
416 | RESULT = list;
|
---|
417 | :}
|
---|
418 | | IDENT COMMA:c
|
---|
419 | {: syntaxError(ErrorMessages.REGEXP_EXPECTED, cleft, cright+1); :}
|
---|
420 | ;
|
---|
421 |
|
---|
422 | hatOPT ::= HAT
|
---|
423 | {: // assumption: there is no upper case for \n
|
---|
424 | charClasses.makeClass('\n', false);
|
---|
425 | RESULT = new Boolean(true); :}
|
---|
426 | | /* empty */
|
---|
427 | {: RESULT = new Boolean(false); :}
|
---|
428 | ;
|
---|
429 |
|
---|
430 | series ::= series:r1 BAR concs:r2
|
---|
431 | {: RESULT = new RegExp2(sym.BAR, r1, r2); :}
|
---|
432 | | concs:r
|
---|
433 | {: RESULT = r; :}
|
---|
434 | | BAR:b
|
---|
435 | {: syntaxError(ErrorMessages.REGEXP_EXPECTED, bleft, bright); :}
|
---|
436 | ;
|
---|
437 |
|
---|
438 | concs ::= concs:r1 nregexp:r2
|
---|
439 | {: RESULT = new RegExp2(sym.CONCAT, r1, r2); :}
|
---|
440 | | nregexp:r
|
---|
441 | {: RESULT = r; :}
|
---|
442 | ;
|
---|
443 |
|
---|
444 | nregexp ::= regexp:r
|
---|
445 | {: RESULT = r; :}
|
---|
446 | | BANG nregexp:r
|
---|
447 | {: RESULT = new RegExp1(sym.BANG, r); :}
|
---|
448 | | TILDE nregexp:r
|
---|
449 | {: RESULT = new RegExp1(sym.TILDE, r); :}
|
---|
450 | ;
|
---|
451 |
|
---|
452 | regexp ::= regexp:r STAR
|
---|
453 | {: RESULT = new RegExp1(sym.STAR, r); :}
|
---|
454 | | regexp:r PLUS
|
---|
455 | {: RESULT = new RegExp1(sym.PLUS, r); :}
|
---|
456 | | regexp:r QUESTION
|
---|
457 | {: RESULT = new RegExp1(sym.QUESTION, r); :}
|
---|
458 | | regexp:r REPEAT:n RBRACE:b
|
---|
459 | {: RESULT = makeRepeat(r, n.intValue(), n.intValue(), bleft, bright); :}
|
---|
460 | | regexp:r REPEAT:n1 REPEAT:n2 RBRACE
|
---|
461 | {: RESULT = makeRepeat(r, n1.intValue(), n2.intValue(), n1left, n2right); :}
|
---|
462 | | OPENBRACKET series:r CLOSEBRACKET
|
---|
463 | {: RESULT = r; :}
|
---|
464 | | MACROUSE:ident
|
---|
465 | {:
|
---|
466 | if ( !scanner.macroDefinition ) {
|
---|
467 | if ( ! macros.markUsed(ident) )
|
---|
468 | throw new ScannerException(scanner.file, ErrorMessages.MACRO_UNDECL,
|
---|
469 | identleft, identright);
|
---|
470 | }
|
---|
471 | RESULT = new RegExp1(sym.MACROUSE, ident);
|
---|
472 | :}
|
---|
473 | | charclass:c
|
---|
474 | {: RESULT = c; :}
|
---|
475 | | preclass:list
|
---|
476 | {:
|
---|
477 | try {
|
---|
478 | // assumption [correct?]: preclasses are already closed under case
|
---|
479 | charClasses.makeClass(list, false);
|
---|
480 | }
|
---|
481 | catch (CharClassException e) {
|
---|
482 | syntaxError(ErrorMessages.CHARSET_2_SMALL, listleft);
|
---|
483 | }
|
---|
484 | RESULT = new RegExp1(sym.CCLASS, list);
|
---|
485 | :}
|
---|
486 | | STRING:str
|
---|
487 | {:
|
---|
488 | try {
|
---|
489 | if ( scanner.caseless ) {
|
---|
490 | charClasses.makeClass(str, true);
|
---|
491 | RESULT = new RegExp1(sym.STRING_I, str);
|
---|
492 | }
|
---|
493 | else {
|
---|
494 | charClasses.makeClass(str, false);
|
---|
495 | RESULT = new RegExp1(sym.STRING, str);
|
---|
496 | }
|
---|
497 | }
|
---|
498 | catch (CharClassException e) {
|
---|
499 | syntaxError(ErrorMessages.CS2SMALL_STRING, strleft, strright);
|
---|
500 | }
|
---|
501 |
|
---|
502 | :}
|
---|
503 | | POINT
|
---|
504 | {:
|
---|
505 | Vector any = new Vector();
|
---|
506 | any.addElement(new Interval('\n','\n'));
|
---|
507 | // assumption: there is no upper case for \n
|
---|
508 | charClasses.makeClass('\n', false);
|
---|
509 | RESULT = new RegExp1(sym.CCLASSNOT, any);
|
---|
510 | :}
|
---|
511 | | CHAR:c
|
---|
512 | {:
|
---|
513 | try {
|
---|
514 | if ( scanner.caseless ) {
|
---|
515 | charClasses.makeClass(c.charValue(), true);
|
---|
516 | RESULT = new RegExp1(sym.CHAR_I, c);
|
---|
517 | }
|
---|
518 | else {
|
---|
519 | charClasses.makeClass(c.charValue(), false);
|
---|
520 | RESULT = new RegExp1(sym.CHAR, c);
|
---|
521 | }
|
---|
522 | }
|
---|
523 | catch (CharClassException e) {
|
---|
524 | syntaxError(ErrorMessages.CS2SMALL_CHAR, cleft, cright);
|
---|
525 | }
|
---|
526 | :}
|
---|
527 | ;
|
---|
528 |
|
---|
529 | charclass ::= OPENCLASS CLOSECLASS
|
---|
530 | {:
|
---|
531 | RESULT = new RegExp1(sym.CCLASS,null);
|
---|
532 | :}
|
---|
533 | | OPENCLASS classcontent:list CLOSECLASS:close
|
---|
534 | {:
|
---|
535 | try {
|
---|
536 | charClasses.makeClass(list, Options.jlex && scanner.caseless);
|
---|
537 | }
|
---|
538 | catch (CharClassException e) {
|
---|
539 | syntaxError(ErrorMessages.CHARSET_2_SMALL, closeleft, closeright);
|
---|
540 | }
|
---|
541 | RESULT = new RegExp1(sym.CCLASS,list);
|
---|
542 | :}
|
---|
543 | | OPENCLASS HAT CLOSECLASS:close
|
---|
544 | {:
|
---|
545 | Vector list = new Vector();
|
---|
546 | list.addElement(new Interval((char)0,CharClasses.maxChar));
|
---|
547 | try {
|
---|
548 | charClasses.makeClass(list, false);
|
---|
549 | }
|
---|
550 | catch (CharClassException e) {
|
---|
551 | syntaxError(ErrorMessages.CHARSET_2_SMALL, closeleft, closeright);
|
---|
552 | }
|
---|
553 | RESULT = new RegExp1(sym.CCLASS,list);
|
---|
554 | :}
|
---|
555 | | OPENCLASS HAT classcontent:list CLOSECLASS:close
|
---|
556 | {:
|
---|
557 | try {
|
---|
558 | charClasses.makeClassNot(list, Options.jlex && scanner.caseless);
|
---|
559 | }
|
---|
560 | catch (CharClassException e) {
|
---|
561 | syntaxError(ErrorMessages.CHARSET_2_SMALL, closeleft, closeright);
|
---|
562 | }
|
---|
563 | RESULT = new RegExp1(sym.CCLASSNOT,list);
|
---|
564 | :}
|
---|
565 | | OPENCLASS DASH classcontent:list CLOSECLASS:close
|
---|
566 | {:
|
---|
567 | try {
|
---|
568 | list.addElement(new Interval('-','-'));
|
---|
569 | charClasses.makeClass(list, Options.jlex && scanner.caseless);
|
---|
570 | }
|
---|
571 | catch (CharClassException e) {
|
---|
572 | syntaxError(ErrorMessages.CHARSET_2_SMALL, closeleft, closeright);
|
---|
573 | }
|
---|
574 | RESULT = new RegExp1(sym.CCLASS,list);
|
---|
575 | :}
|
---|
576 | | OPENCLASS HAT DASH classcontent:list CLOSECLASS:close
|
---|
577 | {:
|
---|
578 | try {
|
---|
579 | list.addElement(new Interval('-','-'));
|
---|
580 | charClasses.makeClassNot(list, Options.jlex && scanner.caseless);
|
---|
581 | }
|
---|
582 | catch (CharClassException e) {
|
---|
583 | syntaxError(ErrorMessages.CHARSET_2_SMALL, closeleft, closeright);
|
---|
584 | }
|
---|
585 | RESULT = new RegExp1(sym.CCLASSNOT,list);
|
---|
586 | :}
|
---|
587 | ;
|
---|
588 |
|
---|
589 | classcontent ::= classcontent:list classcontentelem:elem
|
---|
590 | {:
|
---|
591 | list.addElement(elem);
|
---|
592 | RESULT = list;
|
---|
593 | :}
|
---|
594 | | classcontentelem:elem
|
---|
595 | {:
|
---|
596 | Vector list = new Vector();
|
---|
597 | list.addElement(elem);
|
---|
598 | RESULT = list;
|
---|
599 | :}
|
---|
600 | | classcontent:list preclass:plist
|
---|
601 | {:
|
---|
602 | for (Enumeration e = plist.elements(); e.hasMoreElements();)
|
---|
603 | list.addElement(e.nextElement());
|
---|
604 | RESULT = list;
|
---|
605 | :}
|
---|
606 | | preclass:list
|
---|
607 | {: RESULT = list; :}
|
---|
608 | | classcontent:list STRING:s
|
---|
609 | {:
|
---|
610 | for (int i = 0; i < s.length(); i++)
|
---|
611 | list.addElement(new Interval(s.charAt(i),s.charAt(i)));
|
---|
612 | RESULT = list;
|
---|
613 | :}
|
---|
614 | | STRING:s
|
---|
615 | {:
|
---|
616 | RESULT = new Vector();
|
---|
617 | for (int i = 0; i < s.length(); i++)
|
---|
618 | RESULT.addElement(new Interval(s.charAt(i),s.charAt(i)));
|
---|
619 | :}
|
---|
620 | | classcontent:list MACROUSE:ident
|
---|
621 | {:
|
---|
622 | syntaxError(ErrorMessages.CHARCLASS_MACRO, identleft, identright);
|
---|
623 | :}
|
---|
624 | | MACROUSE:ident
|
---|
625 | {:
|
---|
626 | syntaxError(ErrorMessages.CHARCLASS_MACRO, identleft, identright);
|
---|
627 | :}
|
---|
628 | ;
|
---|
629 |
|
---|
630 | classcontentelem ::= CHAR:c1 DASH CHAR:c2
|
---|
631 | {: RESULT = new Interval(c1.charValue(), c2.charValue()); :}
|
---|
632 | | CHAR:c
|
---|
633 | {: RESULT = new Interval(c.charValue(), c.charValue()); :}
|
---|
634 | ;
|
---|
635 |
|
---|
636 | preclass ::= JLETTERCLASS
|
---|
637 | {: RESULT = makePreClass(sym.JLETTERCLASS); :}
|
---|
638 | | JLETTERDIGITCLASS
|
---|
639 | {: RESULT = makePreClass(sym.JLETTERDIGITCLASS); :}
|
---|
640 | | LETTERCLASS
|
---|
641 | {: RESULT = makePreClass(sym.LETTERCLASS); :}
|
---|
642 | | DIGITCLASS
|
---|
643 | {: RESULT = makePreClass(sym.DIGITCLASS); :}
|
---|
644 | | UPPERCLASS
|
---|
645 | {: RESULT = makePreClass(sym.UPPERCLASS); :}
|
---|
646 | | LOWERCLASS
|
---|
647 | {: RESULT = makePreClass(sym.LOWERCLASS); :}
|
---|
648 | ;
|
---|