Skip to content

Commit d5ab75f

Browse files
committed
Use Tries to match with the keywords
1 parent 900c5dd commit d5ab75f

File tree

2 files changed

+134
-43
lines changed

2 files changed

+134
-43
lines changed

jme3-glsl-highlighter/src/com/jme3/gde/glsl/highlighter/lexer/GlslKeywordLibrary.java

Lines changed: 43 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
*/
3232
package com.jme3.gde.glsl.highlighter.lexer;
3333

34+
import com.jme3.gde.glsl.highlighter.util.Trie;
3435
import java.util.ArrayList;
3536
import java.util.List;
3637

@@ -40,18 +41,20 @@
4041
*
4142
* @author grizeldi
4243
*/
43-
class GlslKeywordLibrary {
44-
44+
final class GlslKeywordLibrary {
45+
4546
public enum KeywordType {
4647
KEYWORD, BUILTIN_FUNCTION, BUILTIN_VARIABLE, BASIC_TYPE, UNFINISHED;
4748
}
48-
private static final List<String> keywords = new ArrayList<>(),
49-
builtinFunctions = new ArrayList<>(),
50-
builtinVariables = new ArrayList<>(),
51-
basicTypes = new ArrayList<>();
49+
50+
private static final Trie keywordsTrie = new Trie();
51+
private static final Trie builtinFunctionsTrie = new Trie();
52+
private static final Trie builtinVariablesTrie = new Trie();
53+
private static final Trie basicTypesTrie = new Trie();
5254

5355
static {
5456
//keywords
57+
List<String> keywords = new ArrayList<>();
5558
keywords.add("attribute");
5659
keywords.add("const");
5760
keywords.add("uniform");
@@ -93,6 +96,7 @@ public enum KeywordType {
9396
keywords.add("discard");
9497
keywords.add("return");
9598
//primitives and other types
99+
List<String> basicTypes = new ArrayList<>();
96100
basicTypes.add("float");
97101
basicTypes.add("double");
98102
basicTypes.add("int");
@@ -217,6 +221,7 @@ public enum KeywordType {
217221
basicTypes.add("struct");
218222
//builtin variables
219223
//compute shaders
224+
List<String> builtinVariables = new ArrayList<>();
220225
builtinVariables.add("gl_NumWorkGroups");
221226
builtinVariables.add("gl_WorkGroupSize");
222227
builtinVariables.add("gl_WorkGroupID");
@@ -291,6 +296,7 @@ public enum KeywordType {
291296
builtinVariables.add("g_LightColor");
292297
builtinVariables.add("g_AmbientLightColor");
293298
//builtin functions
299+
List<String> builtinFunctions = new ArrayList<>();
294300
builtinFunctions.add("radians");
295301
builtinFunctions.add("degrees");
296302
builtinFunctions.add("sin");
@@ -466,51 +472,45 @@ public enum KeywordType {
466472
builtinFunctions.add("memoryBarrierShared");
467473
builtinFunctions.add("memoryBarrierImage");
468474
builtinFunctions.add("groupMemoryBarrier");
475+
476+
// Create the search tries
477+
for(String keyword : keywords) {
478+
keywordsTrie.insert(keyword);
479+
}
480+
for(String keyword : builtinFunctions) {
481+
builtinFunctionsTrie.insert(keyword);
482+
}
483+
for(String keyword : builtinVariables) {
484+
builtinVariablesTrie.insert(keyword);
485+
}
486+
for(String keyword : basicTypes) {
487+
basicTypesTrie.insert(keyword);
488+
}
469489
}
470490

471491
public static KeywordType lookup(String s) {
472492
KeywordType returnType = null;
473-
for (String primitive : basicTypes) {
474-
if (primitive.startsWith(s)) {
475-
if (primitive.equals(s)) {
476-
returnType = KeywordType.BASIC_TYPE;
477-
break;
478-
} else {
479-
returnType = KeywordType.UNFINISHED;
480-
}
481-
}
493+
returnType = lookup(s, returnType, KeywordType.BASIC_TYPE, basicTypesTrie);
494+
returnType = lookup(s, returnType, KeywordType.BUILTIN_VARIABLE, builtinVariablesTrie);
495+
if (returnType == KeywordType.UNFINISHED || returnType == null) {
496+
returnType = lookup(s, returnType, KeywordType.BUILTIN_FUNCTION, builtinFunctionsTrie);
482497
}
483-
for (String var : builtinVariables) {
484-
if (var.startsWith(s)) {
485-
if (var.equals(s)) {
486-
returnType = KeywordType.BUILTIN_VARIABLE;
487-
break;
488-
} else {
489-
returnType = KeywordType.UNFINISHED;
490-
}
491-
}
498+
if (returnType == KeywordType.UNFINISHED || returnType == null) {
499+
returnType = lookup(s, returnType, KeywordType.KEYWORD, keywordsTrie);
492500
}
493-
for (String func : builtinFunctions) {
494-
if (func.startsWith(s) && (returnType == KeywordType.UNFINISHED || returnType == null)) {
495-
if (func.equals(s)) {
496-
returnType = KeywordType.BUILTIN_FUNCTION;
497-
break;
498-
} else {
499-
returnType = KeywordType.UNFINISHED;
500-
}
501-
}
501+
502+
return returnType;
503+
}
504+
505+
private static KeywordType lookup(String s, KeywordType currentType, KeywordType matchType, Trie searchTrie) {
506+
Trie.MatchType match = searchTrie.search(s);
507+
if (match == Trie.MatchType.FULL_MATCH) {
508+
return matchType;
502509
}
503-
for (String keyword : keywords) {
504-
if (keyword.startsWith(s) && (returnType == KeywordType.UNFINISHED || returnType == null)) {
505-
if (keyword.equals(s)) {
506-
returnType = KeywordType.KEYWORD;
507-
break;
508-
} else {
509-
returnType = KeywordType.UNFINISHED;
510-
}
511-
}
510+
if (match == Trie.MatchType.PARTIAL_MATCH) {
511+
return KeywordType.UNFINISHED;
512512
}
513513

514-
return returnType;
514+
return currentType;
515515
}
516516
}
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/*
2+
* Copyright (c) 2003-2024 jMonkeyEngine
3+
* All rights reserved.
4+
*
5+
* Redistribution and use in source and binary forms, with or without
6+
* modification, are permitted provided that the following conditions are
7+
* met:
8+
*
9+
* Redistributions of source code must retain the above copyright
10+
* notice, this list of conditions and the following disclaimer.
11+
*
12+
* * Redistributions in binary form must reproduce the above copyright
13+
* notice, this list of conditions and the following disclaimer in the
14+
* documentation and/or other materials provided with the distribution.
15+
*
16+
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
17+
* may be used to endorse or promote products derived from this software
18+
* without specific prior written permission.
19+
*
20+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21+
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22+
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23+
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24+
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25+
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26+
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27+
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28+
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29+
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31+
*/
32+
package com.jme3.gde.glsl.highlighter.util;
33+
34+
import java.util.HashMap;
35+
import java.util.Map;
36+
37+
/**
38+
* Simple and efficient text search
39+
*/
40+
public class Trie {
41+
42+
private static class TrieNode {
43+
44+
Map<Character, TrieNode> children = new HashMap<>();
45+
boolean isEndOfWord = false;
46+
}
47+
48+
public enum MatchType {
49+
NO_MATCH,
50+
PARTIAL_MATCH,
51+
FULL_MATCH
52+
}
53+
54+
private final TrieNode root;
55+
56+
public Trie() {
57+
root = new TrieNode();
58+
}
59+
60+
/**
61+
* Insert word to the Trie structure
62+
*
63+
* @param word word to insert
64+
*/
65+
public void insert(String word) {
66+
TrieNode current = root;
67+
for (char ch : word.toCharArray()) {
68+
current = current.children.computeIfAbsent(ch, c -> new TrieNode());
69+
}
70+
current.isEndOfWord = true;
71+
}
72+
73+
/**
74+
* Searches for the string
75+
*
76+
* @param word word to search for
77+
* @return match type
78+
*/
79+
public MatchType search(String word) {
80+
TrieNode current = root;
81+
for (char ch : word.toCharArray()) {
82+
if (!current.children.containsKey(ch)) {
83+
return MatchType.NO_MATCH;
84+
}
85+
current = current.children.get(ch);
86+
}
87+
88+
return current.isEndOfWord ? MatchType.FULL_MATCH : MatchType.PARTIAL_MATCH;
89+
}
90+
91+
}

0 commit comments

Comments
 (0)