diff options
author | Jon Bratseth <bratseth@yahoo-inc.com> | 2016-06-15 23:09:44 +0200 |
---|---|---|
committer | Jon Bratseth <bratseth@yahoo-inc.com> | 2016-06-15 23:09:44 +0200 |
commit | 72231250ed81e10d66bfe70701e64fa5fe50f712 (patch) | |
tree | 2728bba1131a6f6e5bdf95afec7d7ff9358dac50 /container-search/src/main/javacc |
Publish
Diffstat (limited to 'container-search/src/main/javacc')
3 files changed, 2002 insertions, 0 deletions
diff --git a/container-search/src/main/javacc/com/yahoo/prelude/semantics/parser/SemanticsParser.jj b/container-search/src/main/javacc/com/yahoo/prelude/semantics/parser/SemanticsParser.jj new file mode 100644 index 00000000000..82c95578147 --- /dev/null +++ b/container-search/src/main/javacc/com/yahoo/prelude/semantics/parser/SemanticsParser.jj @@ -0,0 +1,649 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +/** + * @author bratseth + */ +options { + CACHE_TOKENS = true; + DEBUG_PARSER = false; + ERROR_REPORTING = true; + STATIC = false; + UNICODE_INPUT = true; +} + +PARSER_BEGIN(SemanticsParser) + +package com.yahoo.prelude.semantics.parser; + +import com.yahoo.javacc.UnicodeUtilities; +import com.yahoo.prelude.semantics.*; +import com.yahoo.prelude.semantics.rule.*; +import com.yahoo.prelude.query.TermType; + +public class SemanticsParser { + +} + +PARSER_END(SemanticsParser) + +SKIP : +{ + " " | "\f" | "\r" | "\t" +} + +SPECIAL_TOKEN : +{ + <SINGLE_LINE_COMMENT: "#" (~["\n","\r"])* ("\n"|"\r"|"\r\n")? > +} + +TOKEN : +{ + <NUMBER: <DECIMAL> (["l","L"])? | <HEX> (["l","L"])? | <OCTAL> (["l","L"])?> | + <#DECIMAL: ["1"-"9"] (["0"-"9"])*> | + <#HEX: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+> | + <#OCTAL: "0" (["0"-"7"])*> +} + +TOKEN : +{ + <AUTOMATADIRECTIVE: "@automata"> | + <COLON: ":"> | + <COMMA: ","> | + <CONDITION: ":-"> | + <CONTAINS: "=~"> | + <DASH: "-"> | + <DEFAULTDIRECTIVE: "@default"> | + <DIFFERENT: "!="> | + <DOLLAR: "$"> | + <DOT: "."> | + <ELLIPSIS: "..."> | + <EQUALS: "="> | + <EXCLAMATION: "!"> | + <INCLUDEDIRECTIVE: "@include"> | + <LARGER: ">"> | + <LARGEREQUALS: ">="> | + <LEFTBRACE: "("> | + <LEFTSQUAREBRACKET: "["> | + <LITERAL: "'" (~["'"] | "\\'")* "'"> | + <NL: "\n"> | + <PLUS: "+"> | + <PRODUCE: "+>"> | + <QUESTION: "?"> | + <QUOTE: "\""> | + <REPLACE: "->"> | + <RIGHTBRACE: ")"> | + <RIGHTSQUAREBRACKET: "]"> | + <SEMICOLON: ";"> | + <SLASH: "/"> | + <SMALLER: "<"> | + <SMALLEREQUALS: "<="> | + <STEMMINGDIRECTIVE: "@stemming"> | + <SUPERDIRECTIVE: "@super"> | + <IDENTIFIER: (~[ +"\u0000"-"\u002f","\u003a"-"\u003f","\u005b"-"\u005d","\u007b"-"\u00a7","\u00a9","\u00ab"-"\u00ae","\u00b0"-"\u00b3","\u00b6"-"\u00b7","\u00b9","\u00bb"-"\u00bf", +"\u00d7","\u00f7","\u037e","\u0387","\u03f6","\u0482","\u055a"-"\u055f","\u0589"-"\u058a","\u05be","\u05c0","\u05c3","\u05c6","\u05f3"-"\u05f4","\u0600"-"\u0603", +"\u0606"-"\u060f","\u061b","\u061e"-"\u061f","\u066a"-"\u066d","\u06d4","\u06dd"-"\u06de","\u06e9","\u06fd"-"\u06fe","\u0700"-"\u070d","\u070f","\u07f6"-"\u07f9", +"\u0830"-"\u083e","\u085e","\u0964"-"\u0965","\u0970","\u09f2"-"\u09fb","\u0af1","\u0b70","\u0b72"-"\u0b77","\u0bf0"-"\u0bfa","\u0c78"-"\u0c7f","\u0d70"-"\u0d75", +"\u0d79","\u0df4","\u0e3f","\u0e4f","\u0e5a"-"\u0e5b","\u0f01"-"\u0f17","\u0f1a"-"\u0f1f","\u0f2a"-"\u0f34","\u0f36","\u0f38","\u0f3a"-"\u0f3d","\u0f85", +"\u0fbe"-"\u0fc5","\u0fc7"-"\u0fcc","\u0fce"-"\u0fda","\u104a"-"\u104f","\u109e"-"\u109f","\u10fb","\u1360"-"\u137c","\u1390"-"\u1399","\u1400","\u166d"-"\u166e", +"\u1680","\u169b"-"\u169c","\u16eb"-"\u16f0","\u1735"-"\u1736","\u17b4"-"\u17b5","\u17d4"-"\u17d6","\u17d8"-"\u17db","\u17f0"-"\u17f9","\u1800"-"\u180a", +"\u180e","\u1940","\u1944"-"\u1945","\u19da","\u19de"-"\u19ff","\u1a1e"-"\u1a1f","\u1aa0"-"\u1aa6","\u1aa8"-"\u1aad","\u1b5a"-"\u1b6a","\u1b74"-"\u1b7c", +"\u1bfc"-"\u1bff","\u1c3b"-"\u1c3f","\u1c7e"-"\u1c7f","\u1cd3","\u2000"-"\u2064","\u206a"-"\u2070","\u2074"-"\u207e","\u2080"-"\u208e","\u20a0"-"\u20b9", +"\u2100"-"\u2101","\u2103"-"\u2106","\u2108"-"\u2109","\u2114","\u2116"-"\u2118","\u211e"-"\u2123","\u2125","\u2127","\u2129","\u212e","\u213a"-"\u213b", +"\u2140"-"\u2144","\u214a"-"\u214d","\u214f"-"\u2182","\u2185"-"\u2189","\u2190"-"\u23f3","\u2400"-"\u2426","\u2440"-"\u244a","\u2460"-"\u26ff","\u2701"-"\u27ca", +"\u27cc","\u27ce"-"\u2b4c","\u2b50"-"\u2b59","\u2ce5"-"\u2cea","\u2cf9"-"\u2cff","\u2d70","\u2e00"-"\u2e2e","\u2e30"-"\u2e31","\u2e80"-"\u2e99","\u2e9b"-"\u2ef3", +"\u2f00"-"\u2fd5","\u2ff0"-"\u2ffb","\u3000"-"\u3004","\u3007"-"\u3029","\u3030","\u3036"-"\u303a","\u303d"-"\u303f","\u30a0","\u30fb","\u3190"-"\u319f", +"\u31c0"-"\u31e3","\u3200"-"\u321e","\u3220"-"\u32fe","\u3300"-"\u33ff","\u4dc0"-"\u4dff","\ua490"-"\ua4c6","\ua4fe"-"\ua4ff","\ua60d"-"\ua60f","\ua673", +"\ua67e","\ua6e6"-"\ua6ef","\ua6f2"-"\ua6f7","\ua828"-"\ua82b","\ua830"-"\ua839","\ua874"-"\ua877","\ua8ce"-"\ua8cf","\ua8f8"-"\ua8fa","\ua92e"-"\ua92f", +"\ua95f","\ua9c1"-"\ua9cd","\ua9de"-"\ua9df","\uaa5c"-"\uaa5f","\uaa77"-"\uaa79","\uaade"-"\uaadf","\uabeb","\ue000"-"\uf8ff","\ufb29","\ufd3e"-"\ufd3f", +"\ufdfc"-"\ufdfd","\ufe10"-"\ufe19","\ufe30"-"\ufe52","\ufe54"-"\ufe66","\ufe68"-"\ufe6b","\ufeff","\uff01"-"\uff0f","\uff1a"-"\uff20","\uff3b"-"\uff3d", +"\uff3f","\uff5b"-"\uff65","\uffe0"-"\uffe2","\uffe4"-"\uffe6","\uffe8"-"\uffee","\ufff9"-"\ufffd" + ])+> +} + +/** Parses a search definition and returns the resulting object */ +RuleBase semanticRules(RuleBase rules,RuleImporter importer) : +{ +} +{ + ( LOOKAHEAD(2) <NL> | + directive(rules,importer) | + LOOKAHEAD(4) namedCondition(rules) | + productionRule(rules) ) * + { return rules; } +} + +// ---------------------------------- Directive --------------------------------------- + +RuleBase directive(RuleBase rules,RuleImporter importer) : +{ + String name; +} +{ + ( includeDirective(rules,importer) | defaultDirective(rules) | automataDirective(rules,importer) | stemmingDirective(rules) ) + { return rules; } +} + +void includeDirective(RuleBase rules,RuleImporter importer) : +{ + String name; +} +{ + <INCLUDEDIRECTIVE> <LEFTBRACE> name=stringOrLiteral() <RIGHTBRACE> (<SEMICOLON>)? + { + try { + importer.include(name,rules); + } + catch (java.io.IOException e) { + ParseException ep=new ParseException("Could not read included rule base '" + + name + "'"); + ep.initCause(e); + throw ep; + } + } +} + +void automataDirective(RuleBase rules,RuleImporter importer) : +{ + String name; +} +{ + <AUTOMATADIRECTIVE> <LEFTBRACE> name=stringOrLiteral() <RIGHTBRACE> (<SEMICOLON>)? + { + importer.setAutomata(rules,name); + } +} + +void defaultDirective(RuleBase rules) : +{ +} +{ + <DEFAULTDIRECTIVE> (<SEMICOLON>)? + { + rules.setDefault(true); + } +} + +void stemmingDirective(RuleBase rules) : +{ + String booleanString; +} +{ + <STEMMINGDIRECTIVE> <LEFTBRACE> booleanString=stringOrLiteral() <RIGHTBRACE> (<SEMICOLON>)? + { + rules.setStemming(Boolean.parseBoolean(booleanString)); + } +} + +// ---------------------------------- Production rules -------------------------------- + +void productionRule(RuleBase rules) : +{ + ProductionRule rule; + Condition condition; + ProductionList production=null; +} +{ + condition=topLevelCondition() rule=productionRuleType() ( production=productionList() )? <SEMICOLON> + { + rule.setCondition(condition); + if (production!=null) rule.setProduction(production); + rules.addRule(rule); + } +} + +ProductionRule productionRuleType() : +{ +} +{ + ( <REPLACE> { return new ReplacingProductionRule(); } ) | + ( <PRODUCE> { return new AddingProductionRule(); } ) +} + +ProductionList productionList() : +{ + ProductionList productionList=new ProductionList(); + Production production; + int weight=100; +} +{ + ( production=production() (<EXCLAMATION> weight=number())? + { + production.setWeight(weight); + productionList.addProduction(production); + weight=100; + } (<NL>)* + ) + + { return productionList; } +} + +Production production() : +{ + Production production; +} +{ + ( LOOKAHEAD(2) production=namespaceProduction() | production=termProduction() ) + { return production; } +} + +TermProduction termProduction() : +{ + TermProduction termProduction; + TermType termType; + String label=null; +} +{ + termType=termType() + ( LOOKAHEAD(2) label=label() )? + ( termProduction=nonphraseTermProduction() | termProduction=phraseProduction() ) + + { + termProduction.setLabel(label); + termProduction.setTermType(termType); + return termProduction; + } +} + +TermProduction nonphraseTermProduction() : +{ + TermProduction termProduction; +} +{ + ( termProduction=referenceTermProduction() | + termProduction=literalTermProduction() ) + { + return termProduction; + } +} + +LiteralPhraseProduction phraseProduction() : +{ + LiteralPhraseProduction phraseProduction=new LiteralPhraseProduction(); + String term=null; +} +{ + + <QUOTE> + ( + term=identifier() + { phraseProduction.addTerm(term); } + )+ + <QUOTE> + + { return phraseProduction; } + +} + +NamespaceProduction namespaceProduction() : +{ + String namespace; + String key; + String value=null; +} +{ + namespace=identifier() <DOT> key=stringOrLiteral() <EQUALS> value=identifierOrLiteral() + { return new NamespaceProduction(namespace,key,value); } +} + +ReferenceTermProduction referenceTermProduction() : +{ + String reference; +} +{ + <LEFTSQUAREBRACKET> reference=referenceIdentifier() <RIGHTSQUAREBRACKET> + { return new ReferenceTermProduction(reference); } +} + +LiteralTermProduction literalTermProduction() : +{ + String literal; +} +{ + literal=identifier() + { return new LiteralTermProduction(literal); } +} + +TermType termType() : +{ +} +{ + <QUESTION> { return TermType.OR; } | + <DOLLAR> { return TermType.RANK; } | + <PLUS> { return TermType.AND; } | + <DASH> { return TermType.NOT; } | + { return TermType.DEFAULT; } +} + +String referenceIdentifier() : +{ + String reference; +} +{ + ( reference=identifier() { return reference; } ) + | + ( <ELLIPSIS> { return "..."; } ) +} + +// ---------------------------------- Conditions ------------------------------------- + +void namedCondition(RuleBase rules) : +{ + String conditionName; + Condition condition; +} +{ + <LEFTSQUAREBRACKET> conditionName=identifier() <RIGHTSQUAREBRACKET> <CONDITION> condition=topLevelCondition() <SEMICOLON> + { rules.addCondition(new NamedCondition(conditionName,condition)); } +} + +Condition topLevelCondition() : +{ + Condition condition; + boolean startAnchor=false; + boolean endAnchor=false; +} +{ + ( <DOT> { startAnchor=true; } )? + ( + LOOKAHEAD(3) condition=choiceCondition() | + LOOKAHEAD(3) condition=sequenceCondition() + ) + ( LOOKAHEAD(2) <DOT> { endAnchor=true; } )? + { + condition.setAnchor(Condition.Anchor.create(startAnchor,endAnchor)); + return condition; + } +} + +Condition condition() : +{ + Condition condition; +} +{ + ( + ( LOOKAHEAD(3) condition=choiceCondition() + | condition=terminalCondition() ) + { + return condition; + } + ) +} + +Condition terminalOrSequenceCondition() : +{ + Condition condition; +} +{ + ( LOOKAHEAD(3) condition=sequenceCondition() | + condition=terminalCondition() ) + { return condition; } +} + +Condition terminalCondition() : +{ + Condition condition; +} +{ + ( condition=notCondition() | condition=terminalOrComparisonCondition() ) + { return condition; } +} + +Condition terminalOrComparisonCondition() : +{ + Condition condition,rightCondition; + String comparison; +} +{ + condition=reallyTerminalCondition() + ( comparison=comparison() ( LOOKAHEAD(2) rightCondition=nestedCondition() | rightCondition=reallyTerminalCondition() ) +// ( comparison=comparison() rightCondition=condition() + { condition=new ComparisonCondition(condition,comparison,rightCondition); } + ) ? + { return condition; } + +} + +Condition reallyTerminalCondition() : +{ + String label=null; + String context=null; + String nameSpace=null; + Condition condition=null; +} +{ +// This body looks like this to distinguish these two cases +// namespace.condition +// condition . (end anchor) + ( LOOKAHEAD(8) + ( + ( LOOKAHEAD(2) context=context() )? + ( nameSpace=nameSpace() ) + ( LOOKAHEAD(2) label=label() )? + condition=terminalConditionBody() + ) + | + ( + ( LOOKAHEAD(2) context=context() )? + ( LOOKAHEAD(2) label=label() )? + condition=terminalConditionBody() + ) + ) + { + if (context!=null) + condition.setContextName(context); + condition.setLabel(label); + condition.setNameSpace(nameSpace); + return condition; + } +} + + +Condition terminalConditionBody() : +{ + Condition condition=null; +} +{ + ( + LOOKAHEAD(2) condition=conditionReference() | + condition=termCondition() | + condition=nestedCondition() | + condition=nonReferableEllipsisCondition() | + condition=referableEllipsisCondition() | + condition=superCondition() | + condition=literalCondition() | + condition=compositeItemCondition()) + { return condition; } +} + +Condition notCondition() : +{ + Condition condition; +} +{ + <EXCLAMATION> condition=terminalOrComparisonCondition() + { return new NotCondition(condition); } +} + + +ConditionReference conditionReference() : +{ + String conditionName; +} +{ + <LEFTSQUAREBRACKET> conditionName=identifier() <RIGHTSQUAREBRACKET> + { return new ConditionReference(conditionName); } +} + +EllipsisCondition nonReferableEllipsisCondition() : +{ +} +{ + <ELLIPSIS> { return new EllipsisCondition(false); } +} + +EllipsisCondition referableEllipsisCondition() : +{ +} +{ + <LEFTSQUAREBRACKET> <ELLIPSIS> <RIGHTSQUAREBRACKET> + { return new EllipsisCondition(); } +} + +Condition nestedCondition() : +{ + Condition condition; +} +{ + <LEFTBRACE> condition=choiceCondition() <RIGHTBRACE> + { return condition; } +} + +Condition sequenceCondition() : +{ + SequenceCondition sequenceCondition=new SequenceCondition(); + Condition condition; +} +{ + condition=terminalCondition() + { sequenceCondition.addCondition(condition); } + ( LOOKAHEAD(2) condition=terminalCondition() + { sequenceCondition.addCondition(condition); } + )* + { + if (sequenceCondition.conditionSize()==1) + return sequenceCondition.removeCondition(0); + else + return sequenceCondition; + } +} + +Condition choiceCondition() : +{ + ChoiceCondition choiceCondition=new ChoiceCondition(); + Condition condition; +} +{ + condition=terminalOrSequenceCondition() + { choiceCondition.addCondition(condition); } + ( LOOKAHEAD(3) (<NL>)* <COMMA> (<NL>)* condition=terminalOrSequenceCondition() + { choiceCondition.addCondition(condition); } + ) * + { + if (choiceCondition.conditionSize()==1) + return choiceCondition.removeCondition(0); + else + return choiceCondition; + } +} + +TermCondition termCondition() : +{ + String str; +} +{ + ( str = identifier() ) + { return new TermCondition(str); } +} + +SuperCondition superCondition() : { } +{ + ( <SUPERDIRECTIVE> ) + { return new SuperCondition(); } +} + +LiteralCondition literalCondition() : +{ + String str; +} +{ + ( str = literal() ) + { return new LiteralCondition(str); } +} + +CompositeItemCondition compositeItemCondition() : +{ + Condition condition; + CompositeItemCondition compositeItemCondition = new CompositeItemCondition(); +} +{ + ( <QUOTE> ( condition=terminalConditionBody() { compositeItemCondition.addCondition(condition); } ) <QUOTE> ) + { return compositeItemCondition; } +} + +// ---------------------------------- Primitives ------------------------------------- + +String context() : +{ + String str; +} +{ + ( str = identifier() <SLASH> ) + { return str; } +} + +String label() : +{ + String str; +} +{ + ( str = identifier() <COLON> ) + { return str; } +} + +String nameSpace() : +{ + String str; +} +{ + ( str = identifier() <DOT> ) + { return str; } +} + +String identifier() : { } +{ + ( <IDENTIFIER> | <NUMBER> ) + { return token.image; } +} + +String stringOrLiteral() : +{ + String str; +} +{ + ( str = string() | str = literal() ) + { return str; } +} + +String identifierOrLiteral() : +{ + String str; +} +{ + ( str = identifier() | str = literal() ) + { return str; } +} + +String comparison() : { } +{ + ( <DIFFERENT> | <CONTAINS> | <EQUALS> | <LARGEREQUALS> | <SMALLEREQUALS> | <LARGER> | <SMALLER> ) + { return token.image; } +} + +String string() : +{ + StringBuilder str = new StringBuilder(); +} +{ + ( ( <SLASH> | <IDENTIFIER> | <DOT> | <DASH> ) { str.append(token.image); } ) + + { return str.toString(); } +} + +String literal() : { } +{ + ( <LITERAL> ) + { return UnicodeUtilities.unquote(token.image); } +} + +int number() : { } +{ + <NUMBER> { return Integer.decode(token.image); } +} diff --git a/container-search/src/main/javacc/com/yahoo/search/grouping/request/parser/GroupingParser.jj b/container-search/src/main/javacc/com/yahoo/search/grouping/request/parser/GroupingParser.jj new file mode 100644 index 00000000000..89433ab52f5 --- /dev/null +++ b/container-search/src/main/javacc/com/yahoo/search/grouping/request/parser/GroupingParser.jj @@ -0,0 +1,1148 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +// -------------------------------------------------------------------------------- +// +// JavaCC options. When this file is changed, run "ant compileparser" to rebuild +// the parser classes. +// +// -------------------------------------------------------------------------------- +options { + CACHE_TOKENS = true; + STATIC = false; + DEBUG_PARSER = false; + USER_TOKEN_MANAGER = false; + USER_CHAR_STREAM = true; + ERROR_REPORTING = true; +} + +// -------------------------------------------------------------------------------- +// +// Parser body. +// +// -------------------------------------------------------------------------------- +PARSER_BEGIN(GroupingParser) + +package com.yahoo.search.grouping.request.parser; + +import java.util.List; +import java.util.LinkedList; +import com.yahoo.javacc.UnicodeUtilities; +import com.yahoo.search.grouping.request.*; + +@SuppressWarnings({ "ConstantIfStatement", "UnnecessarySemicolon", "Convert2Diamond", "FinalPrivateMethod" }) +public class GroupingParser { + + private static Number resolveNumber(String str) { + if (str.indexOf('.') >= 0) { + return Double.valueOf(str); + } + return Long.valueOf(str); + } +} + +PARSER_END(GroupingParser) + +TOKEN : +{ + <INTEGER: <DECIMAL> (["l","L"])? | <HEX> (["l","L"])? | <OCTAL> (["l","L"])?> | + <#DECIMAL: ["1"-"9"] (["0"-"9"])*> | + <#HEX: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+> | + <#OCTAL: "0" (["0"-"7"])*> | + <FLOAT: (["0"-"9"])+ ("." (["0"-"9"])*)? (<EXPONENT>)? (["f","F","d","D"])?> | + <#EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+> +} + +// +// NOTE: Whenever you add a new token, you need to also add it do the identifier() rule at the bottom of this grammar. +// NOTE: Failure to do so will cause the token image to become a reserved word. To prevent regression on this, add the +// NOTE: new token to the GroupingParserTestCase#requireThatTokenImagesAreNotReservedWords() test. +// +TOKEN : +{ + <SPACE: [" ","\n","\r","\t"]> | + <SCOLON: ";"> | + <COMMA: ","> | + <DOLLAR: "$"> | + <DOT: "."> | + <EQ: "="> | + <INFIX_ADD: "+"> | + <INFIX_DIV: "/"> | + <INFIX_MOD: "%"> | + <INFIX_MUL: "*"> | + <INFIX_SUB: "-"> | + <LBRACE: "("> | + <RBRACE: ")"> | + <LCURLY: "{"> | + <RCURLY: "}"> | + <LT: "<"> | + <GT: ">"> | + <LBRACKET: "["> | + <RBRACKET: "]"> | + <INF: "inf"> | + <NEGINF: "-inf"> | + <STRING: ("\"" (~["\""] | "\\\"")* "\"") | + ("'" (~["'"] | "\\'")* "'")> | + <ACOS: "acos"> | + <ACOSH: "acosh"> | + <ACCURACY: "accuracy"> | + <ADD: "add"> | + <ALIAS: "alias"> | + <ALL: "all"> | + <AND: "and"> | + <ARRAY: "array"> | + <AS: "as"> | + <AT: "at"> | + <ASIN: "asin"> | + <ASINH: "asinh"> | + <ATAN: "atan"> | + <ATANH: "atanh"> | + <ATTRIBUTE: "attribute"> | + <AVG: "avg"> | + <BUCKET: "bucket"> | + <CAT: "cat"> | + <CBRT: "cbrt"> | + <COS: "cos"> | + <COSH: "cosh"> | + <COUNT: "count"> | + <DEBUGWAIT: "debugwait"> | + <DIV: "div"> | + <DOCIDNSSPECIFIC: "docidnsspecific"> | + <EACH: "each"> | + <EXP: "exp"> | + <FIXEDWIDTH: "fixedwidth"> | + <FLOOR: "floor"> | + <GROUP: "group"> | + <HINT: "hint"> | + <HYPOT: "hypot"> | + <LOG: "log"> | + <LOG1P: "log1p"> | + <LOG10: "log10"> | + <MATH: "math"> | + <MAX: "max"> | + <MD5: "md5"> | + <MIN: "min"> | + <MOD: "mod"> | + <MUL: "mul"> | + <NEG: "neg"> | + <NORMALIZESUBJECT: "normalizesubject"> | + <NOW: "now"> | + <OR: "or"> | + <ORDER: "order"> | + <OUTPUT: "output"> | + <POW: "pow"> | + <PRECISION: "precision"> | + <PREDEFINED: "predefined"> | + <RELEVANCE: "relevance"> | + <REVERSE: "reverse"> | + <SIN: "sin"> | + <SINH: "sinh"> | + <SIZE: "size"> | + <SORT: "sort"> | + <INTERPOLATEDLOOKUP: "interpolatedlookup"> | + <SQRT: "sqrt"> | + <STRCAT: "strcat"> | + <STRLEN: "strlen"> | + <SUB: "sub"> | + <SUM: "sum"> | + <SUMMARY: "summary"> | + <TAN: "tan"> | + <TANH: "tanh"> | + <TIME: "time"> | + <TIME_DATE: "date"> | + <TIME_DAYOFMONTH: "dayofmonth"> | + <TIME_DAYOFWEEK: "dayofweek"> | + <TIME_DAYOFYEAR: "dayofyear"> | + <TIME_HOUROFDAY: "hourofday"> | + <TIME_MINUTEOFHOUR: "minuteofhour"> | + <TIME_MONTHOFYEAR: "monthofyear"> | + <TIME_SECONDOFMINUTE: "secondofminute"> | + <TIME_YEAR: "year"> | + <TODOUBLE: "todouble"> | + <TOLONG: "tolong"> | + <TORAW: "toraw"> | + <TOSTRING: "tostring"> | + <TRUE: "true"> | + <FALSE: "false"> | + <UCA: "uca"> | + <WHERE: "where"> | + <X: "x"> | + <XOR: "xor"> | + <XORBIT: "xorbit"> | + <Y: "y"> | + <YMUM: "ymum"> | + <ZCURVE: "zcurve"> | + <IDENTIFIER: ["A"-"Z","a"-"z"](["A"-"Z","a"-"z","0"-"9","_","@"])*> +} + +// -------------------------------------------------------------------------------- +// +// Production rules. +// +// -------------------------------------------------------------------------------- + +List<GroupingOperation> requestList() : +{ + List<GroupingOperation> lst = new LinkedList<GroupingOperation>(); + GroupingOperation val; +} +{ + ( space() val = root() { lst.add(val); } ( scolon() val = root() { lst.add(val); } )* <EOF> ) + { return lst;} +} + +GroupingOperation request() : +{ + GroupingOperation val; +} +{ + ( space() val = root() <EOF> ) + { return val; } +} + +GroupingOperation root() : +{ + String str; + GroupingOperation ret; +} +{ + ( ret = operation(null) + [ <WHERE> lbrace() str = where() rbrace() { GroupingOperation grp = new AllOperation(); + grp.setWhere(str); + grp.addChild(ret); + ret = grp; } ] ) + { return ret; } +} + +GroupingOperation operation(GroupingOperation parent) : +{ + GroupingOperation ret; +} +{ + ( ret = allOperation(parent) | ret = eachOperation(parent) ) + { return ret; } +} + +GroupingOperation allOperation(GroupingOperation parent) : +{ + GroupingOperation ret; +} +{ + ( <ALL> { ret = new AllOperation(); if (parent != null) { parent.addChild(ret); } } + lbrace() operationBody(ret) rbrace() ) + { return ret; } +} + +GroupingOperation eachOperation(GroupingOperation parent) : +{ + String str; + GroupingOperation ret; +} +{ + ( <EACH> { ret = new EachOperation(); if (parent != null) { parent.addChild(ret); } } + lbrace() operationBody(ret) rbrace() + [ <AS> lbrace() str = string() rbrace() { ret.setLabel(str); } ] ) + { return ret; } +} + +void operationBody(GroupingOperation parent) : +{ + String str; + Number num; + GroupingExpression exp; + List<GroupingExpression> lst; +} +{ + [ <GROUP> lbrace() exp = exp(parent) rbrace() { parent.setGroupBy(exp); } ] + ( ( <ACCURACY> lbrace() num = number() rbrace() { parent.setAccuracy(num.doubleValue()); } ) | + ( <ALIAS> lbrace() str = identifier() comma() exp = exp(parent) rbrace() { parent.putAlias(str, exp); } ) | + ( <HINT> lbrace() str = identifier() rbrace() { parent.addHint(str); } ) | + ( <MAX> lbrace() num = number() rbrace() { parent.setMax(num.intValue()); } ) | + ( <ORDER> lbrace() lst = expList(parent) rbrace() { parent.addOrderBy(lst); } ) | + ( <OUTPUT> lbrace() lst = expList(parent) rbrace() { parent.addOutputs(lst); } ) | + ( <PRECISION> lbrace() num = number() rbrace() { parent.setPrecision(num.intValue()); } ) | + ( <WHERE> lbrace() str = where() rbrace() { parent.setWhere(str); } ) )* + ( operation(parent) )* +} + +String where() : +{ + StringBuilder ret = new StringBuilder(); + String str; +} +{ + ( [ <DOLLAR> { ret.append(token.image); } ] str = identifier() { ret.append(str); } ) + { return ret.toString(); } +} + +List<GroupingExpression> expList(GroupingOperation grp) : +{ + GroupingExpression exp; + List<GroupingExpression> ret = new LinkedList<GroupingExpression>(); +} +{ + ( exp = exp(grp) { ret.add(exp); } ( comma() exp = exp(grp) { ret.add(exp); } )* ) + { return ret; } +} + +GroupingExpression exp(GroupingOperation grp) : +{ + String str; + boolean neg = false; + GroupingExpression exp; +} +{ + ( [ add() | sub() { neg = true; } ] + exp = expAlias(grp) { if (neg) { exp = new NegFunction(exp); } } + [ <AS> lbrace() str = string() rbrace() { exp.setLabel(str); } ] ) + { return exp; } +} + +GroupingExpression expAlias(GroupingOperation grp) : +{ + String str; + GroupingExpression exp; +} +{ + ( ( <DOLLAR> str = identifier() [ eq() exp = expMath(grp) { grp.putAlias(str, exp); } ] { exp = grp.getAlias(str); } ) | + ( exp = expMath(grp) ) ) + { return exp; } +} + +GroupingExpression expMath(GroupingOperation grp) : +{ + MathResolver.Type type = MathResolver.Type.ADD; + MathResolver math = new MathResolver(); + GroupingExpression exp; +} +{ + ( exp = value(grp) { math.push(type, exp); } + ( ( add() { type = MathResolver.Type.ADD; } | + div() { type = MathResolver.Type.DIV; } | + mod() { type = MathResolver.Type.MOD; } | + mul() { type = MathResolver.Type.MUL; } | + sub() { type = MathResolver.Type.SUB; } ) exp = value(grp) { math.push(type, exp); } )* ) + { return math.resolve(); } +} + +GroupingExpression value(GroupingOperation grp) : +{ + GroupingExpression exp; +} +{ + ( LOOKAHEAD(2) + ( ( lbrace() exp = exp(grp) rbrace() ) | + exp = addFunction(grp) | + exp = andFunction(grp) | + exp = attributeFunction() | + exp = avgExpression(grp) | + exp = catFunction(grp) | + exp = constantValue() | + exp = countAggregator() | + exp = debugWaitFunction(grp) | + exp = divFunction(grp) | + exp = docIdNsSpecificValue() | + exp = fixedWidthFunction(grp) | + exp = mathFunction(grp) | + exp = maxExpression(grp) | + exp = md5Function(grp) | + exp = minExpression(grp) | + exp = modFunction(grp) | + exp = mulFunction(grp) | + exp = negFunction(grp) | + exp = normalizeSubjectFunction(grp) | + exp = nowFunction() | + exp = orFunction(grp) | + exp = predefinedFunction(grp) | + exp = relevanceValue() | + exp = reverseFunction(grp) | + exp = sizeFunction(grp) | + exp = sortFunction(grp) | + exp = arrayAtLookup(grp) | + exp = interpolatedLookup(grp) | + exp = stringValue() | + exp = strCatFunction(grp) | + exp = strLenFunction(grp) | + exp = subFunction(grp) | + exp = sumAggregator(grp) | + exp = summaryValue() | + exp = timeFunction(grp) | + exp = toDoubleFunction(grp) | + exp = toLongFunction(grp) | + exp = toRawFunction(grp) | + exp = toStringFunction(grp) | + exp = ucaFunction(grp) | + exp = xorExpression(grp) | + exp = xorBitFunction(grp) | + exp = ymumValue() | + exp = zcurveFunction(grp) ) | + ( exp = attributeValue() ) ) + { return exp; } +} + +AddFunction addFunction(GroupingOperation grp) : +{ + List<GroupingExpression> argN = null; + GroupingExpression arg1, arg2; +} +{ + ( <ADD> lbrace() arg1 = exp(grp) comma() arg2 = exp(grp) [ comma() argN = expList(grp) ] rbrace() ) + { if (argN == null) return new AddFunction(arg1, arg2); + return new AddFunction(arg1, arg2, argN.toArray(new GroupingExpression[argN.size()])); } +} + +AndFunction andFunction(GroupingOperation grp) : +{ + List<GroupingExpression> argN = null; + GroupingExpression arg1, arg2; +} +{ + ( <AND> lbrace() arg1 = exp(grp) comma() arg2 = exp(grp) [ comma() argN = expList(grp) ] rbrace() ) + { if (argN == null) return new AndFunction(arg1, arg2); + return new AndFunction(arg1, arg2, argN.toArray(new GroupingExpression[argN.size()])); } +} + +AttributeValue attributeValue() : +{ + StringBuilder ret = new StringBuilder(); + String str; +} +{ + ( str = identifier() { ret.append(str); } + ( ( <DOT> { ret.append(token.image); } ( str = identifier() { ret.append(str); } ) ) | + ( lcurly() str = string() { ret.append("{\"").append(str).append("\"}"); } rcurly() ) )* ) + { return new AttributeValue(ret.toString()); } +} + +AttributeFunction attributeFunction() : +{ + AttributeValue val; +} +{ + ( <ATTRIBUTE> lbrace() val = attributeValue() rbrace() ) + { return new AttributeFunction(val.getAttributeName()); } +} + +ArrayAtLookup arrayAtLookup(GroupingOperation parent) : +{ + AttributeValue val = null; + GroupingExpression arg2 = null; +} +{ + ( <ARRAY> <DOT> <AT> lbrace() val = attributeValue() comma() arg2 = exp(parent) rbrace() ) + { + return new ArrayAtLookup(val.getAttributeName(), arg2); + } +} + +InterpolatedLookup interpolatedLookup(GroupingOperation parent) : +{ + AttributeValue val = null; + GroupingExpression arg2 = null; +} +{ + ( <INTERPOLATEDLOOKUP> lbrace() val = attributeValue() comma() arg2 = exp(parent) rbrace() ) + { + return new InterpolatedLookup(val.getAttributeName(), arg2); + } +} + +GroupingExpression avgExpression(GroupingOperation grp) : +{ + List<GroupingExpression> argN = null; + GroupingExpression arg1, arg2 = null; +} +{ + ( <AVG> lbrace() arg1 = exp(grp) [ comma() arg2 = exp(grp) [ comma() argN = expList(grp) ] ] rbrace() ) + { if (arg2 == null) return new AvgAggregator(arg1); + if (argN == null) return new AvgFunction(arg1, arg2); + return new AvgFunction(arg1, arg2, argN.toArray(new GroupingExpression[argN.size()])); } +} + +CatFunction catFunction(GroupingOperation grp) : +{ + List<GroupingExpression> argN = null; + GroupingExpression arg1, arg2; +} +{ + ( <CAT> lbrace() arg1 = exp(grp) comma() arg2 = exp(grp) [ comma() argN = expList(grp) ] rbrace() ) + { if (argN == null) return new CatFunction(arg1, arg2); + return new CatFunction(arg1, arg2, argN.toArray(new GroupingExpression[argN.size()])); } +} + +ConstantValue constantValue() : +{ + Number num; +} +{ + ( num = number() ) + { return num instanceof Double ? new DoubleValue((Double)num) : new LongValue((Long)num); } +} + +ConstantValue constantValueSigned() : +{ + Number num; +} +{ + ( num = signedNumber() ) + { return num instanceof Double ? new DoubleValue((Double)num) : new LongValue((Long)num); } +} + +InfiniteValue infiniteNegativeValue() : { } +{ + ( neginf() { return new InfiniteValue(new Infinite(true)); } ) +} + +InfiniteValue infinitePositiveValue() : { } +{ + ( inf() { return new InfiniteValue(new Infinite(false)); } ) +} + +CountAggregator countAggregator() : { } +{ + ( <COUNT> lbrace() rbrace() ) + { return new CountAggregator(); } +} + +DebugWaitFunction debugWaitFunction(GroupingOperation grp) : +{ + GroupingExpression arg; + Number waitTime; + BooleanValue busy; +} +{ ( <DEBUGWAIT> lbrace() arg = exp(grp) comma() + waitTime = number() comma() + busy = booleanValue() + rbrace() ) + { return new DebugWaitFunction(arg, new DoubleValue(waitTime.doubleValue()), busy); } +} + +DivFunction divFunction(GroupingOperation grp) : +{ + List<GroupingExpression> argN = null; + GroupingExpression arg1, arg2; +} +{ + ( <DIV> lbrace() arg1 = exp(grp) comma() arg2 = exp(grp) [ comma() argN = expList(grp) ] rbrace() ) + { if (argN == null) return new DivFunction(arg1, arg2); + return new DivFunction(arg1, arg2, argN.toArray(new GroupingExpression[argN.size()])); } +} + +DocIdNsSpecificValue docIdNsSpecificValue() : { } +{ + ( <DOCIDNSSPECIFIC> lbrace() rbrace() ) + { return new DocIdNsSpecificValue(); } +} + +FixedWidthFunction fixedWidthFunction(GroupingOperation grp) : +{ + GroupingExpression exp; + Number num; +} +{ + ( <FIXEDWIDTH> lbrace() exp = exp(grp) comma() num = number() rbrace() ) + { return new FixedWidthFunction(exp, num); } +} + +GroupingExpression maxExpression(GroupingOperation grp) : +{ + List<GroupingExpression> argN = null; + GroupingExpression arg1, arg2 = null; +} +{ + ( <MAX> lbrace() arg1 = exp(grp) [ comma() arg2 = exp(grp) [ comma() argN = expList(grp) ] ] rbrace() ) + { if (arg2 == null) return new MaxAggregator(arg1); + if (argN == null) return new MaxFunction(arg1, arg2); + return new MaxFunction(arg1, arg2, argN.toArray(new GroupingExpression[argN.size()])); } +} + +GroupingExpression md5Function(GroupingOperation grp) : +{ + GroupingExpression exp; + Number num; +} +{ + ( <MD5> lbrace() exp = exp(grp) comma() num = number() rbrace() ) + { return new Md5Function(exp, num.intValue()); } +} + +GroupingExpression minExpression(GroupingOperation grp) : +{ + List<GroupingExpression> argN = null; + GroupingExpression arg1, arg2 = null; +} +{ + ( <MIN> lbrace() arg1 = exp(grp) [ comma() arg2 = exp(grp) [ comma() argN = expList(grp) ] ] rbrace() ) + { if (arg2 == null) return new MinAggregator(arg1); + if (argN == null) return new MinFunction(arg1, arg2); + return new MinFunction(arg1, arg2, argN.toArray(new GroupingExpression[argN.size()])); } +} + +ModFunction modFunction(GroupingOperation grp) : +{ + List<GroupingExpression> argN = null; + GroupingExpression arg1, arg2; +} +{ + ( <MOD> lbrace() arg1 = exp(grp) comma() arg2 = exp(grp) [ comma() argN = expList(grp) ] rbrace() ) + { if (argN == null) return new ModFunction(arg1, arg2); + return new ModFunction(arg1, arg2, argN.toArray(new GroupingExpression[argN.size()])); } +} + +MulFunction mulFunction(GroupingOperation grp) : +{ + List<GroupingExpression> argN = null; + GroupingExpression arg1, arg2; +} +{ + ( <MUL> lbrace() arg1 = exp(grp) comma() arg2 = exp(grp) [ comma() argN = expList(grp) ] rbrace() ) + { if (argN == null) return new MulFunction(arg1, arg2); + return new MulFunction(arg1, arg2, argN.toArray(new GroupingExpression[argN.size()])); } +} + +NegFunction negFunction(GroupingOperation grp) : +{ + GroupingExpression exp; +} +{ + ( <NEG> lbrace() exp = exp(grp) rbrace() ) + { return new NegFunction(exp); } +} + +NormalizeSubjectFunction normalizeSubjectFunction(GroupingOperation grp) : +{ + GroupingExpression exp; +} +{ + ( <NORMALIZESUBJECT> lbrace() exp = exp(grp) rbrace() ) + { return new NormalizeSubjectFunction(exp); } +} + +NowFunction nowFunction() : { } +{ + ( <NOW> lbrace() rbrace() ) + { return new NowFunction(); } +} + +OrFunction orFunction(GroupingOperation grp) : +{ + List<GroupingExpression> argN = null; + GroupingExpression arg1, arg2; +} +{ + ( <OR> lbrace() arg1 = exp(grp) comma() arg2 = exp(grp) [ comma() argN = expList(grp) ] rbrace() ) + { if (argN == null) return new OrFunction(arg1, arg2); + return new OrFunction(arg1, arg2, argN.toArray(new GroupingExpression[argN.size()])); } +} + +PredefinedFunction predefinedFunction(GroupingOperation grp) : +{ + GroupingExpression exp; + BucketResolver resolver = new BucketResolver(); +} +{ + ( <PREDEFINED> lbrace() exp = exp(grp) comma() + bucket(grp, resolver) ( comma() bucket(grp, resolver) )* rbrace() ) + { return resolver.resolve(exp); } +} + +RelevanceValue relevanceValue() : { } +{ + ( <RELEVANCE> lbrace() rbrace() ) + { return new RelevanceValue(); } +} + +ReverseFunction reverseFunction(GroupingOperation grp) : +{ + GroupingExpression exp; +} +{ + ( <REVERSE> lbrace() exp = exp(grp) rbrace() ) + { return new ReverseFunction(exp); } +} + +SizeFunction sizeFunction(GroupingOperation grp) : +{ + GroupingExpression exp; +} +{ + ( <SIZE> lbrace() exp = exp(grp) rbrace() ) + { return new SizeFunction(exp); } +} + +SortFunction sortFunction(GroupingOperation grp) : +{ + GroupingExpression exp; +} +{ + ( <SORT> lbrace() exp = exp(grp) rbrace() ) + { return new SortFunction(exp); } +} + +StringValue stringValue() : +{ + String str; +} +{ + ( <STRING> { str = UnicodeUtilities.unquote(token.image); } space() ) + { return new StringValue(str); } +} + +RawValue rawValue(GroupingOperation grp) : +{ + RawBuffer buffer = new RawBuffer(); +} +{ + ( lcurly() byteValue(buffer) ( comma() byteValue(buffer) )* rcurly() ) + { return new RawValue(buffer); } +} + +StringValue stringValueUnquoted() : +{ + String str; +} +{ + ( str = string() ) + { return new StringValue(str); } +} + +StrCatFunction strCatFunction(GroupingOperation grp) : +{ + List<GroupingExpression> argN = null; + GroupingExpression arg1, arg2; +} +{ + ( <STRCAT> lbrace() arg1 = exp(grp) comma() arg2 = exp(grp) [ comma() argN = expList(grp) ] rbrace() ) + { if (argN == null) return new StrCatFunction(arg1, arg2); + return new StrCatFunction(arg1, arg2, argN.toArray(new GroupingExpression[argN.size()])); } +} + +StrLenFunction strLenFunction(GroupingOperation grp) : +{ + GroupingExpression exp; +} +{ + ( <STRLEN> lbrace() exp = exp(grp) rbrace() ) + { return new StrLenFunction(exp); } +} + +SubFunction subFunction(GroupingOperation grp) : +{ + List<GroupingExpression> argN = null; + GroupingExpression arg1, arg2; +} +{ + ( <SUB> lbrace() arg1 = exp(grp) comma() arg2 = exp(grp) [ comma() argN = expList(grp) ] rbrace() ) + { if (argN == null) return new SubFunction(arg1, arg2); + return new SubFunction(arg1, arg2, argN.toArray(new GroupingExpression[argN.size()])); } +} + +SumAggregator sumAggregator(GroupingOperation grp) : +{ + GroupingExpression exp; +} +{ + ( <SUM> lbrace() exp = exp(grp) rbrace() ) + { return new SumAggregator(exp); } +} + +SummaryValue summaryValue() : +{ + String str = null; +} +{ + ( <SUMMARY> lbrace() [ str = string() ] rbrace() ) + { return str == null ? new SummaryValue() : new SummaryValue(str); } +} + +FunctionNode timeFunction(GroupingOperation grp) : +{ + TimeFunctions.Type type; + GroupingExpression exp; +} +{ + ( <TIME> <DOT> ( <TIME_DATE> { type = TimeFunctions.Type.DATE; } | + <TIME_DAYOFMONTH> { type = TimeFunctions.Type.DAY_OF_MONTH; } | + <TIME_DAYOFWEEK> { type = TimeFunctions.Type.DAY_OF_WEEK; } | + <TIME_DAYOFYEAR> { type = TimeFunctions.Type.DAY_OF_YEAR; } | + <TIME_HOUROFDAY> { type = TimeFunctions.Type.HOUR_OF_DAY; } | + <TIME_MINUTEOFHOUR> { type = TimeFunctions.Type.MINUTE_OF_HOUR; } | + <TIME_MONTHOFYEAR> { type = TimeFunctions.Type.MONTH_OF_YEAR; } | + <TIME_SECONDOFMINUTE> { type = TimeFunctions.Type.SECOND_OF_MINUTE; } | + <TIME_YEAR> { type = TimeFunctions.Type.YEAR; } ) + lbrace() exp = exp(grp) rbrace() ) + { return TimeFunctions.newInstance(type, exp); } +} + +FunctionNode mathFunction(GroupingOperation grp) : +{ + GroupingExpression arg1, arg2 = null; + MathFunctions.Function func; +} +{ + ( <MATH> <DOT> ( ( ( <POW> { func = MathFunctions.Function.POW; } | + <HYPOT> { func = MathFunctions.Function.HYPOT; } ) lbrace() arg1 = exp(grp) <COMMA> + arg2 = exp(grp) rbrace() ) | + ( ( <EXP> { func = MathFunctions.Function.EXP; } | + <LOG> { func = MathFunctions.Function.LOG; } | + <LOG1P> { func = MathFunctions.Function.LOG1P; } | + <LOG10> { func = MathFunctions.Function.LOG10; } | + <SIN> { func = MathFunctions.Function.SIN; } | + <ASIN> { func = MathFunctions.Function.ASIN; } | + <COS> { func = MathFunctions.Function.COS; } | + <ACOS> { func = MathFunctions.Function.ACOS; } | + <TAN> { func = MathFunctions.Function.TAN; } | + <ATAN> { func = MathFunctions.Function.ATAN; } | + <SQRT> { func = MathFunctions.Function.SQRT; } | + <SINH> { func = MathFunctions.Function.SINH; } | + <ASINH> { func = MathFunctions.Function.ASINH; } | + <COSH> { func = MathFunctions.Function.COSH; } | + <ACOSH> { func = MathFunctions.Function.ACOSH; } | + <TANH> { func = MathFunctions.Function.TANH; } | + <ATANH> { func = MathFunctions.Function.ATANH; } | + <FLOOR> { func = MathFunctions.Function.FLOOR; } | + <CBRT> { func = MathFunctions.Function.CBRT; } ) lbrace() arg1 = exp(grp) rbrace() ) ) ) + { return MathFunctions.newInstance(func, arg1, arg2); } +} + +FunctionNode ucaFunction(GroupingOperation grp) : +{ + GroupingExpression arg; + String locale; + String strength = null; +} +{ + ( <UCA> lbrace() arg = exp(grp) comma() locale = string() [ comma() strength = string() ] rbrace() ) + { return (strength == null ? new UcaFunction(arg, locale) + : new UcaFunction(arg, locale, strength)); } +} + +FunctionNode zcurveFunction(GroupingOperation grp) : +{ + GroupingExpression exp; + int dim; +} +{ + ( <ZCURVE> <DOT> ( <X> { dim = 0; } | <Y> { dim = 1; } ) lbrace() exp = exp(grp) rbrace() ) + { return dim == 0 ? new ZCurveXFunction(exp) : new ZCurveYFunction(exp); } +} + +ToDoubleFunction toDoubleFunction(GroupingOperation grp) : +{ + GroupingExpression exp; +} +{ + ( <TODOUBLE> lbrace() exp = exp(grp) rbrace() ) + { return new ToDoubleFunction(exp); } +} + +ToLongFunction toLongFunction(GroupingOperation grp) : +{ + GroupingExpression exp; +} +{ + ( <TOLONG> lbrace() exp = exp(grp) rbrace() ) + { return new ToLongFunction(exp); } +} + +ToRawFunction toRawFunction(GroupingOperation grp) : +{ + GroupingExpression exp; +} +{ + ( <TORAW> lbrace() exp = exp(grp) rbrace() ) + { return new ToRawFunction(exp); } +} + + +ToStringFunction toStringFunction(GroupingOperation grp) : +{ + GroupingExpression exp; +} +{ + ( <TOSTRING> lbrace() exp = exp(grp) rbrace() ) + { return new ToStringFunction(exp); } +} + +GroupingExpression xorExpression(GroupingOperation grp) : +{ + List<GroupingExpression> argN = null; + GroupingExpression arg1, arg2 = null; +} +{ + ( <XOR> lbrace() arg1 = exp(grp) [ comma() arg2 = exp(grp) [ comma() argN = expList(grp) ] ] rbrace() ) + { if (arg2 == null) return new XorAggregator(arg1); + if (argN == null) return new XorFunction(arg1, arg2); + return new XorFunction(arg1, arg2, argN.toArray(new GroupingExpression[argN.size()])); } +} + +XorBitFunction xorBitFunction(GroupingOperation grp) : +{ + GroupingExpression exp; + Number num; +} +{ + ( <XORBIT> lbrace() exp = exp(grp) comma() num = number() rbrace() ) + { return new XorBitFunction(exp, num.intValue()); } +} + +YmumValue ymumValue() : { } +{ + ( <YMUM> lbrace() rbrace() ) + { return new YmumValue(); } +} + +void bucket(GroupingOperation grp, BucketResolver resolver) : +{ + ConstantValue from, to = null; + boolean inclusiveFrom, inclusiveTo; +} +{ + ( <BUCKET> ( ( ( lbrace() | lbracket() ) { inclusiveFrom = true; } ) | + ( lt() { inclusiveFrom = false; } ) + ) + ( ( from = infiniteNegativeValue() | from = rawValue(grp) | from = constantValueSigned() | from = stringValueUnquoted() ) + ( [ comma() ( to = infinitePositiveValue() | to = rawValue(grp) | to = constantValueSigned() | to = stringValueUnquoted() ) ] ) + ) + ( ( ( gt() | rbrace() ) { inclusiveTo = false; } ) | + ( rbracket() { inclusiveTo = true; } ) + ) + ) + { resolver.push(from, inclusiveFrom); resolver.push((to == null) ? from : to, inclusiveTo); } +} + +Number signedNumber() : +{ + String str; + boolean neg = false; +} +{ + ([ <INFIX_SUB> { neg = true; }]( <INTEGER> | <FLOAT> ) { str = neg ? "-" + token.image : token.image; } space() ) + { return resolveNumber(str); } +} + + +Number number() : +{ + String str; +} +{ + ( ( <INTEGER> | <FLOAT> ) { str = token.image; } space() ) + { return resolveNumber(str); } +} + +BooleanValue booleanValue() : +{ + String str; +} +{ + ( ( <TRUE> | <FALSE> ) { str = token.image; } space() ) + { return new BooleanValue(Boolean.parseBoolean(str)); } +} + +void byteValue(RawBuffer buffer) : { } +{ + ( ( <INTEGER> { buffer.put(Byte.parseByte(token.image)); } ) | + ( <STRING> { buffer.put(token.image.getBytes()); } ) + ) +} + +String string() : +{ + String ret; +} +{ + ( ret = identifier() | ( <STRING> { ret = UnicodeUtilities.unquote(token.image); } space() ) ) + { return ret; } +} + +String identifier() : +{ + String ret; +} +{ + ( ( <ACOS> | + <ACOSH> | + <ACCURACY> | + <ADD> | + <ALIAS> | + <ALL> | + <AND> | + <ARRAY> | + <AS> | + <AT> | + <ASIN> | + <ASINH> | + <ATAN> | + <ATANH> | + <ATTRIBUTE> | + <AVG> | + <BUCKET> | + <CAT> | + <CBRT> | + <COS> | + <COSH> | + <COUNT> | + <DEBUGWAIT> | + <DIV> | + <DOCIDNSSPECIFIC> | + <EACH> | + <EXP> | + <FIXEDWIDTH> | + <FLOOR> | + <GROUP> | + <HINT> | + <HYPOT> | + <IDENTIFIER> | + <LOG> | + <LOG1P> | + <LOG10> | + <MATH> | + <MAX> | + <MD5> | + <MIN> | + <MOD> | + <MUL> | + <NEG> | + <NORMALIZESUBJECT> | + <NOW> | + <OR> | + <ORDER> | + <OUTPUT> | + <POW> | + <PRECISION> | + <PREDEFINED> | + <RELEVANCE> | + <REVERSE> | + <SIN> | + <SINH> | + <SIZE> | + <SORT> | + <INTERPOLATEDLOOKUP> | + <SQRT> | + <STRCAT> | + <STRLEN> | + <SUB> | + <SUM> | + <SUMMARY> | + <TAN> | + <TANH> | + <TIME> | + <TIME_DATE> | + <TIME_DAYOFMONTH> | + <TIME_DAYOFWEEK> | + <TIME_DAYOFYEAR> | + <TIME_HOUROFDAY> | + <TIME_MINUTEOFHOUR> | + <TIME_MONTHOFYEAR> | + <TIME_SECONDOFMINUTE> | + <TIME_YEAR> | + <TODOUBLE> | + <TOLONG> | + <TORAW> | + <TOSTRING> | + <TRUE> | + <FALSE> | + <UCA> | + <WHERE> | + <X> | + <XOR> | + <XORBIT> | + <Y> | + <YMUM> | + <ZCURVE> ) { ret = token.image; } space() ) + { return ret; } +} + +void add() : { } +{ + ( <INFIX_ADD> space() ) +} + +void comma() : { } +{ + ( <COMMA> space() ) +} + +void div() : { } +{ + ( <INFIX_DIV> space() ) +} + +void eq() : { } +{ + ( <EQ> space() ) +} + +void lt() : { } +{ + ( <LT> space() ) +} + +void gt() : { } +{ + ( <GT> space() ) +} + +void inf() : { } +{ + ( <INF> space() ) +} + +void neginf() : { } +{ + ( <NEGINF> space() ) +} + +void lbracket() : { } +{ + ( <LBRACKET> space() ) +} + +void rbracket() : { } +{ + ( <RBRACKET> space() ) +} + +void lbrace() : { } +{ + ( <LBRACE> space() ) +} + +void lcurly() : { } +{ + ( <LCURLY> space() ) +} + +void mod() : { } +{ + ( <INFIX_MOD> space() ) +} + +void mul() : { } +{ + ( <INFIX_MUL> space() ) +} + +void rbrace() : { } +{ + ( <RBRACE> space() ) +} + +void rcurly() : { } +{ + ( <RCURLY> space() ) +} + +void sub() : { } +{ + ( <INFIX_SUB> space() ) +} + +void scolon() : { } +{ + ( <SCOLON> space() ) +} + +void space() : { } +{ + ( <SPACE> )* +} diff --git a/container-search/src/main/javacc/com/yahoo/search/query/textserialize/parser/Parser.jj b/container-search/src/main/javacc/com/yahoo/search/query/textserialize/parser/Parser.jj new file mode 100644 index 00000000000..52328ccafa5 --- /dev/null +++ b/container-search/src/main/javacc/com/yahoo/search/query/textserialize/parser/Parser.jj @@ -0,0 +1,205 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +/** + * @author <a href="mailto:tonyv@yahoo-inc.com">tonyv</a> + */ +options { + LOOKAHEAD = 1; + STATIC = false; + UNICODE_INPUT = true; +} + +PARSER_BEGIN(Parser) +package com.yahoo.search.query.textserialize.parser; + +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.LinkedHashMap; + +public class Parser { + private DispatchFormHandler dispatchFormHandler; + private Object dispatchContext; + + public Parser(java.io.Reader stream, DispatchFormHandler dispatchFormHandler, Object dispatchContext) { + this(stream); + this.dispatchFormHandler = dispatchFormHandler; + this.dispatchContext = dispatchContext; + } + + private static String parseString(String in) { + return stripEnclosingQuotes( + in.replace("\\\\", "\\").replace("\\\"", "\"")); + } + + private static String stripEnclosingQuotes(String in) { + return in.substring(1, in.length() - 1); + } +} + +PARSER_END(Parser) + +Object start(): +{ + final Object result; +} +{ + result = form() + <EOF> + + { return result; } +} + +Object form(): +{ + final Object result; +} +{ + ( + result = dispatchForm() | + result = map() | + result = array() | + result = literal() + ) + + { return result; } +} + +Object literal(): +{ + final Object result; +} +{ + ( + result = string() | + result = number() | + result = bool() | + result = null_() + ) + + { return result; } +} + +String string(): +{ + Token t; +} +{ + t = <STRING> + { return parseString(t.image); } +} + +Double number(): +{ + Token t; +} +{ + t = <NUMBER> + { return Double.valueOf(t.image); } +} + +Boolean bool(): +{ + Token t; +} +{ + t = <BOOLEAN> + + { + if ("on".equals(t.image)) return true; + return Boolean.valueOf(t.image); + } +} + +Object null_(): +{} +{ + <NULL> + { return null; } +} + +Map<Object, Object> map(): +{ + Object key, value; + Map<Object, Object> result = new LinkedHashMap<Object, Object>(); +} +{ + <OPEN_CURLY> + ( + key = form() + value = form() + + { result.put(key, value); } + )* + <CLOSE_CURLY> + + { return result; } +} + +Object dispatchForm(): +{ + Token symbol; + List<Object> arguments; +} +{ + <OPEN_PAREN> + symbol = <SYMBOL> + arguments = forms() + <CLOSE_PAREN> + + { return dispatchFormHandler.dispatch(symbol.image, arguments, dispatchContext); } +} + +List<Object> forms(): +{ + Object value; + List<Object> results = new ArrayList<Object>(); +} +{ + ( + value = form() + { results.add(value); } + )* + + { return results; } +} + +List<Object> array(): +{ + List<Object> result; +} +{ + <OPEN_SQUARE> + result = forms() + <CLOSE_SQUARE> + + { return result; } +} + +SKIP : { " " | "\n" | "\r" | "\t" | "\f" | "," } + +TOKEN : { < OPEN_PAREN: "(" > } +TOKEN : { < CLOSE_PAREN: ")" > } +TOKEN : { < OPEN_CURLY: "{" > } +TOKEN : { < CLOSE_CURLY: "}" > } +TOKEN : { < OPEN_SQUARE: "[" > } +TOKEN : { < CLOSE_SQUARE: "]" > } + +TOKEN : { <BOOLEAN: "true" | "false" | "on" | "off" > } +TOKEN : { <NULL: "null" > } + +TOKEN : { < STRING: <QUOTE> (<STRING_CHARACTER>)* <QUOTE> > } +TOKEN : { < #STRING_CHARACTER: "\\\\" | "\\\"" | ~["\"", "\\"] > } +TOKEN : { < #QUOTE: "\"" > } + +TOKEN : { < NUMBER: (<SIGN>)? (<DIGIT>)+ ("." (<DIGIT>)*)? (<EXPONENT>)? > } +TOKEN : { < #EXPONENT: ["e", "E"] (<SIGN>)? (<DIGIT>)+ > } +TOKEN : { < #SIGN: ["+", "-"] >} +TOKEN : { < #DIGIT: ["0" - "9"] > } + +TOKEN : { < SYMBOL: <SYMBOL_FIRST> (<SYMBOL_REST>)* > } +TOKEN : { < #SYMBOL_FIRST: ["a"-"z"] | ["A"-"Z"] | + "+" | "-" | "*" | "/" | + "!" | "?" | + "-" | "_" | + "=" | ">" | "<" > } +TOKEN : { < #SYMBOL_REST: <SYMBOL_FIRST> | ["0" - "9"] | "." > } |