src/main/antlr3/au/id/djc/rdftemplate/selector/Selector.g (5712B) - raw
1 grammar Selector; 2 3 @parser::header { 4 package au.id.djc.rdftemplate.selector; 5 import java.util.Map; 6 } 7 8 @parser::members { 9 10 @Override 11 public void reportError(RecognitionException e) { 12 throw new InvalidSelectorSyntaxException(e); 13 } 14 15 private AdaptationFactory adaptationFactory; 16 private PredicateResolver predicateResolver; 17 private Map<String, String> namespacePrefixMap; 18 19 public void setAdaptationFactory(AdaptationFactory adaptationFactory) { 20 this.adaptationFactory = adaptationFactory; 21 } 22 23 public void setPredicateResolver(PredicateResolver predicateResolver) { 24 this.predicateResolver = predicateResolver; 25 } 26 27 public void setNamespacePrefixMap(Map<String, String> map) { 28 this.namespacePrefixMap = map; 29 } 30 31 private String ns(String prefix) { 32 String ns = namespacePrefixMap.get(prefix); 33 if (ns == null) 34 throw new InvalidSelectorSyntaxException("Unbound namespace prefix " + prefix); 35 return ns; 36 } 37 38 } 39 40 @lexer::header { 41 package au.id.djc.rdftemplate.selector; 42 } 43 44 @lexer::members { 45 @Override 46 public void reportError(RecognitionException e) { 47 throw new InvalidSelectorSyntaxException(e); 48 } 49 } 50 51 start : unionSelector ; 52 53 unionSelector returns [Selector<?> result] 54 @init { 55 List<Selector<?>> selectors = new ArrayList<Selector<?>>(); 56 } 57 : WHITESPACE* 58 s=selector { selectors.add(s); } 59 ( WHITESPACE* 60 '|' 61 WHITESPACE* 62 s=selector { selectors.add(s); } 63 )* 64 { 65 if (selectors.size() > 1) 66 result = new UnionSelector(selectors); 67 else 68 result = selectors.get(0); 69 } 70 ; 71 72 selector returns [Selector<?> result] 73 @init { 74 Adaptation<?> adaptation = null; 75 } 76 : ( ts=traversingSelector { result = ts; } 77 | { result = new NoopSelector(); } 78 ) 79 ( '#' 80 adaptationName=XMLTOKEN 81 { 82 adaptation = adaptationFactory.getByName($adaptationName.text); 83 } 84 ( '(' 85 ( startIndex=INTEGER { 86 adaptation.setArgs(new Object[] { Integer.parseInt($startIndex.text) }); 87 } 88 | sq=SINGLE_QUOTED { 89 adaptation.setArgs(new Object[] { $sq.text }); 90 } 91 ) 92 ')' 93 | 94 ) 95 { $result = new SelectorWithAdaptation(result, adaptation); } 96 | 97 ) 98 WHITESPACE* 99 ; 100 101 traversingSelector returns [TraversingSelector result] 102 @init { 103 result = new TraversingSelector(); 104 } 105 : t=traversal { $result.addTraversal(t); } 106 ( WHITESPACE* 107 '/' 108 WHITESPACE* 109 t=traversal { $result.addTraversal(t); } 110 ) * 111 ; 112 113 traversal returns [Traversal result] 114 @init { 115 result = new Traversal(); 116 } 117 : ( '!' { $result.setInverse(true); } 118 WHITESPACE* 119 | // optional 120 ) 121 nsprefix=XMLTOKEN { $result.setPropertyNamespace(ns($nsprefix.text)); } 122 ':' 123 localname=XMLTOKEN { $result.setPropertyLocalName($localname.text); } 124 ( '[' 125 WHITESPACE* 126 p=booleanPredicate { $result.setPredicate(p); } 127 WHITESPACE* 128 ']' 129 | // optional 130 ) 131 ( '(' 132 WHITESPACE* 133 so=sortOrder { $result.addSortOrderComparator(so); } 134 ( WHITESPACE* 135 ',' 136 WHITESPACE* 137 so=sortOrder { $result.addSortOrderComparator(so); } 138 )* 139 WHITESPACE* 140 ')' 141 | // optional 142 ) 143 ( '[' 144 WHITESPACE* 145 subscript=INTEGER { $result.setSubscript(Integer.parseInt($subscript.text)); } 146 WHITESPACE* 147 ']' 148 | // optional 149 ) 150 ; 151 152 sortOrder returns [SelectorComparator<? extends Comparable<?>> result] 153 @init { 154 result = new SelectorComparator(); 155 } 156 : ( '~' { $result.setReversed(true); } 157 WHITESPACE* 158 | // optional 159 ) 160 s=selector { $result.setSelector((Selector) s.withResultType(Comparable.class)); } 161 ; 162 163 booleanPredicate returns [Predicate result] 164 : ( p=predicate { result = p; } 165 | left=predicate 166 WHITESPACE+ 167 'and' 168 WHITESPACE+ 169 right=booleanPredicate 170 { result = new BooleanAndPredicate(left, right); } 171 ) 172 ; 173 174 predicate returns [Predicate result] 175 @init { 176 Class<? extends Predicate> predicateClass; 177 } 178 : predicateName=XMLTOKEN 179 { 180 predicateClass = predicateResolver.getByName($predicateName.text); 181 if (predicateClass == null) 182 throw new InvalidSelectorSyntaxException("No predicate named " + $predicateName.text); 183 } 184 WHITESPACE* 185 '=' 186 WHITESPACE* 187 ( sq=SINGLE_QUOTED { 188 try { 189 result = predicateClass.getConstructor(String.class).newInstance($sq.text); 190 } catch (Exception e) { 191 throw new InvalidSelectorSyntaxException(e); 192 } 193 } 194 | nsprefix=XMLTOKEN 195 ':' 196 localname=XMLTOKEN 197 { 198 try { 199 result = predicateClass.getConstructor(String.class, String.class).newInstance(ns($nsprefix.text), $localname.text); 200 } catch (Exception e) { 201 throw new InvalidSelectorSyntaxException(e); 202 } 203 } 204 ) 205 ; 206 207 XMLTOKEN : ('a'..'z'|'A'..'Z') ('a'..'z'|'A'..'Z'|'0'..'9'|'_'|'-')* ; 208 INTEGER : ('0'..'9')+ ; 209 SINGLE_QUOTED : '\'' ( options {greedy=false;} : . )* '\'' 210 { 211 // strip quotes 212 String txt = getText(); 213 setText(txt.substring(1, txt.length() -1)); 214 }; 215 WHITESPACE : (' '|'\n'|'\r'|'\t') ;