summaryrefslogtreecommitdiffstats
path: root/predicate-search-core/src/main/antlr3/com/yahoo/document/predicate/parser/Predicate.g
diff options
context:
space:
mode:
Diffstat (limited to 'predicate-search-core/src/main/antlr3/com/yahoo/document/predicate/parser/Predicate.g')
-rw-r--r--predicate-search-core/src/main/antlr3/com/yahoo/document/predicate/parser/Predicate.g118
1 files changed, 118 insertions, 0 deletions
diff --git a/predicate-search-core/src/main/antlr3/com/yahoo/document/predicate/parser/Predicate.g b/predicate-search-core/src/main/antlr3/com/yahoo/document/predicate/parser/Predicate.g
new file mode 100644
index 00000000000..963d87c3218
--- /dev/null
+++ b/predicate-search-core/src/main/antlr3/com/yahoo/document/predicate/parser/Predicate.g
@@ -0,0 +1,118 @@
+grammar Predicate;
+
+@header {
+package com.yahoo.document.predicate.parser;
+
+import com.yahoo.document.predicate.Conjunction;
+import com.yahoo.document.predicate.Disjunction;
+import com.yahoo.document.predicate.FeatureRange;
+import com.yahoo.document.predicate.FeatureSet;
+import com.yahoo.document.predicate.Negation;
+import com.yahoo.document.predicate.Predicate;
+import com.yahoo.document.predicate.Predicates;
+}
+
+@lexer::header {
+package com.yahoo.document.predicate.parser;
+
+import com.yahoo.document.predicate.Predicate;
+}
+
+@members {
+ @Override
+ public void emitErrorMessage(String message) {
+ throw new IllegalArgumentException(message);
+ }
+}
+
+@lexer::members {
+ @Override
+ public void emitErrorMessage(String message) {
+ throw new IllegalArgumentException(message);
+ }
+}
+
+predicate returns [Predicate n]
+ : d=disjunction EOF { n = d; }
+ ;
+
+disjunction returns [Predicate n]
+ : c=conjunction { n = c; }
+ ( OR c2=conjunction { n = new Disjunction(n, c2); }
+ ( OR c3=conjunction { ((Disjunction)n).addOperand(c3); } )* )?
+ ;
+
+conjunction returns [Predicate n]
+ : u=unary_node { n = u; }
+ ( AND u2=unary_node { n = new Conjunction(n, u2); }
+ ( AND u3=unary_node { ((Conjunction)n).addOperand(u3); } )* )?
+ ;
+
+unary_node returns [Predicate n]
+ : l=leaf { n = l; }
+ | ( not=NOT )? '(' d=disjunction ')' { n = d; if (not != null) { n = new Negation(n); } }
+ ;
+
+leaf returns [Predicate n]
+ : k=value ( not=NOT )? IN
+ ( mv=multivalue[k] { n = mv; }
+ | r=range[k] { n = r; }
+ ) { if (not != null) { n = new Negation(n); } }
+ | TRUE { n = Predicates.value(true); }
+ | FALSE { n = Predicates.value(false); }
+ ;
+
+multivalue[String key] returns [FeatureSet n]
+ : '[' v1=value { n = new FeatureSet(key, v1); }
+ ( ',' v2=value { n.addValue(v2); })* ']'
+ ;
+
+value returns [String s]
+ : VALUE { s = $VALUE.text; }
+ | STRING { s = $STRING.text; }
+ | INTEGER { s = $INTEGER.text; }
+ | k=keyword { s = k; }
+ ;
+
+range[String key] returns [FeatureRange r]
+ : '[' { r = new FeatureRange(key); }
+ ( i1=INTEGER { r.setFromInclusive(Long.parseLong(i1.getText())); } )?
+ '..'
+ ( i2=INTEGER { r.setToInclusive(Long.parseLong(i2.getText())); } )?
+ ( '(' partition (',' partition)* ')' )?
+ ']'
+ ;
+
+partition
+ : value ('='|'=-') (INTEGER INTEGER /* second integer becomes negative */ | INTEGER '+[' INTEGER? '..' INTEGER? ']')
+ ;
+
+keyword returns [String s]
+ : OR { s = $OR.text; }
+ | AND { s = $AND.text; }
+ | NOT { s = $NOT.text; }
+ | IN { s = $IN.text; }
+ | TRUE { s = $TRUE.text; }
+ | FALSE { s = $FALSE.text; }
+ ;
+
+INTEGER : ( '-' | '+' )? ('1'..'9' ( '0'..'9' )* | '0') ;
+
+OR : 'OR' | 'or' ;
+AND : 'AND' | 'and' ;
+NOT : 'NOT' | 'not' ;
+IN : 'IN' | 'in' ;
+TRUE : 'TRUE' | 'true' ;
+FALSE : 'FALSE' | 'false' ;
+
+VALUE : ( 'a'..'z' | 'A'..'Z' | '0'..'9' | '_' )+ ;
+
+STRING
+ : ( '\'' ( ~('\'') | '\\\'' )* '\''
+ | '\"' ( ~('\"') | '\\\"' )* '\"' )
+ { setText(Predicate.asciiDecode(getText().substring(1, getText().length() - 1))); }
+ ;
+
+WS : (' ' | '\t')+
+ {$channel = HIDDEN;}
+ ;