1 package org.antlr.works.syntax; 2 3 import org.antlr.xjlib.foundation.XJUtils; 4 import org.antlr.works.ate.syntax.generic.ATESyntaxLexer; 5 import org.antlr.works.ate.syntax.generic.ATESyntaxParser; 6 import org.antlr.works.ate.syntax.misc.ATEToken; 7 import org.antlr.works.syntax.element.ElementReference; 8 import org.antlr.works.syntax.element.ElementRule; 9 10 import java.io.IOException ; 11 import java.util.*; 12 42 43 public class GrammarSyntax { 44 45 private List<ElementRule> duplicateRules = new ArrayList<ElementRule>(); 46 private List<ElementReference> undefinedReferences = new ArrayList<ElementReference>(); 47 private List<ElementRule> hasLeftRecursionRules = new ArrayList<ElementRule>(); 48 49 private Set<String > tokenVocabNames = new HashSet<String >(); 50 private String tokenVocabName; 51 52 private GrammarSyntaxDelegate delegate; 53 54 public GrammarSyntax(GrammarSyntaxDelegate delegate) { 55 this.delegate = delegate; 56 } 57 58 public GrammarSyntaxEngine getParserEngine() { 59 return delegate.getParserEngine(); 60 } 61 62 public int getNumberOfRulesWithErrors() { 63 int count = 0; 64 if(getParserEngine().getRules() != null) { 65 for (ElementRule rule : getParserEngine().getRules()) { 66 if (rule.hasErrors()) 67 count++; 68 } 69 } 70 return count; 71 } 72 73 public List<ElementRule> getDuplicateRules() { 74 return duplicateRules; 75 } 76 77 public List<ElementReference> getUndefinedReferences() { 78 return undefinedReferences; 79 } 80 81 public void resetTokenVocab() { 82 tokenVocabName = null; 83 tokenVocabNames.clear(); 84 } 85 86 public Set<String > getTokenVocabNames() { 87 String tokenVocab = getParserEngine().getTokenVocab(); 88 if(tokenVocab == null) { 89 tokenVocabNames.clear(); 90 return tokenVocabNames; 91 } 92 93 if(tokenVocabName != null && tokenVocabName.equals(tokenVocab)) 94 return tokenVocabNames; 95 96 tokenVocabName = tokenVocab; 97 tokenVocabNames.clear(); 98 99 try { 100 String file = delegate.getTokenVocabFile(tokenVocabName+".tokens"); 101 if(file != null) { 102 readTokenVocabFromFile(file, tokenVocabNames); 103 } 104 } catch (IOException e) { 105 e.printStackTrace(); 106 } 107 108 return tokenVocabNames; 109 } 110 111 public static boolean readTokenVocabFromFile(String filePath, Set<String > tokenNames) throws IOException { 112 List<ATEToken> tokens = parsePropertiesString(XJUtils.getStringFromFile(filePath)); 114 for (ATEToken t : tokens) { 116 tokenNames.add(t.getAttribute()); 117 } 118 119 return true; 120 } 121 122 private static List<ATEToken> parsePropertiesString(final String content) { 123 124 class ParseProperties extends ATESyntaxParser { 125 126 public List<ATEToken> propertiesTokens; 127 128 public void parseTokens() { 129 propertiesTokens = new ArrayList<ATEToken>(); 130 while(nextToken()) { 131 if(T(0).type == ATESyntaxLexer.TOKEN_ID) { 132 if(isChar(1, "=") || isChar(1, "\n")) 133 propertiesTokens.add(T(0)); 134 } 135 } 136 } 137 138 } 139 140 GrammarSyntaxLexer lexer = new GrammarSyntaxLexer(); 141 lexer.tokenize(content); 142 143 ParseProperties parser = new ParseProperties(); 144 parser.parse(lexer.getTokens()); 145 return parser.propertiesTokens; 146 } 147 148 public void rebuildHasLeftRecursionRulesList() { 149 if(getParserEngine().getRules() == null) 150 return; 151 152 hasLeftRecursionRules.clear(); 153 for (ElementRule r : getParserEngine().getRules()) { 154 if (r.hasLeftRecursion()) { 156 hasLeftRecursionRules.add(r); 157 } 158 } 159 } 160 161 public void rebuildDuplicateRulesList() { 162 List<ElementRule> rules = getParserEngine().getRules(); 163 if(rules == null) 164 return; 165 166 List<ElementRule> sortedRules = Collections.list(Collections.enumeration(rules)); 167 Collections.sort(sortedRules); 168 Iterator<ElementRule> iter = sortedRules.iterator(); 169 ElementRule currentRule = null; 170 duplicateRules.clear(); 171 while(iter.hasNext()) { 172 ElementRule nextRule = iter.next(); 173 if(currentRule != null && currentRule.name.equals(nextRule.name) && !duplicateRules.contains(currentRule)) { 174 duplicateRules.add(currentRule); 175 duplicateRules.add(nextRule); 176 } 177 currentRule = nextRule; 178 } 179 } 180 181 public void rebuildUndefinedReferencesList() { 182 List<String > existingReferences = getParserEngine().getRuleNames(); 183 existingReferences.addAll(getParserEngine().getDeclaredTokenNames()); 184 existingReferences.addAll(getParserEngine().getPredefinedReferences()); 185 186 Set<String > tokenVocabNames = getTokenVocabNames(); 187 existingReferences.addAll(tokenVocabNames); 188 delegate.getParser().resolveReferencesWithExternalNames(tokenVocabNames); 189 190 undefinedReferences.clear(); 191 List<ElementReference> references = getParserEngine().getReferences(); 192 if(references == null) 193 return; 194 195 for (ElementReference ref : references) { 196 if (!existingReferences.contains(ref.token.getAttribute())) 197 undefinedReferences.add(ref); 198 } 199 } 200 201 public void rebuildAll() { 202 rebuildDuplicateRulesList(); 203 rebuildUndefinedReferencesList(); 204 rebuildHasLeftRecursionRulesList(); 205 } 206 207 public void parserDidParse() { 208 rebuildAll(); 209 } 210 211 } 212 | Popular Tags |