1 | /* |
2 | * Copyright 2004-2014 H2 Group. Multiple-Licensed under the MPL 2.0, |
3 | * and the EPL 1.0 (http://h2database.com/html/license.html). |
4 | * Initial Developer: H2 Group |
5 | */ |
6 | package org.h2.bnf; |
7 | |
8 | import java.util.HashMap; |
9 | |
10 | /** |
11 | * Represents a hard coded terminal rule in a BNF object. |
12 | */ |
13 | public class RuleFixed implements Rule { |
14 | |
15 | public static final int YMD = 0, HMS = 1, NANOS = 2; |
16 | public static final int ANY_EXCEPT_SINGLE_QUOTE = 3; |
17 | public static final int ANY_EXCEPT_DOUBLE_QUOTE = 4; |
18 | public static final int ANY_UNTIL_EOL = 5; |
19 | public static final int ANY_UNTIL_END = 6; |
20 | public static final int ANY_WORD = 7; |
21 | public static final int ANY_EXCEPT_2_DOLLAR = 8; |
22 | public static final int HEX_START = 10, CONCAT = 11; |
23 | public static final int AZ_UNDERSCORE = 12, AF = 13, DIGIT = 14; |
24 | public static final int OPEN_BRACKET = 15, CLOSE_BRACKET = 16; |
25 | |
26 | private final int type; |
27 | |
28 | RuleFixed(int type) { |
29 | this.type = type; |
30 | } |
31 | |
32 | @Override |
33 | public void accept(BnfVisitor visitor) { |
34 | visitor.visitRuleFixed(type); |
35 | } |
36 | |
37 | @Override |
38 | public void setLinks(HashMap<String, RuleHead> ruleMap) { |
39 | // nothing to do |
40 | } |
41 | |
42 | @Override |
43 | public boolean autoComplete(Sentence sentence) { |
44 | sentence.stopIfRequired(); |
45 | String query = sentence.getQuery(); |
46 | String s = query; |
47 | switch(type) { |
48 | case YMD: |
49 | while (s.length() > 0 && "0123456789-".indexOf(s.charAt(0)) >= 0) { |
50 | s = s.substring(1); |
51 | } |
52 | if (s.length() == 0) { |
53 | sentence.add("2006-01-01", "1", Sentence.KEYWORD); |
54 | } |
55 | break; |
56 | case HMS: |
57 | while (s.length() > 0 && "0123456789:".indexOf(s.charAt(0)) >= 0) { |
58 | s = s.substring(1); |
59 | } |
60 | if (s.length() == 0) { |
61 | sentence.add("12:00:00", "1", Sentence.KEYWORD); |
62 | } |
63 | break; |
64 | case NANOS: |
65 | while (s.length() > 0 && Character.isDigit(s.charAt(0))) { |
66 | s = s.substring(1); |
67 | } |
68 | if (s.length() == 0) { |
69 | sentence.add("nanoseconds", "0", Sentence.KEYWORD); |
70 | } |
71 | break; |
72 | case ANY_EXCEPT_SINGLE_QUOTE: |
73 | while (true) { |
74 | while (s.length() > 0 && s.charAt(0) != '\'') { |
75 | s = s.substring(1); |
76 | } |
77 | if (s.startsWith("''")) { |
78 | s = s.substring(2); |
79 | } else { |
80 | break; |
81 | } |
82 | } |
83 | if (s.length() == 0) { |
84 | sentence.add("anything", "Hello World", Sentence.KEYWORD); |
85 | sentence.add("'", "'", Sentence.KEYWORD); |
86 | } |
87 | break; |
88 | case ANY_EXCEPT_2_DOLLAR: |
89 | while (s.length() > 0 && !s.startsWith("$$")) { |
90 | s = s.substring(1); |
91 | } |
92 | if (s.length() == 0) { |
93 | sentence.add("anything", "Hello World", Sentence.KEYWORD); |
94 | sentence.add("$$", "$$", Sentence.KEYWORD); |
95 | } |
96 | break; |
97 | case ANY_EXCEPT_DOUBLE_QUOTE: |
98 | while (true) { |
99 | while (s.length() > 0 && s.charAt(0) != '\"') { |
100 | s = s.substring(1); |
101 | } |
102 | if (s.startsWith("\"\"")) { |
103 | s = s.substring(2); |
104 | } else { |
105 | break; |
106 | } |
107 | } |
108 | if (s.length() == 0) { |
109 | sentence.add("anything", "identifier", Sentence.KEYWORD); |
110 | sentence.add("\"", "\"", Sentence.KEYWORD); |
111 | } |
112 | break; |
113 | case ANY_WORD: |
114 | while (s.length() > 0 && !Bnf.startWithSpace(s)) { |
115 | s = s.substring(1); |
116 | } |
117 | if (s.length() == 0) { |
118 | sentence.add("anything", "anything", Sentence.KEYWORD); |
119 | } |
120 | break; |
121 | case HEX_START: |
122 | if (s.startsWith("0X") || s.startsWith("0x")) { |
123 | s = s.substring(2); |
124 | } else if ("0".equals(s)) { |
125 | sentence.add("0x", "x", Sentence.KEYWORD); |
126 | } else if (s.length() == 0) { |
127 | sentence.add("0x", "0x", Sentence.KEYWORD); |
128 | } |
129 | break; |
130 | case CONCAT: |
131 | if (s.equals("|")) { |
132 | sentence.add("||", "|", Sentence.KEYWORD); |
133 | } else if (s.startsWith("||")) { |
134 | s = s.substring(2); |
135 | } else if (s.length() == 0) { |
136 | sentence.add("||", "||", Sentence.KEYWORD); |
137 | } |
138 | break; |
139 | case AZ_UNDERSCORE: |
140 | if (s.length() > 0 && |
141 | (Character.isLetter(s.charAt(0)) || s.charAt(0) == '_')) { |
142 | s = s.substring(1); |
143 | } |
144 | if (s.length() == 0) { |
145 | sentence.add("character", "A", Sentence.KEYWORD); |
146 | } |
147 | break; |
148 | case AF: |
149 | if (s.length() > 0) { |
150 | char ch = Character.toUpperCase(s.charAt(0)); |
151 | if (ch >= 'A' && ch <= 'F') { |
152 | s = s.substring(1); |
153 | } |
154 | } |
155 | if (s.length() == 0) { |
156 | sentence.add("hex character", "0A", Sentence.KEYWORD); |
157 | } |
158 | break; |
159 | case DIGIT: |
160 | if (s.length() > 0 && Character.isDigit(s.charAt(0))) { |
161 | s = s.substring(1); |
162 | } |
163 | if (s.length() == 0) { |
164 | sentence.add("digit", "1", Sentence.KEYWORD); |
165 | } |
166 | break; |
167 | case OPEN_BRACKET: |
168 | if (s.length() == 0) { |
169 | sentence.add("[", "[", Sentence.KEYWORD); |
170 | } else if (s.charAt(0) == '[') { |
171 | s = s.substring(1); |
172 | } |
173 | break; |
174 | case CLOSE_BRACKET: |
175 | if (s.length() == 0) { |
176 | sentence.add("]", "]", Sentence.KEYWORD); |
177 | } else if (s.charAt(0) == ']') { |
178 | s = s.substring(1); |
179 | } |
180 | break; |
181 | // no autocomplete support for comments |
182 | // (comments are not reachable in the bnf tree) |
183 | case ANY_UNTIL_EOL: |
184 | case ANY_UNTIL_END: |
185 | default: |
186 | throw new AssertionError("type="+type); |
187 | } |
188 | if (!s.equals(query)) { |
189 | while (Bnf.startWithSpace(s)) { |
190 | s = s.substring(1); |
191 | } |
192 | sentence.setQuery(s); |
193 | return true; |
194 | } |
195 | return false; |
196 | } |
197 | |
198 | } |