diff options
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.g | 118 |
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;} + ; |