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 | import org.h2.util.StringUtils; |
11 | |
12 | /** |
13 | * A single terminal rule in a BNF object. |
14 | */ |
15 | public class RuleElement implements Rule { |
16 | |
17 | private final boolean keyword; |
18 | private final String name; |
19 | private Rule link; |
20 | private final int type; |
21 | |
22 | public RuleElement(String name, String topic) { |
23 | this.name = name; |
24 | this.keyword = name.length() == 1 || |
25 | name.equals(StringUtils.toUpperEnglish(name)); |
26 | topic = StringUtils.toLowerEnglish(topic); |
27 | this.type = topic.startsWith("function") ? |
28 | Sentence.FUNCTION : Sentence.KEYWORD; |
29 | } |
30 | |
31 | @Override |
32 | public void accept(BnfVisitor visitor) { |
33 | visitor.visitRuleElement(keyword, name, link); |
34 | } |
35 | |
36 | @Override |
37 | public void setLinks(HashMap<String, RuleHead> ruleMap) { |
38 | if (link != null) { |
39 | link.setLinks(ruleMap); |
40 | } |
41 | if (keyword) { |
42 | return; |
43 | } |
44 | String test = Bnf.getRuleMapKey(name); |
45 | for (int i = 0; i < test.length(); i++) { |
46 | String t = test.substring(i); |
47 | RuleHead r = ruleMap.get(t); |
48 | if (r != null) { |
49 | link = r.getRule(); |
50 | return; |
51 | } |
52 | } |
53 | throw new AssertionError("Unknown " + name + "/" + test); |
54 | } |
55 | |
56 | @Override |
57 | public boolean autoComplete(Sentence sentence) { |
58 | sentence.stopIfRequired(); |
59 | if (keyword) { |
60 | String query = sentence.getQuery(); |
61 | String q = query.trim(); |
62 | String up = sentence.getQueryUpper().trim(); |
63 | if (up.startsWith(name)) { |
64 | query = query.substring(name.length()); |
65 | while (!"_".equals(name) && Bnf.startWithSpace(query)) { |
66 | query = query.substring(1); |
67 | } |
68 | sentence.setQuery(query); |
69 | return true; |
70 | } else if (q.length() == 0 || name.startsWith(up)) { |
71 | if (q.length() < name.length()) { |
72 | sentence.add(name, name.substring(q.length()), type); |
73 | } |
74 | } |
75 | return false; |
76 | } |
77 | return link.autoComplete(sentence); |
78 | } |
79 | |
80 | } |