001: /*
002: * Copyright 2004-2008 H2 Group. Licensed under the H2 License, Version 1.0
003: * (http://h2database.com/html/license.html).
004: * Initial Developer: H2 Group
005: */
006: package org.h2.bnf;
007:
008: import java.util.HashMap;
009: import java.util.Random;
010:
011: import org.h2.util.StringUtils;
012:
013: /**
014: * Represents a hard coded terminal rule in a BNF object.
015: */
016: public class RuleFixed implements Rule {
017: static final int YMD = 0, HMS = 1, NANOS = 2;
018: static final int ANY_EXCEPT_SINGLE_QUOTE = 3;
019: static final int ANY_EXCEPT_DOUBLE_QUOTE = 4;
020: static final int ANY_UNTIL_EOL = 5;
021: static final int ANY_UNTIL_END = 6;
022: static final int ANY_WORD = 7;
023: static final int HEX_START = 10, CONCAT = 11, AZ_UNDERLINE = 12,
024: AF = 13, DIGIT = 14;
025:
026: private final int type;
027:
028: RuleFixed(int type) {
029: this .type = type;
030: }
031:
032: public String random(Bnf config, int level) {
033: Random r = config.getRandom();
034: switch (type) {
035: case YMD:
036: return "" + (1800 + r.nextInt(200)) + "-"
037: + (1 + r.nextInt(12)) + "-" + (1 + r.nextInt(31));
038: case HMS:
039: return "" + (r.nextInt(24)) + "-" + (r.nextInt(60)) + "-"
040: + (r.nextInt(60));
041: case NANOS:
042: return "" + (r.nextInt(100000) + r.nextInt(10000));
043: case ANY_UNTIL_EOL:
044: case ANY_EXCEPT_SINGLE_QUOTE:
045: case ANY_EXCEPT_DOUBLE_QUOTE:
046: case ANY_WORD:
047: case ANY_UNTIL_END: {
048: StringBuffer buff = new StringBuffer();
049: int len = r.nextBoolean() ? 1 : r.nextInt(5);
050: for (int i = 0; i < len; i++) {
051: buff.append((char) ('A' + r.nextInt('C' - 'A')));
052: }
053: return buff.toString();
054: }
055: case HEX_START:
056: return "0x";
057: case CONCAT:
058: return "||";
059: case AZ_UNDERLINE:
060: return "" + (char) ('A' + r.nextInt('C' - 'A'));
061: case AF:
062: return "" + (char) ('A' + r.nextInt('F' - 'A'));
063: case DIGIT:
064: return "" + (char) ('0' + r.nextInt(10));
065: default:
066: throw new Error("type=" + type);
067: }
068: }
069:
070: public String name() {
071: return "type=" + type;
072: }
073:
074: public Rule last() {
075: return this ;
076: }
077:
078: public void setLinks(HashMap ruleMap) {
079: }
080:
081: public String matchRemove(String query, Sentence sentence) {
082: if (sentence.stop()) {
083: return null;
084: }
085: if (query.length() == 0) {
086: return null;
087: }
088: String s = query;
089: switch (type) {
090: case YMD:
091: while (s.length() > 0
092: && "0123456789- ".indexOf(s.charAt(0)) >= 0) {
093: s = s.substring(1);
094: }
095: break;
096: case HMS:
097: while (s.length() > 0
098: && "0123456789:. ".indexOf(s.charAt(0)) >= 0) {
099: s = s.substring(1);
100: }
101: break;
102: case NANOS:
103: while (s.length() > 0 && Character.isDigit(s.charAt(0))) {
104: s = s.substring(1);
105: }
106: break;
107: case ANY_WORD:
108: while (s.length() > 0
109: && Character.isWhitespace(s.charAt(0))) {
110: s = s.substring(1);
111: }
112: break;
113: case ANY_UNTIL_END:
114: while (s.length() > 1 && s.startsWith("*/")) {
115: s = s.substring(1);
116: }
117: break;
118: case ANY_UNTIL_EOL:
119: while (s.length() > 0 && s.charAt(0) != '\n') {
120: s = s.substring(1);
121: }
122: break;
123: case ANY_EXCEPT_SINGLE_QUOTE:
124: while (true) {
125: while (s.length() > 0 && s.charAt(0) != '\'') {
126: s = s.substring(1);
127: }
128: if (s.startsWith("''")) {
129: s = s.substring(2);
130: } else {
131: break;
132: }
133: }
134: break;
135: case ANY_EXCEPT_DOUBLE_QUOTE:
136: while (true) {
137: while (s.length() > 0 && s.charAt(0) != '\"') {
138: s = s.substring(1);
139: }
140: if (s.startsWith("\"\"")) {
141: s = s.substring(2);
142: } else {
143: break;
144: }
145: }
146: break;
147: case HEX_START:
148: if (StringUtils.toUpperEnglish(s).startsWith("0X")) {
149: s = s.substring(2);
150: } else if (StringUtils.toUpperEnglish(s).startsWith("0")) {
151: s = s.substring(1);
152: }
153: break;
154: case CONCAT:
155: if (s.startsWith("||")) {
156: s = s.substring(2);
157: } else if (s.startsWith("|")) {
158: s = s.substring(1);
159: }
160: break;
161: case AZ_UNDERLINE:
162: if (s.length() > 0
163: && (Character.isLetter(s.charAt(0)) || s.charAt(0) == '_')) {
164: s = s.substring(1);
165: }
166: break;
167: case AF:
168: if (s.length() > 0) {
169: char ch = Character.toUpperCase(s.charAt(0));
170: if (ch >= 'A' && ch <= 'F') {
171: s = s.substring(1);
172: }
173: }
174: break;
175: case DIGIT:
176: if (s.length() > 0 && Character.isDigit(s.charAt(0))) {
177: s = s.substring(1);
178: }
179: break;
180: default:
181: throw new Error("type=" + type);
182: }
183: if (s == query) {
184: return null;
185: }
186: return s;
187: }
188:
189: public void addNextTokenList(String query, Sentence sentence) {
190: if (sentence.stop()) {
191: return;
192: }
193: // String s = matchRemove(query, iteration);
194: switch (type) {
195: case YMD:
196: if (query.length() == 0) {
197: sentence.add("2006-01-01", "2006-01-01",
198: Sentence.KEYWORD);
199: }
200: break;
201: case HMS:
202: if (query.length() == 0) {
203: sentence.add("12:00:00", "12:00:00", Sentence.KEYWORD);
204: }
205: break;
206: case NANOS:
207: if (query.length() == 0) {
208: sentence.add("nanoseconds", "0", Sentence.KEYWORD);
209: }
210: break;
211: case ANY_EXCEPT_SINGLE_QUOTE:
212: if (query.length() == 0) {
213: sentence.add("anything", "Hello World",
214: Sentence.KEYWORD);
215: sentence.add("'", "'", Sentence.KEYWORD);
216: }
217: break;
218: case ANY_EXCEPT_DOUBLE_QUOTE:
219: if (query.length() == 0) {
220: sentence
221: .add("anything", "identifier", Sentence.KEYWORD);
222: }
223: break;
224: case ANY_WORD:
225: break;
226: case HEX_START:
227: if (query.length() == 0) {
228: sentence.add("0x", "0x", Sentence.KEYWORD);
229: } else if ("0".equals(query)) {
230: sentence.add("0x", "x", Sentence.KEYWORD);
231: }
232: break;
233: case CONCAT:
234: if (query.length() == 0) {
235: sentence.add("||", "||", Sentence.KEYWORD);
236: } else if ("|".equals(query)) {
237: sentence.add("||", "|", Sentence.KEYWORD);
238: }
239: break;
240: case AZ_UNDERLINE:
241: if (query.length() == 0) {
242: sentence.add("character", "A", Sentence.KEYWORD);
243: }
244: break;
245: case AF:
246: if (query.length() == 0) {
247: sentence.add("hex character", "0A", Sentence.KEYWORD);
248: }
249: break;
250: case DIGIT:
251: if (query.length() == 0) {
252: sentence.add("digit", "1", Sentence.KEYWORD);
253: }
254: break;
255: default:
256: throw new Error("type=" + type);
257: }
258: }
259:
260: }
|