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:
010: import org.h2.util.StringUtils;
011:
012: /**
013: * A single terminal rule in a BNF object.
014: */
015: public class RuleElement implements Rule {
016:
017: private boolean keyword;
018: private String name;
019: private Rule link;
020: private int type;
021: private String topic;
022:
023: RuleElement(String name, String topic) {
024: this .name = name;
025: this .topic = topic;
026: if (name.length() == 1
027: || name.equals(StringUtils.toUpperEnglish(name))) {
028: keyword = true;
029: }
030: topic = StringUtils.toLowerEnglish(topic);
031: this .type = topic.startsWith("function") ? Sentence.FUNCTION
032: : Sentence.KEYWORD;
033: }
034:
035: RuleElement merge(RuleElement rule) {
036: return new RuleElement(name + " " + rule.name, topic);
037: }
038:
039: public String random(Bnf config, int level) {
040: if (keyword) {
041: return name.length() > 1 ? " " + name + " " : name;
042: }
043: if (link != null) {
044: return link.random(config, level + 1);
045: }
046: throw new Error(">>>" + name + "<<<");
047: }
048:
049: public String name() {
050: return name;
051: }
052:
053: public Rule last() {
054: return this ;
055: }
056:
057: public void setLinks(HashMap ruleMap) {
058: if (link != null) {
059: link.setLinks(ruleMap);
060: }
061: if (keyword) {
062: return;
063: }
064: for (int i = 0; i < name.length() && link == null; i++) {
065: String test = StringUtils.toLowerEnglish(name.substring(i));
066: RuleHead r = (RuleHead) ruleMap.get(test);
067: if (r != null) {
068: link = r.getRule();
069: return;
070: }
071: }
072: if (link == null) {
073: throw new Error(">>>" + name + "<<<");
074: }
075: }
076:
077: public String matchRemove(String query, Sentence sentence) {
078: if (sentence.stop()) {
079: return null;
080: }
081: if (query.length() == 0) {
082: return null;
083: }
084: if (keyword) {
085: String up = StringUtils.toUpperEnglish(query);
086: if (up.startsWith(name)) {
087: query = query.substring(name.length());
088: while (!"_".equals(name) && query.length() > 0
089: && Character.isWhitespace(query.charAt(0))) {
090: query = query.substring(1);
091: }
092: return query;
093: }
094: return null;
095: } else {
096: query = link.matchRemove(query, sentence);
097: if (query != null
098: && name != null
099: && !name.startsWith("@")
100: && (link.name() == null || !link.name().startsWith(
101: "@"))) {
102: while (query.length() > 0
103: && Character.isWhitespace(query.charAt(0))) {
104: query = query.substring(1);
105: }
106: }
107: return query;
108: }
109: }
110:
111: public void addNextTokenList(String query, Sentence sentence) {
112: if (sentence.stop()) {
113: return;
114: }
115: if (keyword) {
116: String q = query.trim();
117: String up = StringUtils.toUpperEnglish(q);
118: if (q.length() == 0 || name.startsWith(up)) {
119: if (q.length() < name.length()) {
120: sentence
121: .add(name, name.substring(q.length()), type);
122: }
123: }
124: return;
125: }
126: link.addNextTokenList(query, sentence);
127: }
128:
129: boolean isKeyword() {
130: return keyword;
131: }
132:
133: }
|