/interpreter/tags/at2-build190607/src/edu/vub/util/regexp/RESyntax.java

http://ambienttalk.googlecode.com/ · Java · 563 lines · 194 code · 89 blank · 280 comment · 3 complexity · d10bad2dd3cfee27b9948752dff54bf1 MD5 · raw file

  1. /* gnu/regexp/RESyntax.java
  2. Copyright (C) 2006 Free Software Foundation, Inc.
  3. This file is part of GNU Classpath.
  4. GNU Classpath is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2, or (at your option)
  7. any later version.
  8. GNU Classpath is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GNU Classpath; see the file COPYING. If not, write to the
  14. Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  15. 02110-1301 USA.
  16. Linking this library statically or dynamically with other modules is
  17. making a combined work based on this library. Thus, the terms and
  18. conditions of the GNU General Public License cover the whole
  19. combination.
  20. As a special exception, the copyright holders of this library give you
  21. permission to link this library with independent modules to produce an
  22. executable, regardless of the license terms of these independent
  23. modules, and to copy and distribute the resulting executable under
  24. terms of your choice, provided that you also meet, for each linked
  25. independent module, the terms and conditions of the license of that
  26. module. An independent module is a module which is not derived from
  27. or based on this library. If you modify this library, you may extend
  28. this exception to your version of the library, but you are not
  29. obligated to do so. If you do not wish to do so, delete this
  30. exception statement from your version. */
  31. package edu.vub.util.regexp;
  32. import java.io.Serializable;
  33. import java.util.BitSet;
  34. /**
  35. * An RESyntax specifies the way a regular expression will be compiled.
  36. * This class provides a number of predefined useful constants for
  37. * emulating popular regular expression syntaxes. Additionally the
  38. * user may construct his or her own syntax, using any combination of the
  39. * syntax bit constants. The syntax is an optional argument to any of the
  40. * matching methods on class RE.
  41. *
  42. * @author <A HREF="mailto:wes@cacas.org">Wes Biggs</A>
  43. */
  44. public final class RESyntax implements Serializable {
  45. static final String DEFAULT_LINE_SEPARATOR = System.getProperty("line.separator");
  46. private static final String SYNTAX_IS_FINAL = "Syntax has been declared final and cannot be modified";
  47. private BitSet bits;
  48. // true for the constant defined syntaxes
  49. private boolean isFinal = false;
  50. private String lineSeparator = DEFAULT_LINE_SEPARATOR;
  51. // Values for constants are bit indexes
  52. /**
  53. * Syntax bit. Backslash is an escape character in lists.
  54. */
  55. public static final int RE_BACKSLASH_ESCAPE_IN_LISTS = 0;
  56. /**
  57. * Syntax bit. Use \? instead of ? and \+ instead of +.
  58. */
  59. public static final int RE_BK_PLUS_QM = 1;
  60. /**
  61. * Syntax bit. POSIX character classes ([:...:]) in lists are allowed.
  62. */
  63. public static final int RE_CHAR_CLASSES = 2;
  64. /**
  65. * Syntax bit. ^ and $ are special everywhere.
  66. * <B>Not implemented.</B>
  67. */
  68. public static final int RE_CONTEXT_INDEP_ANCHORS = 3;
  69. /**
  70. * Syntax bit. Repetition operators are only special in valid positions.
  71. * <B>Not implemented.</B>
  72. */
  73. public static final int RE_CONTEXT_INDEP_OPS = 4;
  74. /**
  75. * Syntax bit. Repetition and alternation operators are invalid
  76. * at start and end of pattern and other places.
  77. * <B>Not implemented</B>.
  78. */
  79. public static final int RE_CONTEXT_INVALID_OPS = 5;
  80. /**
  81. * Syntax bit. Match-any-character operator (.) matches a newline.
  82. */
  83. public static final int RE_DOT_NEWLINE = 6;
  84. /**
  85. * Syntax bit. Match-any-character operator (.) does not match a null.
  86. */
  87. public static final int RE_DOT_NOT_NULL = 7;
  88. /**
  89. * Syntax bit. Intervals ({x}, {x,}, {x,y}) are allowed.
  90. */
  91. public static final int RE_INTERVALS = 8;
  92. /**
  93. * Syntax bit. No alternation (|), match one-or-more (+), or
  94. * match zero-or-one (?) operators.
  95. */
  96. public static final int RE_LIMITED_OPS = 9;
  97. /**
  98. * Syntax bit. Newline is an alternation operator.
  99. */
  100. public static final int RE_NEWLINE_ALT = 10; // impl.
  101. /**
  102. * Syntax bit. Intervals use { } instead of \{ \}
  103. */
  104. public static final int RE_NO_BK_BRACES = 11;
  105. /**
  106. * Syntax bit. Grouping uses ( ) instead of \( \).
  107. */
  108. public static final int RE_NO_BK_PARENS = 12;
  109. /**
  110. * Syntax bit. Backreferences not allowed.
  111. */
  112. public static final int RE_NO_BK_REFS = 13;
  113. /**
  114. * Syntax bit. Alternation uses | instead of \|
  115. */
  116. public static final int RE_NO_BK_VBAR = 14;
  117. /**
  118. * Syntax bit. <B>Not implemented</B>.
  119. */
  120. public static final int RE_NO_EMPTY_RANGES = 15;
  121. /**
  122. * Syntax bit. An unmatched right parenthesis (')' or '\)', depending
  123. * on RE_NO_BK_PARENS) will throw an exception when compiling.
  124. */
  125. public static final int RE_UNMATCHED_RIGHT_PAREN_ORD = 16;
  126. /**
  127. * Syntax bit. <B>Not implemented.</B>
  128. */
  129. public static final int RE_HAT_LISTS_NOT_NEWLINE = 17;
  130. /**
  131. * Syntax bit. Stingy matching is allowed (+?, *?, ??, {x,y}?).
  132. */
  133. public static final int RE_STINGY_OPS = 18;
  134. /**
  135. * Syntax bit. Allow character class escapes (\d, \D, \s, \S, \w, \W).
  136. */
  137. public static final int RE_CHAR_CLASS_ESCAPES = 19;
  138. /**
  139. * Syntax bit. Allow use of (?:xxx) grouping (subexpression is not saved).
  140. */
  141. public static final int RE_PURE_GROUPING = 20;
  142. /**
  143. * Syntax bit. Allow use of (?=xxx) and (?!xxx) apply the subexpression
  144. * to the text following the current position without consuming that text.
  145. */
  146. public static final int RE_LOOKAHEAD = 21;
  147. /**
  148. * Syntax bit. Allow beginning- and end-of-string anchors (\A, \Z).
  149. */
  150. public static final int RE_STRING_ANCHORS = 22;
  151. /**
  152. * Syntax bit. Allow embedded comments, (?#comment), as in Perl5.
  153. */
  154. public static final int RE_COMMENTS = 23;
  155. /**
  156. * Syntax bit. Allow character class escapes within lists, as in Perl5.
  157. */
  158. public static final int RE_CHAR_CLASS_ESC_IN_LISTS = 24;
  159. /**
  160. * Syntax bit. Possessive matching is allowed (++, *+, ?+, {x,y}+).
  161. */
  162. public static final int RE_POSSESSIVE_OPS = 25;
  163. /**
  164. * Syntax bit. Allow embedded flags, (?is-x), as in Perl5.
  165. */
  166. public static final int RE_EMBEDDED_FLAGS = 26;
  167. /**
  168. * Syntax bit. Allow octal char (\0377), as in Perl5.
  169. */
  170. public static final int RE_OCTAL_CHAR = 27;
  171. /**
  172. * Syntax bit. Allow hex char (\x1b), as in Perl5.
  173. */
  174. public static final int RE_HEX_CHAR = 28;
  175. /**
  176. * Syntax bit. Allow Unicode char (\u1234), as in Java 1.4.
  177. */
  178. public static final int RE_UNICODE_CHAR = 29;
  179. /**
  180. * Syntax bit. Allow named property (\p{P}, \P{p}), as in Perl5.
  181. */
  182. public static final int RE_NAMED_PROPERTY = 30;
  183. /**
  184. * Syntax bit. Allow nested characterclass ([a-z&&[^p-r]]), as in Java 1.4.
  185. */
  186. public static final int RE_NESTED_CHARCLASS = 31;
  187. private static final int BIT_TOTAL = 32;
  188. /**
  189. * Predefined syntax.
  190. * Emulates regular expression support in the awk utility.
  191. */
  192. public static final RESyntax RE_SYNTAX_AWK;
  193. /**
  194. * Predefined syntax.
  195. * Emulates regular expression support in the ed utility.
  196. */
  197. public static final RESyntax RE_SYNTAX_ED;
  198. /**
  199. * Predefined syntax.
  200. * Emulates regular expression support in the egrep utility.
  201. */
  202. public static final RESyntax RE_SYNTAX_EGREP;
  203. /**
  204. * Predefined syntax.
  205. * Emulates regular expression support in the GNU Emacs editor.
  206. */
  207. public static final RESyntax RE_SYNTAX_EMACS;
  208. /**
  209. * Predefined syntax.
  210. * Emulates regular expression support in the grep utility.
  211. */
  212. public static final RESyntax RE_SYNTAX_GREP;
  213. /**
  214. * Predefined syntax.
  215. * Emulates regular expression support in the POSIX awk specification.
  216. */
  217. public static final RESyntax RE_SYNTAX_POSIX_AWK;
  218. /**
  219. * Predefined syntax.
  220. * Emulates POSIX basic regular expression support.
  221. */
  222. public static final RESyntax RE_SYNTAX_POSIX_BASIC;
  223. /**
  224. * Predefined syntax.
  225. * Emulates regular expression support in the POSIX egrep specification.
  226. */
  227. public static final RESyntax RE_SYNTAX_POSIX_EGREP;
  228. /**
  229. * Predefined syntax.
  230. * Emulates POSIX extended regular expression support.
  231. */
  232. public static final RESyntax RE_SYNTAX_POSIX_EXTENDED;
  233. /**
  234. * Predefined syntax.
  235. * Emulates POSIX basic minimal regular expressions.
  236. */
  237. public static final RESyntax RE_SYNTAX_POSIX_MINIMAL_BASIC;
  238. /**
  239. * Predefined syntax.
  240. * Emulates POSIX extended minimal regular expressions.
  241. */
  242. public static final RESyntax RE_SYNTAX_POSIX_MINIMAL_EXTENDED;
  243. /**
  244. * Predefined syntax.
  245. * Emulates regular expression support in the sed utility.
  246. */
  247. public static final RESyntax RE_SYNTAX_SED;
  248. /**
  249. * Predefined syntax.
  250. * Emulates regular expression support in Larry Wall's perl, version 4,
  251. */
  252. public static final RESyntax RE_SYNTAX_PERL4;
  253. /**
  254. * Predefined syntax.
  255. * Emulates regular expression support in Larry Wall's perl, version 4,
  256. * using single line mode (/s modifier).
  257. */
  258. public static final RESyntax RE_SYNTAX_PERL4_S; // single line mode (/s)
  259. /**
  260. * Predefined syntax.
  261. * Emulates regular expression support in Larry Wall's perl, version 5.
  262. */
  263. public static final RESyntax RE_SYNTAX_PERL5;
  264. /**
  265. * Predefined syntax.
  266. * Emulates regular expression support in Larry Wall's perl, version 5,
  267. * using single line mode (/s modifier).
  268. */
  269. public static final RESyntax RE_SYNTAX_PERL5_S;
  270. /**
  271. * Predefined syntax.
  272. * Emulates regular expression support in Java 1.4's java.util.regex
  273. * package.
  274. */
  275. public static final RESyntax RE_SYNTAX_JAVA_1_4;
  276. static {
  277. // Define syntaxes
  278. RE_SYNTAX_EMACS = new RESyntax().makeFinal();
  279. RESyntax RE_SYNTAX_POSIX_COMMON = new RESyntax()
  280. .set(RE_CHAR_CLASSES)
  281. .set(RE_DOT_NEWLINE)
  282. .set(RE_DOT_NOT_NULL)
  283. .set(RE_INTERVALS)
  284. .set(RE_NO_EMPTY_RANGES)
  285. .makeFinal();
  286. RE_SYNTAX_POSIX_BASIC = new RESyntax(RE_SYNTAX_POSIX_COMMON)
  287. .set(RE_BK_PLUS_QM)
  288. .makeFinal();
  289. RE_SYNTAX_POSIX_EXTENDED = new RESyntax(RE_SYNTAX_POSIX_COMMON)
  290. .set(RE_CONTEXT_INDEP_ANCHORS)
  291. .set(RE_CONTEXT_INDEP_OPS)
  292. .set(RE_NO_BK_BRACES)
  293. .set(RE_NO_BK_PARENS)
  294. .set(RE_NO_BK_VBAR)
  295. .set(RE_UNMATCHED_RIGHT_PAREN_ORD)
  296. .makeFinal();
  297. RE_SYNTAX_AWK = new RESyntax()
  298. .set(RE_BACKSLASH_ESCAPE_IN_LISTS)
  299. .set(RE_DOT_NOT_NULL)
  300. .set(RE_NO_BK_PARENS)
  301. .set(RE_NO_BK_REFS)
  302. .set(RE_NO_BK_VBAR)
  303. .set(RE_NO_EMPTY_RANGES)
  304. .set(RE_UNMATCHED_RIGHT_PAREN_ORD)
  305. .makeFinal();
  306. RE_SYNTAX_POSIX_AWK = new RESyntax(RE_SYNTAX_POSIX_EXTENDED)
  307. .set(RE_BACKSLASH_ESCAPE_IN_LISTS)
  308. .makeFinal();
  309. RE_SYNTAX_GREP = new RESyntax()
  310. .set(RE_BK_PLUS_QM)
  311. .set(RE_CHAR_CLASSES)
  312. .set(RE_HAT_LISTS_NOT_NEWLINE)
  313. .set(RE_INTERVALS)
  314. .set(RE_NEWLINE_ALT)
  315. .makeFinal();
  316. RE_SYNTAX_EGREP = new RESyntax()
  317. .set(RE_CHAR_CLASSES)
  318. .set(RE_CONTEXT_INDEP_ANCHORS)
  319. .set(RE_CONTEXT_INDEP_OPS)
  320. .set(RE_HAT_LISTS_NOT_NEWLINE)
  321. .set(RE_NEWLINE_ALT)
  322. .set(RE_NO_BK_PARENS)
  323. .set(RE_NO_BK_VBAR)
  324. .makeFinal();
  325. RE_SYNTAX_POSIX_EGREP = new RESyntax(RE_SYNTAX_EGREP)
  326. .set(RE_INTERVALS)
  327. .set(RE_NO_BK_BRACES)
  328. .makeFinal();
  329. /* P1003.2/D11.2, section 4.20.7.1, lines 5078ff. */
  330. RE_SYNTAX_ED = new RESyntax(RE_SYNTAX_POSIX_BASIC)
  331. .makeFinal();
  332. RE_SYNTAX_SED = new RESyntax(RE_SYNTAX_POSIX_BASIC)
  333. .makeFinal();
  334. RE_SYNTAX_POSIX_MINIMAL_BASIC = new RESyntax(RE_SYNTAX_POSIX_COMMON)
  335. .set(RE_LIMITED_OPS)
  336. .makeFinal();
  337. /* Differs from RE_SYNTAX_POSIX_EXTENDED in that RE_CONTEXT_INVALID_OPS
  338. replaces RE_CONTEXT_INDEP_OPS and RE_NO_BK_REFS is added. */
  339. RE_SYNTAX_POSIX_MINIMAL_EXTENDED = new RESyntax(RE_SYNTAX_POSIX_COMMON)
  340. .set(RE_CONTEXT_INDEP_ANCHORS)
  341. .set(RE_CONTEXT_INVALID_OPS)
  342. .set(RE_NO_BK_BRACES)
  343. .set(RE_NO_BK_PARENS)
  344. .set(RE_NO_BK_REFS)
  345. .set(RE_NO_BK_VBAR)
  346. .set(RE_UNMATCHED_RIGHT_PAREN_ORD)
  347. .makeFinal();
  348. /* There is no official Perl spec, but here's a "best guess" */
  349. RE_SYNTAX_PERL4 = new RESyntax()
  350. .set(RE_BACKSLASH_ESCAPE_IN_LISTS)
  351. .set(RE_CONTEXT_INDEP_ANCHORS)
  352. .set(RE_CONTEXT_INDEP_OPS) // except for '{', apparently
  353. .set(RE_INTERVALS)
  354. .set(RE_NO_BK_BRACES)
  355. .set(RE_NO_BK_PARENS)
  356. .set(RE_NO_BK_VBAR)
  357. .set(RE_NO_EMPTY_RANGES)
  358. .set(RE_CHAR_CLASS_ESCAPES) // \d,\D,\w,\W,\s,\S
  359. .makeFinal();
  360. RE_SYNTAX_PERL4_S = new RESyntax(RE_SYNTAX_PERL4)
  361. .set(RE_DOT_NEWLINE)
  362. .makeFinal();
  363. RE_SYNTAX_PERL5 = new RESyntax(RE_SYNTAX_PERL4)
  364. .set(RE_PURE_GROUPING) // (?:)
  365. .set(RE_STINGY_OPS) // *?,??,+?,{}?
  366. .set(RE_LOOKAHEAD) // (?=)(?!)
  367. .set(RE_STRING_ANCHORS) // \A,\Z
  368. .set(RE_CHAR_CLASS_ESC_IN_LISTS)// \d,\D,\w,\W,\s,\S within []
  369. .set(RE_COMMENTS) // (?#)
  370. .set(RE_EMBEDDED_FLAGS) // (?imsx-imsx)
  371. .set(RE_OCTAL_CHAR) // \0377
  372. .set(RE_HEX_CHAR) // \x1b
  373. .set(RE_NAMED_PROPERTY) // \p{prop}, \P{prop}
  374. .makeFinal();
  375. RE_SYNTAX_PERL5_S = new RESyntax(RE_SYNTAX_PERL5)
  376. .set(RE_DOT_NEWLINE)
  377. .makeFinal();
  378. RE_SYNTAX_JAVA_1_4 = new RESyntax(RE_SYNTAX_PERL5)
  379. // XXX
  380. .set(RE_POSSESSIVE_OPS) // *+,?+,++,{}+
  381. .set(RE_UNICODE_CHAR) // \u1234
  382. .set(RE_NESTED_CHARCLASS) // [a-z&&[^p-r]]
  383. .makeFinal();
  384. }
  385. /**
  386. * Construct a new syntax object with all bits turned off.
  387. * This is equivalent to RE_SYNTAX_EMACS.
  388. */
  389. public RESyntax() {
  390. bits = new BitSet(BIT_TOTAL);
  391. }
  392. /**
  393. * Called internally when constructing predefined syntaxes
  394. * so their interpretation cannot vary. Conceivably useful
  395. * for your syntaxes as well. Causes IllegalAccessError to
  396. * be thrown if any attempt to modify the syntax is made.
  397. *
  398. * @return this object for convenient chaining
  399. */
  400. public RESyntax makeFinal() {
  401. isFinal = true;
  402. return this;
  403. }
  404. /**
  405. * Construct a new syntax object with all bits set the same
  406. * as the other syntax.
  407. */
  408. public RESyntax(RESyntax other) {
  409. bits = (BitSet) other.bits.clone();
  410. }
  411. /**
  412. * Check if a given bit is set in this syntax.
  413. */
  414. public boolean get(int index) {
  415. return bits.get(index);
  416. }
  417. /**
  418. * Set a given bit in this syntax.
  419. *
  420. * @param index the constant (RESyntax.RE_xxx) bit to set.
  421. * @return a reference to this object for easy chaining.
  422. */
  423. public RESyntax set(int index) {
  424. if (isFinal) throw new IllegalAccessError(SYNTAX_IS_FINAL);
  425. bits.set(index);
  426. return this;
  427. }
  428. /**
  429. * Clear a given bit in this syntax.
  430. *
  431. * @param index the constant (RESyntax.RE_xxx) bit to clear.
  432. * @return a reference to this object for easy chaining.
  433. */
  434. public RESyntax clear(int index) {
  435. if (isFinal) throw new IllegalAccessError(SYNTAX_IS_FINAL);
  436. bits.clear(index);
  437. return this;
  438. }
  439. /**
  440. * Changes the line separator string for regular expressions
  441. * created using this RESyntax. The default separator is the
  442. * value returned by the system property "line.separator", which
  443. * should be correct when reading platform-specific files from a
  444. * filesystem. However, many programs may collect input from
  445. * sources where the line separator is differently specified (for
  446. * example, in the applet environment, the text box widget
  447. * interprets line breaks as single-character newlines,
  448. * regardless of the host platform.
  449. *
  450. * Note that setting the line separator to a character or
  451. * characters that have specific meaning within the current syntax
  452. * can cause unexpected chronosynclastic infundibula.
  453. *
  454. * @return this object for convenient chaining
  455. */
  456. public RESyntax setLineSeparator(String aSeparator) {
  457. if (isFinal) throw new IllegalAccessError(SYNTAX_IS_FINAL);
  458. lineSeparator = aSeparator;
  459. return this;
  460. }
  461. /**
  462. * Returns the currently active line separator string. The default
  463. * is the platform-dependent system property "line.separator".
  464. */
  465. public String getLineSeparator() {
  466. return lineSeparator;
  467. }
  468. }