diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fa0abd2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,16 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so +.vscode + + +# fresh +tmp +*.retry +/dist +.#* +*~ +*.sh +__debug_bin + diff --git a/Cypher.g4 b/Cypher.g4 new file mode 100644 index 0000000..dd617c7 --- /dev/null +++ b/Cypher.g4 @@ -0,0 +1,792 @@ +/** + * Copyright (c) 2015-2021 "Neo Technology," + * Network Engine for Objects in Lund AB [http://neotechnology.com] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Attribution Notice under the terms of the Apache License 2.0 + * + * This work was created by the collective efforts of the openCypher community. + * Without limiting the terms of Section 6, any Derivative Work that is not + * approved by the public consensus process of the openCypher Implementers Group + * should not be described as “Cypher” (and Cypher® is a registered trademark of + * Neo4j Inc.) or as "openCypher". Extensions by implementers or prototypes or + * proposals for change that have been documented or implemented should only be + * described as "implementation extensions to Cypher" or as "proposed changes to + * Cypher that are not yet approved by the openCypher community". + */ +grammar Cypher; + +oC_Cypher + : SP? oC_Statement ( SP? ';' )? SP? EOF ; + +oC_Statement + : oC_Query ; + +oC_Query + : oC_RegularQuery + | oC_StandaloneCall + ; + +oC_RegularQuery + : oC_SingleQuery ( SP? oC_Union )* ; + +oC_Union + : ( UNION SP ALL SP? oC_SingleQuery ) + | ( UNION SP? oC_SingleQuery ) + ; + +UNION : ( 'U' | 'u' ) ( 'N' | 'n' ) ( 'I' | 'i' ) ( 'O' | 'o' ) ( 'N' | 'n' ) ; + +ALL : ( 'A' | 'a' ) ( 'L' | 'l' ) ( 'L' | 'l' ) ; + +oC_SingleQuery + : oC_SinglePartQuery + | oC_MultiPartQuery + ; + +oC_SinglePartQuery + : ( ( oC_ReadingClause SP? )* oC_Return ) + | ( ( oC_ReadingClause SP? )* oC_UpdatingClause ( SP? oC_UpdatingClause )* ( SP? oC_Return )? ) + ; + +oC_MultiPartQuery + : ( ( oC_ReadingClause SP? )* ( oC_UpdatingClause SP? )* oC_With SP? )+ oC_SinglePartQuery ; + +oC_UpdatingClause + : oC_Create + | oC_Merge + | oC_Delete + | oC_Set + | oC_Remove + ; + +oC_ReadingClause + : oC_Match + | oC_Unwind + | oC_InQueryCall + ; + +oC_Match + : ( OPTIONAL SP )? MATCH SP? oC_Pattern ( SP? oC_Where )? ; + +OPTIONAL : ( 'O' | 'o' ) ( 'P' | 'p' ) ( 'T' | 't' ) ( 'I' | 'i' ) ( 'O' | 'o' ) ( 'N' | 'n' ) ( 'A' | 'a' ) ( 'L' | 'l' ) ; + +MATCH : ( 'M' | 'm' ) ( 'A' | 'a' ) ( 'T' | 't' ) ( 'C' | 'c' ) ( 'H' | 'h' ) ; + +oC_Unwind + : UNWIND SP? oC_Expression SP AS SP oC_Variable ; + +UNWIND : ( 'U' | 'u' ) ( 'N' | 'n' ) ( 'W' | 'w' ) ( 'I' | 'i' ) ( 'N' | 'n' ) ( 'D' | 'd' ) ; + +AS : ( 'A' | 'a' ) ( 'S' | 's' ) ; + +oC_Merge + : MERGE SP? oC_PatternPart ( SP oC_MergeAction )* ; + +MERGE : ( 'M' | 'm' ) ( 'E' | 'e' ) ( 'R' | 'r' ) ( 'G' | 'g' ) ( 'E' | 'e' ) ; + +oC_MergeAction + : ( ON SP MATCH SP oC_Set ) + | ( ON SP CREATE SP oC_Set ) + ; + +ON : ( 'O' | 'o' ) ( 'N' | 'n' ) ; + +CREATE : ( 'C' | 'c' ) ( 'R' | 'r' ) ( 'E' | 'e' ) ( 'A' | 'a' ) ( 'T' | 't' ) ( 'E' | 'e' ) ; + +oC_Create + : CREATE SP? oC_Pattern ; + +oC_Set + : SET SP? oC_SetItem ( SP? ',' SP? oC_SetItem )* ; + +SET : ( 'S' | 's' ) ( 'E' | 'e' ) ( 'T' | 't' ) ; + +oC_SetItem + : ( oC_PropertyExpression SP? '=' SP? oC_Expression ) + | ( oC_Variable SP? '=' SP? oC_Expression ) + | ( oC_Variable SP? '+=' SP? oC_Expression ) + | ( oC_Variable SP? oC_NodeLabels ) + ; + +oC_Delete + : ( DETACH SP )? DELETE SP? oC_Expression ( SP? ',' SP? oC_Expression )* ; + +DETACH : ( 'D' | 'd' ) ( 'E' | 'e' ) ( 'T' | 't' ) ( 'A' | 'a' ) ( 'C' | 'c' ) ( 'H' | 'h' ) ; + +DELETE : ( 'D' | 'd' ) ( 'E' | 'e' ) ( 'L' | 'l' ) ( 'E' | 'e' ) ( 'T' | 't' ) ( 'E' | 'e' ) ; + +oC_Remove + : REMOVE SP oC_RemoveItem ( SP? ',' SP? oC_RemoveItem )* ; + +REMOVE : ( 'R' | 'r' ) ( 'E' | 'e' ) ( 'M' | 'm' ) ( 'O' | 'o' ) ( 'V' | 'v' ) ( 'E' | 'e' ) ; + +oC_RemoveItem + : ( oC_Variable oC_NodeLabels ) + | oC_PropertyExpression + ; + +oC_InQueryCall + : CALL SP oC_ExplicitProcedureInvocation ( SP? YIELD SP oC_YieldItems )? ; + +CALL : ( 'C' | 'c' ) ( 'A' | 'a' ) ( 'L' | 'l' ) ( 'L' | 'l' ) ; + +YIELD : ( 'Y' | 'y' ) ( 'I' | 'i' ) ( 'E' | 'e' ) ( 'L' | 'l' ) ( 'D' | 'd' ) ; + +oC_StandaloneCall + : CALL SP ( oC_ExplicitProcedureInvocation | oC_ImplicitProcedureInvocation ) ( SP YIELD SP oC_YieldItems )? ; + +oC_YieldItems + : ( '*' | ( oC_YieldItem ( SP? ',' SP? oC_YieldItem )* ) ) ( SP? oC_Where )? ; + +oC_YieldItem + : ( oC_ProcedureResultField SP AS SP )? oC_Variable ; + +oC_With + : WITH oC_ProjectionBody ( SP? oC_Where )? ; + +WITH : ( 'W' | 'w' ) ( 'I' | 'i' ) ( 'T' | 't' ) ( 'H' | 'h' ) ; + +oC_Return + : RETURN oC_ProjectionBody ; + +RETURN : ( 'R' | 'r' ) ( 'E' | 'e' ) ( 'T' | 't' ) ( 'U' | 'u' ) ( 'R' | 'r' ) ( 'N' | 'n' ) ; + +oC_ProjectionBody + : ( SP? DISTINCT )? SP oC_ProjectionItems ( SP oC_Order )? ( SP oC_Skip )? ( SP oC_Limit )? ; + +DISTINCT : ( 'D' | 'd' ) ( 'I' | 'i' ) ( 'S' | 's' ) ( 'T' | 't' ) ( 'I' | 'i' ) ( 'N' | 'n' ) ( 'C' | 'c' ) ( 'T' | 't' ) ; + +oC_ProjectionItems + : ( '*' ( SP? ',' SP? oC_ProjectionItem )* ) + | ( oC_ProjectionItem ( SP? ',' SP? oC_ProjectionItem )* ) + ; + +oC_ProjectionItem + : ( oC_Expression SP AS SP oC_Variable ) + | oC_Expression + ; + +oC_Order + : ORDER SP BY SP oC_SortItem ( ',' SP? oC_SortItem )* ; + +ORDER : ( 'O' | 'o' ) ( 'R' | 'r' ) ( 'D' | 'd' ) ( 'E' | 'e' ) ( 'R' | 'r' ) ; + +BY : ( 'B' | 'b' ) ( 'Y' | 'y' ) ; + +oC_Skip + : L_SKIP SP oC_Expression ; + +L_SKIP : ( 'S' | 's' ) ( 'K' | 'k' ) ( 'I' | 'i' ) ( 'P' | 'p' ) ; + +oC_Limit + : LIMIT SP oC_Expression ; + +LIMIT : ( 'L' | 'l' ) ( 'I' | 'i' ) ( 'M' | 'm' ) ( 'I' | 'i' ) ( 'T' | 't' ) ; + +oC_SortItem + : oC_Expression ( SP? ( ASCENDING | ASC | DESCENDING | DESC ) )? ; + +ASCENDING : ( 'A' | 'a' ) ( 'S' | 's' ) ( 'C' | 'c' ) ( 'E' | 'e' ) ( 'N' | 'n' ) ( 'D' | 'd' ) ( 'I' | 'i' ) ( 'N' | 'n' ) ( 'G' | 'g' ) ; + +ASC : ( 'A' | 'a' ) ( 'S' | 's' ) ( 'C' | 'c' ) ; + +DESCENDING : ( 'D' | 'd' ) ( 'E' | 'e' ) ( 'S' | 's' ) ( 'C' | 'c' ) ( 'E' | 'e' ) ( 'N' | 'n' ) ( 'D' | 'd' ) ( 'I' | 'i' ) ( 'N' | 'n' ) ( 'G' | 'g' ) ; + +DESC : ( 'D' | 'd' ) ( 'E' | 'e' ) ( 'S' | 's' ) ( 'C' | 'c' ) ; + +oC_Where + : WHERE SP oC_Expression ; + +WHERE : ( 'W' | 'w' ) ( 'H' | 'h' ) ( 'E' | 'e' ) ( 'R' | 'r' ) ( 'E' | 'e' ) ; + +oC_Pattern + : oC_PatternPart ( SP? ',' SP? oC_PatternPart )* ; + +oC_PatternPart + : ( oC_Variable SP? '=' SP? oC_AnonymousPatternPart ) + | oC_AnonymousPatternPart + ; + +oC_AnonymousPatternPart + : oC_PatternElement ; + +oC_PatternElement + : ( oC_NodePattern ( SP? oC_PatternElementChain )* ) + | ( '(' oC_PatternElement ')' ) + ; + +oC_NodePattern + : '(' SP? ( oC_Variable SP? )? ( oC_NodeLabels SP? )? ( oC_Properties SP? )? ')' ; + +oC_PatternElementChain + : oC_RelationshipPattern SP? oC_NodePattern ; + +oC_RelationshipPattern + : ( oC_LeftArrowHead SP? oC_Dash SP? oC_RelationshipDetail? SP? oC_Dash SP? oC_RightArrowHead ) + | ( oC_LeftArrowHead SP? oC_Dash SP? oC_RelationshipDetail? SP? oC_Dash ) + | ( oC_Dash SP? oC_RelationshipDetail? SP? oC_Dash SP? oC_RightArrowHead ) + | ( oC_Dash SP? oC_RelationshipDetail? SP? oC_Dash ) + ; + +oC_RelationshipDetail + : '[' SP? ( oC_Variable SP? )? ( oC_RelationshipTypes SP? )? oC_RangeLiteral? ( oC_Properties SP? )? ']' ; + +oC_Properties + : oC_MapLiteral + | oC_Parameter + ; + +oC_RelationshipTypes + : ':' SP? oC_RelTypeName ( SP? '|' ':'? SP? oC_RelTypeName )* ; + +oC_NodeLabels + : oC_NodeLabel ( SP? oC_NodeLabel )* ; + +oC_NodeLabel + : ':' SP? oC_LabelName ; + +oC_RangeLiteral + : '*' SP? ( oC_IntegerLiteral SP? )? ( '..' SP? ( oC_IntegerLiteral SP? )? )? ; + +oC_LabelName + : oC_SchemaName ; + +oC_RelTypeName + : oC_SchemaName ; + +oC_Expression + : oC_OrExpression ; + +oC_OrExpression + : oC_XorExpression ( SP OR SP oC_XorExpression )* ; + +OR : ( 'O' | 'o' ) ( 'R' | 'r' ) ; + +oC_XorExpression + : oC_AndExpression ( SP XOR SP oC_AndExpression )* ; + +XOR : ( 'X' | 'x' ) ( 'O' | 'o' ) ( 'R' | 'r' ) ; + +oC_AndExpression + : oC_NotExpression ( SP AND SP oC_NotExpression )* ; + +AND : ( 'A' | 'a' ) ( 'N' | 'n' ) ( 'D' | 'd' ) ; + +oC_NotExpression + : ( NOT SP? )* oC_ComparisonExpression ; + +NOT : ( 'N' | 'n' ) ( 'O' | 'o' ) ( 'T' | 't' ) ; + +oC_ComparisonExpression + : oC_AddOrSubtractExpression ( SP? oC_PartialComparisonExpression )* ; + +oC_AddOrSubtractExpression + : oC_MultiplyDivideModuloExpression ( ( SP? '+' SP? oC_MultiplyDivideModuloExpression ) | ( SP? '-' SP? oC_MultiplyDivideModuloExpression ) )* ; + +oC_MultiplyDivideModuloExpression + : oC_PowerOfExpression ( ( SP? '*' SP? oC_PowerOfExpression ) | ( SP? '/' SP? oC_PowerOfExpression ) | ( SP? '%' SP? oC_PowerOfExpression ) )* ; + +oC_PowerOfExpression + : oC_UnaryAddOrSubtractExpression ( SP? '^' SP? oC_UnaryAddOrSubtractExpression )* ; + +oC_UnaryAddOrSubtractExpression + : ( ( '+' | '-' ) SP? )* oC_StringListNullOperatorExpression ; + +oC_StringListNullOperatorExpression + : oC_PropertyOrLabelsExpression ( oC_StringOperatorExpression | oC_ListOperatorExpression | oC_NullOperatorExpression )* ; + +oC_ListOperatorExpression + : ( SP IN SP? oC_PropertyOrLabelsExpression ) + | ( SP? '[' oC_Expression ']' ) + | ( SP? '[' oC_Expression? '..' oC_Expression? ']' ) + ; + +IN : ( 'I' | 'i' ) ( 'N' | 'n' ) ; + +oC_StringOperatorExpression + : ( ( SP STARTS SP WITH ) | ( SP ENDS SP WITH ) | ( SP CONTAINS ) ) SP? oC_PropertyOrLabelsExpression ; + +STARTS : ( 'S' | 's' ) ( 'T' | 't' ) ( 'A' | 'a' ) ( 'R' | 'r' ) ( 'T' | 't' ) ( 'S' | 's' ) ; + +ENDS : ( 'E' | 'e' ) ( 'N' | 'n' ) ( 'D' | 'd' ) ( 'S' | 's' ) ; + +CONTAINS : ( 'C' | 'c' ) ( 'O' | 'o' ) ( 'N' | 'n' ) ( 'T' | 't' ) ( 'A' | 'a' ) ( 'I' | 'i' ) ( 'N' | 'n' ) ( 'S' | 's' ) ; + +oC_NullOperatorExpression + : ( SP IS SP NULL ) + | ( SP IS SP NOT SP NULL ) + ; + +IS : ( 'I' | 'i' ) ( 'S' | 's' ) ; + +NULL : ( 'N' | 'n' ) ( 'U' | 'u' ) ( 'L' | 'l' ) ( 'L' | 'l' ) ; + +oC_PropertyOrLabelsExpression + : oC_Atom ( SP? oC_PropertyLookup )* ( SP? oC_NodeLabels )? ; + +oC_Atom + : oC_Literal + | oC_Parameter + | oC_CaseExpression + | ( COUNT SP? '(' SP? '*' SP? ')' ) + | oC_ListComprehension + | oC_PatternComprehension + | ( ALL SP? '(' SP? oC_FilterExpression SP? ')' ) + | ( ANY SP? '(' SP? oC_FilterExpression SP? ')' ) + | ( NONE SP? '(' SP? oC_FilterExpression SP? ')' ) + | ( SINGLE SP? '(' SP? oC_FilterExpression SP? ')' ) + | oC_RelationshipsPattern + | oC_ParenthesizedExpression + | oC_FunctionInvocation + | oC_Variable + ; + +COUNT : ( 'C' | 'c' ) ( 'O' | 'o' ) ( 'U' | 'u' ) ( 'N' | 'n' ) ( 'T' | 't' ) ; + +ANY : ( 'A' | 'a' ) ( 'N' | 'n' ) ( 'Y' | 'y' ) ; + +NONE : ( 'N' | 'n' ) ( 'O' | 'o' ) ( 'N' | 'n' ) ( 'E' | 'e' ) ; + +SINGLE : ( 'S' | 's' ) ( 'I' | 'i' ) ( 'N' | 'n' ) ( 'G' | 'g' ) ( 'L' | 'l' ) ( 'E' | 'e' ) ; + +oC_Literal + : oC_NumberLiteral + | StringLiteral + | oC_BooleanLiteral + | NULL + | oC_MapLiteral + | oC_ListLiteral + ; + +oC_BooleanLiteral + : TRUE + | FALSE + ; + +TRUE : ( 'T' | 't' ) ( 'R' | 'r' ) ( 'U' | 'u' ) ( 'E' | 'e' ) ; + +FALSE : ( 'F' | 'f' ) ( 'A' | 'a' ) ( 'L' | 'l' ) ( 'S' | 's' ) ( 'E' | 'e' ) ; + +oC_ListLiteral + : '[' SP? ( oC_Expression SP? ( ',' SP? oC_Expression SP? )* )? ']' ; + +oC_PartialComparisonExpression + : ( '=' SP? oC_AddOrSubtractExpression ) + | ( '<>' SP? oC_AddOrSubtractExpression ) + | ( '<' SP? oC_AddOrSubtractExpression ) + | ( '>' SP? oC_AddOrSubtractExpression ) + | ( '<=' SP? oC_AddOrSubtractExpression ) + | ( '>=' SP? oC_AddOrSubtractExpression ) + ; + +oC_ParenthesizedExpression + : '(' SP? oC_Expression SP? ')' ; + +oC_RelationshipsPattern + : oC_NodePattern ( SP? oC_PatternElementChain )+ ; + +oC_FilterExpression + : oC_IdInColl ( SP? oC_Where )? ; + +oC_IdInColl + : oC_Variable SP IN SP oC_Expression ; + +oC_FunctionInvocation + : oC_FunctionName SP? '(' SP? ( DISTINCT SP? )? ( oC_Expression SP? ( ',' SP? oC_Expression SP? )* )? ')' ; + +oC_FunctionName + : ( oC_Namespace oC_SymbolicName ) + | EXISTS + ; + +EXISTS : ( 'E' | 'e' ) ( 'X' | 'x' ) ( 'I' | 'i' ) ( 'S' | 's' ) ( 'T' | 't' ) ( 'S' | 's' ) ; + +oC_ExplicitProcedureInvocation + : oC_ProcedureName SP? '(' SP? ( oC_Expression SP? ( ',' SP? oC_Expression SP? )* )? ')' ; + +oC_ImplicitProcedureInvocation + : oC_ProcedureName ; + +oC_ProcedureResultField + : oC_SymbolicName ; + +oC_ProcedureName + : oC_Namespace oC_SymbolicName ; + +oC_Namespace + : ( oC_SymbolicName '.' )* ; + +oC_ListComprehension + : '[' SP? oC_FilterExpression ( SP? '|' SP? oC_Expression )? SP? ']' ; + +oC_PatternComprehension + : '[' SP? ( oC_Variable SP? '=' SP? )? oC_RelationshipsPattern SP? ( WHERE SP? oC_Expression SP? )? '|' SP? oC_Expression SP? ']' ; + +oC_PropertyLookup + : '.' SP? ( oC_PropertyKeyName ) ; + +oC_CaseExpression + : ( ( CASE ( SP? oC_CaseAlternatives )+ ) | ( CASE SP? oC_Expression ( SP? oC_CaseAlternatives )+ ) ) ( SP? ELSE SP? oC_Expression )? SP? END ; + +CASE : ( 'C' | 'c' ) ( 'A' | 'a' ) ( 'S' | 's' ) ( 'E' | 'e' ) ; + +ELSE : ( 'E' | 'e' ) ( 'L' | 'l' ) ( 'S' | 's' ) ( 'E' | 'e' ) ; + +END : ( 'E' | 'e' ) ( 'N' | 'n' ) ( 'D' | 'd' ) ; + +oC_CaseAlternatives + : WHEN SP? oC_Expression SP? THEN SP? oC_Expression ; + +WHEN : ( 'W' | 'w' ) ( 'H' | 'h' ) ( 'E' | 'e' ) ( 'N' | 'n' ) ; + +THEN : ( 'T' | 't' ) ( 'H' | 'h' ) ( 'E' | 'e' ) ( 'N' | 'n' ) ; + +oC_Variable + : oC_SymbolicName ; + +StringLiteral + : ( '"' ( StringLiteral_0 | EscapedChar )* '"' ) + | ( '\'' ( StringLiteral_1 | EscapedChar )* '\'' ) + ; + +EscapedChar + : '\\' ( '\\' | '\'' | '"' | ( 'B' | 'b' ) | ( 'F' | 'f' ) | ( 'N' | 'n' ) | ( 'R' | 'r' ) | ( 'T' | 't' ) | ( ( 'U' | 'u' ) ( HexDigit HexDigit HexDigit HexDigit ) ) | ( ( 'U' | 'u' ) ( HexDigit HexDigit HexDigit HexDigit HexDigit HexDigit HexDigit HexDigit ) ) ) ; + +oC_NumberLiteral + : oC_DoubleLiteral + | oC_IntegerLiteral + ; + +oC_MapLiteral + : '{' SP? ( oC_PropertyKeyName SP? ':' SP? oC_Expression SP? ( ',' SP? oC_PropertyKeyName SP? ':' SP? oC_Expression SP? )* )? '}' ; + +oC_Parameter + : '$' ( oC_SymbolicName | DecimalInteger ) ; + +oC_PropertyExpression + : oC_Atom ( SP? oC_PropertyLookup )+ ; + +oC_PropertyKeyName + : oC_SchemaName ; + +oC_IntegerLiteral + : HexInteger + | OctalInteger + | DecimalInteger + ; + +HexInteger + : '0x' ( HexDigit )+ ; + +DecimalInteger + : ZeroDigit + | ( NonZeroDigit ( Digit )* ) + ; + +OctalInteger + : ZeroDigit ( OctDigit )+ ; + +HexLetter + : ( 'A' | 'a' ) + | ( 'B' | 'b' ) + | ( 'C' | 'c' ) + | ( 'D' | 'd' ) + | ( 'E' | 'e' ) + | ( 'F' | 'f' ) + ; + +HexDigit + : Digit + | HexLetter + ; + +Digit + : ZeroDigit + | NonZeroDigit + ; + +NonZeroDigit + : NonZeroOctDigit + | '8' + | '9' + ; + +NonZeroOctDigit + : '1' + | '2' + | '3' + | '4' + | '5' + | '6' + | '7' + ; + +OctDigit + : ZeroDigit + | NonZeroOctDigit + ; + +ZeroDigit + : '0' ; + +oC_DoubleLiteral + : ExponentDecimalReal + | RegularDecimalReal + ; + +ExponentDecimalReal + : ( ( Digit )+ | ( ( Digit )+ '.' ( Digit )+ ) | ( '.' ( Digit )+ ) ) ( 'E' | 'e' ) '-'? ( Digit )+ ; + +RegularDecimalReal + : ( Digit )* '.' ( Digit )+ ; + +oC_SchemaName + : oC_SymbolicName + | oC_ReservedWord + ; + +oC_ReservedWord + : ALL + | ASC + | ASCENDING + | BY + | CREATE + | DELETE + | DESC + | DESCENDING + | DETACH + | EXISTS + | LIMIT + | MATCH + | MERGE + | ON + | OPTIONAL + | ORDER + | REMOVE + | RETURN + | SET + | L_SKIP + | WHERE + | WITH + | UNION + | UNWIND + | AND + | AS + | CONTAINS + | DISTINCT + | ENDS + | IN + | IS + | NOT + | OR + | STARTS + | XOR + | FALSE + | TRUE + | NULL + | CONSTRAINT + | DO + | FOR + | REQUIRE + | UNIQUE + | CASE + | WHEN + | THEN + | ELSE + | END + | MANDATORY + | SCALAR + | OF + | ADD + | DROP + ; + +CONSTRAINT : ( 'C' | 'c' ) ( 'O' | 'o' ) ( 'N' | 'n' ) ( 'S' | 's' ) ( 'T' | 't' ) ( 'R' | 'r' ) ( 'A' | 'a' ) ( 'I' | 'i' ) ( 'N' | 'n' ) ( 'T' | 't' ) ; + +DO : ( 'D' | 'd' ) ( 'O' | 'o' ) ; + +FOR : ( 'F' | 'f' ) ( 'O' | 'o' ) ( 'R' | 'r' ) ; + +REQUIRE : ( 'R' | 'r' ) ( 'E' | 'e' ) ( 'Q' | 'q' ) ( 'U' | 'u' ) ( 'I' | 'i' ) ( 'R' | 'r' ) ( 'E' | 'e' ) ; + +UNIQUE : ( 'U' | 'u' ) ( 'N' | 'n' ) ( 'I' | 'i' ) ( 'Q' | 'q' ) ( 'U' | 'u' ) ( 'E' | 'e' ) ; + +MANDATORY : ( 'M' | 'm' ) ( 'A' | 'a' ) ( 'N' | 'n' ) ( 'D' | 'd' ) ( 'A' | 'a' ) ( 'T' | 't' ) ( 'O' | 'o' ) ( 'R' | 'r' ) ( 'Y' | 'y' ) ; + +SCALAR : ( 'S' | 's' ) ( 'C' | 'c' ) ( 'A' | 'a' ) ( 'L' | 'l' ) ( 'A' | 'a' ) ( 'R' | 'r' ) ; + +OF : ( 'O' | 'o' ) ( 'F' | 'f' ) ; + +ADD : ( 'A' | 'a' ) ( 'D' | 'd' ) ( 'D' | 'd' ) ; + +DROP : ( 'D' | 'd' ) ( 'R' | 'r' ) ( 'O' | 'o' ) ( 'P' | 'p' ) ; + +oC_SymbolicName + : UnescapedSymbolicName + | EscapedSymbolicName + | HexLetter + | COUNT + | FILTER + | EXTRACT + | ANY + | NONE + | SINGLE + ; + +FILTER : ( 'F' | 'f' ) ( 'I' | 'i' ) ( 'L' | 'l' ) ( 'T' | 't' ) ( 'E' | 'e' ) ( 'R' | 'r' ) ; + +EXTRACT : ( 'E' | 'e' ) ( 'X' | 'x' ) ( 'T' | 't' ) ( 'R' | 'r' ) ( 'A' | 'a' ) ( 'C' | 'c' ) ( 'T' | 't' ) ; + +UnescapedSymbolicName + : IdentifierStart ( IdentifierPart )* ; + +/** + * Based on the unicode identifier and pattern syntax + * (http://www.unicode.org/reports/tr31/) + * And extended with a few characters. + */ +IdentifierStart + : ID_Start + | Pc + ; + +/** + * Based on the unicode identifier and pattern syntax + * (http://www.unicode.org/reports/tr31/) + * And extended with a few characters. + */ +IdentifierPart + : ID_Continue + | Sc + ; + +/** + * Any character except "`", enclosed within `backticks`. Backticks are escaped with double backticks. + */ +EscapedSymbolicName + : ( '`' ( EscapedSymbolicName_0 )* '`' )+ ; + +SP + : ( WHITESPACE )+ ; + +WHITESPACE + : SPACE + | TAB + | LF + | VT + | FF + | CR + | FS + | GS + | RS + | US + | '\u1680' + | '\u180e' + | '\u2000' + | '\u2001' + | '\u2002' + | '\u2003' + | '\u2004' + | '\u2005' + | '\u2006' + | '\u2008' + | '\u2009' + | '\u200a' + | '\u2028' + | '\u2029' + | '\u205f' + | '\u3000' + | '\u00a0' + | '\u2007' + | '\u202f' + | Comment + ; + +Comment + : ( '/*' ( Comment_1 | ( '*' Comment_2 ) )* '*/' ) + | ( '//' ( Comment_3 )* CR? ( LF | EOF ) ) + ; + +oC_LeftArrowHead + : '<' + | '\u27e8' + | '\u3008' + | '\ufe64' + | '\uff1c' + ; + +oC_RightArrowHead + : '>' + | '\u27e9' + | '\u3009' + | '\ufe65' + | '\uff1e' + ; + +oC_Dash + : '-' + | '\u00ad' + | '\u2010' + | '\u2011' + | '\u2012' + | '\u2013' + | '\u2014' + | '\u2015' + | '\u2212' + | '\ufe58' + | '\ufe63' + | '\uff0d' + ; + +fragment FF : [\f] ; + +fragment EscapedSymbolicName_0 : ~[`] ; + +fragment RS : [\u001E] ; + +fragment ID_Continue : [\p{ID_Continue}] ; + +fragment Comment_1 : ~[*] ; + +fragment StringLiteral_1 : ~['\\] ; + +fragment Comment_3 : ~[\n\r] ; + +fragment Comment_2 : ~[/] ; + +fragment GS : [\u001D] ; + +fragment FS : [\u001C] ; + +fragment CR : [\r] ; + +fragment Sc : [\p{Sc}] ; + +fragment SPACE : [ ] ; + +fragment Pc : [\p{Pc}] ; + +fragment TAB : [\t] ; + +fragment StringLiteral_0 : ~["\\] ; + +fragment LF : [\n] ; + +fragment VT : [\u000B] ; + +fragment US : [\u001F] ; + +fragment ID_Start : [\p{ID_Start}] ; + diff --git a/arithmeticeval.go b/arithmeticeval.go new file mode 100644 index 0000000..8414a45 --- /dev/null +++ b/arithmeticeval.go @@ -0,0 +1,470 @@ +package opencypher + +import ( + "math" + "time" + + "github.com/neo4j/neo4j-go-driver/neo4j" +) + +func (expr *UnaryAddOrSubtractExpression) Evaluate(ctx *EvalContext) (Value, error) { + if expr.constValue != nil { + return *expr.constValue, nil + } + + value, err := expr.Expr.Evaluate(ctx) + if err != nil { + return value, err + } + if value.Value == nil { + return value, nil + } + if expr.Neg { + if intValue, ok := value.Value.(int); ok { + value.Value = -intValue + } else if floatValue, ok := value.Value.(float64); ok { + value.Value = -floatValue + } else { + return value, ErrInvalidUnaryOperation + } + } + if value.Constant { + expr.constValue = &value + } + return value, nil +} + +func (expr *PowerOfExpression) Evaluate(ctx *EvalContext) (Value, error) { + if expr.constValue != nil { + return *expr.constValue, nil + } + var ret Value + for i := range expr.Parts { + val, err := expr.Parts[i].Evaluate(ctx) + if err != nil { + return val, err + } + if val.Value == nil { + return Value{}, nil + } + if i == 0 { + ret = val + } else { + var valValue float64 + if intValue, ok := val.Value.(int); ok { + valValue = float64(intValue) + } else if floatValue, ok := val.Value.(float64); ok { + valValue = floatValue + } else { + return Value{}, ErrInvalidPowerOperation + } + if i, ok := ret.Value.(int); ok { + ret.Value = math.Pow(float64(i), valValue) + } else if f, ok := ret.Value.(float64); ok { + ret.Value = math.Pow(f, valValue) + } else { + return Value{}, ErrInvalidPowerOperation + } + ret.Constant = ret.Constant && val.Constant + } + } + if ret.Constant { + expr.constValue = &ret + } + return ret, nil +} + +func mulintint(a, b int, op rune) (int, error) { + switch op { + case '*': + return a * b, nil + case '/': + if b == 0 { + return 0, ErrDivideByZero + } + return a / b, nil + } + if b == 0 { + return 0, ErrDivideByZero + } + return a % b, nil +} + +func mulintfloat(a int, b float64, op rune) (float64, error) { + switch op { + case '*': + return float64(a) * b, nil + case '/': + if b == 0 { + return 0, ErrDivideByZero + } + return float64(a) / b, nil + } + if b == 0 { + return 0, ErrDivideByZero + } + return math.Mod(float64(a), b), nil +} + +func mulfloatint(a float64, b int, op rune) (float64, error) { + switch op { + case '*': + return a * float64(b), nil + case '/': + if b == 0 { + return 0, ErrDivideByZero + } + return a / float64(b), nil + } + if b == 0 { + return 0, ErrDivideByZero + } + return math.Mod(a, float64(b)), nil +} + +func mulfloatfloat(a, b float64, op rune) (float64, error) { + switch op { + case '*': + return a * b, nil + case '/': + if b == 0 { + return 0, ErrDivideByZero + } + return a / b, nil + } + if b == 0 { + return 0, ErrDivideByZero + } + return math.Mod(a, b), nil +} + +func muldurint(a neo4j.Duration, b int64, op rune) (neo4j.Duration, error) { + switch op { + case '*': + return neo4j.DurationOf(a.Months()*b, a.Days()*b, a.Seconds()*b, a.Nanos()*int(b)), nil + case '/': + if b == 0 { + return neo4j.Duration{}, ErrDivideByZero + } + return neo4j.DurationOf(a.Months()/b, a.Days()/b, a.Seconds()/b, a.Nanos()/int(b)), nil + } + return neo4j.Duration{}, ErrInvalidDurationOperation +} + +func mulintdur(a int64, b neo4j.Duration, op rune) (neo4j.Duration, error) { + switch op { + case '*': + return neo4j.DurationOf(b.Months()*a, b.Days()*a, b.Seconds()*a, b.Nanos()*int(a)), nil + default: + return neo4j.Duration{}, ErrInvalidDurationOperation + } +} + +func muldurfloat(a neo4j.Duration, b float64, op rune) (neo4j.Duration, error) { + val := int64(b) + switch op { + case '*': + return neo4j.DurationOf(int64(a.Months()*val), int64(a.Days()*val), int64(a.Seconds()*val), a.Nanos()*int(val)), nil + case '/': + if b == 0 { + return neo4j.Duration{}, ErrDivideByZero + } + return neo4j.DurationOf(int64(a.Months()/val), int64(a.Days()/val), int64(a.Seconds()/val), a.Nanos()/int(val)), nil + } + return neo4j.Duration{}, ErrInvalidDurationOperation +} + +func mulfloatdur(a float64, b neo4j.Duration, op rune) (neo4j.Duration, error) { + val := int64(a) + switch op { + case '*': + return neo4j.DurationOf(b.Months()*val, b.Days()*val, b.Seconds()*val, b.Nanos()*int(val)), nil + default: + return neo4j.Duration{}, ErrInvalidDurationOperation + } +} + +func (expr *MultiplyDivideModuloExpression) Evaluate(ctx *EvalContext) (Value, error) { + if expr.constValue != nil { + return *expr.constValue, nil + } + + var ret Value + var err error + for i := range expr.Parts { + var val Value + val, err = expr.Parts[i].Expr.Evaluate(ctx) + if err != nil { + return val, err + } + if i == 0 { + ret = val + } else { + if ret.Value == nil { + return Value{}, nil + } + ret.Constant = ret.Constant && val.Constant + switch result := ret.Value.(type) { + case int: + switch operand := val.Value.(type) { + case int: + ret.Value, err = mulintint(result, operand, expr.Parts[i].Op) + case float64: + ret.Value, err = mulintfloat(result, operand, expr.Parts[i].Op) + case neo4j.Duration: + ret.Value, err = mulintdur(int64(result), operand, expr.Parts[i].Op) + default: + err = ErrInvalidMultiplicativeOperation + } + case float64: + switch operand := val.Value.(type) { + case int: + ret.Value, err = mulfloatint(result, operand, expr.Parts[i].Op) + case float64: + ret.Value, err = mulfloatfloat(result, operand, expr.Parts[i].Op) + case neo4j.Duration: + ret.Value, err = mulfloatdur(result, operand, expr.Parts[i].Op) + default: + err = ErrInvalidMultiplicativeOperation + } + case neo4j.Duration: + switch operand := val.Value.(type) { + case int: + ret.Value, err = muldurint(result, int64(operand), expr.Parts[i].Op) + case float64: + ret.Value, err = muldurfloat(result, operand, expr.Parts[i].Op) + default: + err = ErrInvalidMultiplicativeOperation + } + default: + err = ErrInvalidMultiplicativeOperation + } + } + } + if err != nil { + return Value{}, err + } + if ret.Constant { + expr.constValue = &ret + } + return ret, nil +} + +func addintint(a int, b int, sub bool) int { + if sub { + return a - b + } + return a + b +} + +func addintfloat(a int, b float64, sub bool) float64 { + if sub { + return float64(a) - b + } + return float64(a) + b +} + +func addfloatint(a float64, b int, sub bool) float64 { + if sub { + return a - float64(b) + } + return a + float64(b) +} + +func addfloatfloat(a float64, b float64, sub bool) float64 { + if sub { + return a - b + } + return a + b +} + +func addstringstring(a string, b string, sub bool) (string, error) { + if sub { + return "", ErrInvalidStringOperation + } + return a + b, nil +} + +func adddatedur(a neo4j.Date, b neo4j.Duration, sub bool) neo4j.Date { + t := a.Time() + if sub { + return neo4j.DateOf(time.Date(t.Year(), t.Month()-time.Month(b.Months()), t.Day()-int(b.Days()), 0, 0, 0, 0, t.Location())) + } + return neo4j.DateOf(time.Date(t.Year(), t.Month()+time.Month(b.Months()), t.Day()+int(b.Days()), 0, 0, 0, 0, t.Location())) +} + +func addtimedur(a neo4j.LocalTime, b neo4j.Duration, sub bool) neo4j.LocalTime { + t := a.Time() + if sub { + return neo4j.LocalTimeOf(time.Date(1970, 1, 1, t.Hour(), t.Minute(), t.Second()-int(b.Seconds()), t.Nanosecond()-b.Nanos(), t.Location())) + } + return neo4j.LocalTimeOf(time.Date(1970, 1, 1, t.Hour(), t.Minute(), t.Second()+int(b.Seconds()), t.Nanosecond()+b.Nanos(), t.Location())) +} + +func adddatetimedur(a neo4j.LocalDateTime, b neo4j.Duration, sub bool) neo4j.LocalDateTime { + t := a.Time() + if sub { + return neo4j.LocalDateTimeOf(time.Date(t.Year(), t.Month()-time.Month(b.Months()), t.Day()-int(b.Days()), t.Hour(), t.Minute(), t.Second()-int(b.Seconds()), t.Nanosecond()-b.Nanos(), t.Location())) + } + return neo4j.LocalDateTimeOf(time.Date(t.Year(), t.Month()+time.Month(b.Months()), t.Day()+int(b.Days()), t.Hour(), t.Minute(), t.Second()+int(b.Seconds()), t.Nanosecond()+b.Nanos(), t.Location())) +} + +func adddurdate(a neo4j.Duration, b neo4j.Date, sub bool) (neo4j.Date, error) { + if sub { + return neo4j.Date{}, ErrInvalidDateOperation + } + return adddatedur(b, a, false), nil +} + +func adddurtime(a neo4j.Duration, b neo4j.LocalTime, sub bool) (neo4j.LocalTime, error) { + if sub { + return neo4j.LocalTime{}, ErrInvalidDateOperation + } + return addtimedur(b, a, false), nil +} + +func adddurdatetime(a neo4j.Duration, b neo4j.LocalDateTime, sub bool) (neo4j.LocalDateTime, error) { + if sub { + return neo4j.LocalDateTime{}, ErrInvalidDateOperation + } + return adddatetimedur(b, a, false), nil +} + +func adddurdur(a neo4j.Duration, b neo4j.Duration, sub bool) (neo4j.Duration, error) { + if sub { + return neo4j.DurationOf(a.Months()-b.Months(), a.Days()-b.Days(), a.Seconds()-b.Seconds(), a.Nanos()-b.Nanos()), nil + } + return neo4j.DurationOf(a.Months()+b.Months(), a.Days()+b.Days(), a.Seconds()+b.Seconds(), a.Nanos()+b.Nanos()), nil +} + +func addlistlist(a, b []Value) Value { + arr := make([]Value, 0, len(a)+len(b)) + ret := Value{Constant: true} + for _, x := range a { + if !x.Constant { + ret.Constant = false + } + arr = append(arr, x) + } + for _, x := range b { + if !x.Constant { + ret.Constant = false + } + arr = append(arr, x) + } + return ret +} + +func (expr *AddOrSubtractExpression) Evaluate(ctx *EvalContext) (Value, error) { + if expr.constValue != nil { + return *expr.constValue, nil + } + + var ret Value + first := true + + accumulate := func(operand Value, sub bool) error { + if first { + first = false + ret = operand + return nil + } + ret.Constant = ret.Constant && operand.Constant + var err error + switch retValue := ret.Value.(type) { + case int: + switch operandValue := operand.Value.(type) { + case int: + ret.Value = addintint(retValue, operandValue, sub) + case float64: + ret.Value = addintfloat(retValue, operandValue, sub) + default: + err = ErrInvalidAdditiveOperation + } + case float64: + switch operandValue := operand.Value.(type) { + case int: + ret.Value = addfloatint(retValue, operandValue, sub) + case float64: + ret.Value = addfloatfloat(retValue, operandValue, sub) + default: + err = ErrInvalidAdditiveOperation + } + case string: + switch operandValue := operand.Value.(type) { + case string: + ret.Value, err = addstringstring(retValue, operandValue, sub) + default: + err = ErrInvalidAdditiveOperation + } + case neo4j.Duration: + switch operandValue := operand.Value.(type) { + case neo4j.Duration: + ret.Value, err = adddurdur(retValue, operandValue, sub) + case neo4j.Date: + ret.Value, err = adddurdate(retValue, operandValue, sub) + case neo4j.LocalTime: + ret.Value, err = adddurtime(retValue, operandValue, sub) + case neo4j.LocalDateTime: + ret.Value, err = adddurdatetime(retValue, operandValue, sub) + default: + err = ErrInvalidAdditiveOperation + } + case neo4j.Date: + switch operandValue := operand.Value.(type) { + case neo4j.Duration: + ret.Value = adddatedur(retValue, operandValue, sub) + default: + err = ErrInvalidAdditiveOperation + } + case neo4j.LocalTime: + switch operandValue := operand.Value.(type) { + case neo4j.Duration: + ret.Value = addtimedur(retValue, operandValue, sub) + default: + err = ErrInvalidAdditiveOperation + } + case neo4j.LocalDateTime: + switch operandValue := operand.Value.(type) { + case neo4j.Duration: + ret.Value = adddatetimedur(retValue, operandValue, sub) + default: + err = ErrInvalidAdditiveOperation + } + case []Value: + if sub { + return ErrInvalidAdditiveOperation + } + switch operandValue := operand.Value.(type) { + case []Value: + ret = addlistlist(retValue, operandValue) + default: + err = ErrInvalidAdditiveOperation + } + } + return err + } + + for i := range expr.Add { + val, err := expr.Add[i].Evaluate(ctx) + if err != nil { + return Value{}, err + } + if err = accumulate(val, false); err != nil { + return Value{}, err + } + } + for i := range expr.Sub { + val, err := expr.Add[i].Evaluate(ctx) + if err != nil { + return Value{}, err + } + if err = accumulate(val, true); err != nil { + return Value{}, err + } + } + if ret.Constant { + expr.constValue = &ret + } + return ret, nil +} diff --git a/ast.go b/ast.go new file mode 100644 index 0000000..77172ab --- /dev/null +++ b/ast.go @@ -0,0 +1,1249 @@ +package opencypher + +import ( + "strconv" + "strings" + + "github.com/antlr/antlr4/runtime/Go/antlr" + "github.com/cloudprivacylabs/opencypher/parser" +) + +type Evaluatable interface { + Evaluate(*EvalContext) (Value, error) +} + +type RegularQuery struct { + SingleQuery Evaluatable + Unions []Union +} + +type Union struct { + All bool + SingleQuery Evaluatable +} + +type SinglePartQuery struct { + Read []ReadingClause + Update []UpdatingClause + Return *ReturnClause +} + +type MultiPartQueryPart struct { + Read []ReadingClause + Update []UpdatingClause + With WithClause +} + +type WithClause struct { + Projection ProjectionBody + Where Expression +} + +type MultiPartQuery struct { + Parts []MultiPartQueryPart + SingleQuery SinglePartQuery +} + +type ReadingClause interface { + GetResults(*EvalContext) (ResultSet, error) +} + +type UpdatingClause interface { + Evaluatable +} + +type Expression interface { + Evaluatable +} + +type Unwind struct { + Expr Expression + As Variable +} + +type OrExpression struct { + Parts []Evaluatable +} +type XorExpression struct { + Parts []Evaluatable +} +type AndExpression struct { + Parts []Evaluatable +} + +type NotExpression struct { + Part ComparisonExpression +} +type ComparisonExpression struct { + First Expression + Second []PartialComparisonExpression +} + +type PartialComparisonExpression struct { + Op string + Expr AddOrSubtractExpression +} + +type AddOrSubtractExpression struct { + Add []MultiplyDivideModuloExpression + Sub []MultiplyDivideModuloExpression + + constValue *Value +} + +type MultiplyDivideModuloExpression struct { + Parts []MultiplyDivideModuloExpressionPart + + constValue *Value +} + +type MultiplyDivideModuloExpressionPart struct { + // For the first element of parts, Op=0 + Op rune + Expr PowerOfExpression +} + +type PowerOfExpression struct { + Parts []UnaryAddOrSubtractExpression + + constValue *Value +} + +type UnaryAddOrSubtractExpression struct { + Neg bool + Expr StringListNullOperatorExpression + + constValue *Value +} + +type StringListNullOperatorExpression struct { + PropertyOrLabels PropertyOrLabelsExpression + Parts []StringListNullOperatorExpressionPart +} + +type StringListNullOperatorExpressionPart struct { + String *StringOperatorExpression + ListIn Expression + ListIndex Expression + ListRange *ListRangeExpression + IsNull *bool +} + +type ListRangeExpression struct { + First Expression + Second Expression +} + +type StringOperatorExpression struct { + Operator string + Expr Expression +} + +type PropertyOrLabelsExpression struct { + Atom Atom + PropertyLookup []SchemaName + NodeLabels *NodeLabels +} + +type RelationshipTypes struct { + Rel []SchemaName +} + +type ReturnClause struct { + Projection ProjectionBody +} + +type ProjectionBody struct { + Distinct bool + Items ProjectionItems + Order *Order + Skip Expression + Limit Expression +} + +type ProjectionItems struct { + All bool + Items []ProjectionItem +} + +type ProjectionItem struct { + Var *Variable + Expr Expression +} + +type Order struct { + Items []SortItem +} + +type SortItem struct { + Asc bool + Expr Expression +} + +type SchemaName struct { + *SymbolicName + *ReservedWord +} + +func (s SchemaName) String() string { + if s.SymbolicName != nil { + return string(*s.SymbolicName) + } + if s.ReservedWord != nil { + return string(*s.ReservedWord) + } + return "" +} + +// oC_Match +// : ( OPTIONAL SP )? MATCH SP? oC_Pattern ( SP? oC_Where )? ; + +type Match struct { + Optional bool + Pattern Pattern + Where Expression +} +type NodeLabels []SchemaName + +type SymbolicName string +type ReservedWord string + +type Variable SymbolicName + +type Pattern struct { + Parts []PatternPart +} + +type PatternPart struct { + Var *Variable + Start NodePattern + Path []PatternChain +} + +type NodePattern struct { + Var *Variable + Labels *NodeLabels + Properties *Properties +} + +type PatternChain struct { + Rel RelationshipPattern + Node NodePattern +} + +type RelationshipPattern struct { + Backwards bool + Var *Variable + RelTypes *RelationshipTypes + Range *RangeLiteral + Properties *Properties +} + +type Parameter string + +type Properties struct { + Map *MapLiteral + Param *Parameter +} + +type CountAtom struct{} + +type FilterAtom struct { + Op string + Filter FilterExpression +} + +type Atom interface { + Evaluatable +} + +type FilterExpression struct { + Variable Variable + InExpr Expression + Where Expression +} + +type Filter struct { + // TODO: Derived from filter expression +} + +type RelationshipsPattern struct { + Start NodePattern + Chain []PatternChain +} + +type ListComprehension struct { + Filter FilterExpression + Expr Expression +} + +type FunctionInvocation struct { + Name []SymbolicName + Distinct bool + Args []Expression + + function Function + args []Evaluatable +} + +type PatternComprehension struct { + Var *Variable + Rel RelationshipsPattern + Where Expression + Expr Expression +} + +type Case struct { + Test Expression + Alternatives []CaseAlternative + Default Expression +} + +type CaseAlternative struct { + When Expression + Then Expression +} + +type NullLiteral struct{} +type StringLiteral string +type DoubleLiteral float64 +type IntLiteral int +type BooleanLiteral bool + +type RangeLiteral struct { + From, To *IntLiteral +} + +type ListLiteral struct { + Values []Expression + + constValue *Value +} + +type MapLiteral struct { + KeyValues []MapKeyValue + + constValue *Value +} + +type MapKeyValue struct { + Key string + Value Expression +} + +func oC_Cypher(ctx *parser.OC_CypherContext) Evaluatable { + return oC_Statement(ctx.OC_Statement().(*parser.OC_StatementContext)) +} + +func oC_Statement(ctx *parser.OC_StatementContext) Evaluatable { + return oC_Query(ctx.OC_Query().(*parser.OC_QueryContext)) +} + +func oC_Query(ctx *parser.OC_QueryContext) Evaluatable { + if x := ctx.OC_RegularQuery(); x != nil { + return oC_RegularQuery(x.(*parser.OC_RegularQueryContext)) + } + return oC_StandaloneCall(ctx.OC_StandaloneCall().(*parser.OC_StandaloneCallContext)) +} + +func oC_RegularQuery(ctx *parser.OC_RegularQueryContext) RegularQuery { + ret := RegularQuery{ + SingleQuery: oC_SingleQuery(ctx.OC_SingleQuery().(*parser.OC_SingleQueryContext)), + } + for _, u := range ctx.AllOC_Union() { + ret.Unions = append(ret.Unions, oC_Union(u.(*parser.OC_UnionContext))) + } + return ret +} + +func oC_Union(ctx *parser.OC_UnionContext) Union { + return Union{ + All: ctx.ALL() != nil, + SingleQuery: oC_SingleQuery(ctx.OC_SingleQuery().(*parser.OC_SingleQueryContext)), + } +} + +func oC_SingleQuery(ctx *parser.OC_SingleQueryContext) Evaluatable { + if x := ctx.OC_SinglePartQuery(); x != nil { + return oC_SinglePartQuery(x.(*parser.OC_SinglePartQueryContext)) + } + return oC_MultiPartQuery(ctx.OC_MultiPartQuery().(*parser.OC_MultiPartQueryContext)) +} + +func oC_SinglePartQuery(ctx *parser.OC_SinglePartQueryContext) SinglePartQuery { + ret := SinglePartQuery{} + for _, r := range ctx.AllOC_ReadingClause() { + ret.Read = append(ret.Read, oC_ReadingClause(r.(*parser.OC_ReadingClauseContext))) + } + for _, u := range ctx.AllOC_UpdatingClause() { + ret.Update = append(ret.Update, oC_UpdatingClause(u.(*parser.OC_UpdatingClauseContext))) + } + if x := ctx.OC_Return(); x != nil { + r := oC_Return(x.(*parser.OC_ReturnContext)) + ret.Return = &r + } + return ret +} + +//oC_MultiPartQuery +// : ( ( oC_ReadingClause SP? )* ( oC_UpdatingClause SP? )* oC_With SP? )+ oC_SinglePartQuery ; +func oC_MultiPartQuery(ctx *parser.OC_MultiPartQueryContext) MultiPartQuery { + ret := MultiPartQuery{Parts: []MultiPartQueryPart{}} + count := ctx.GetChildCount() + lastIsFull := true + for child := 0; child < count; child++ { + ch := ctx.GetChild(child) + lastPart := &ret.Parts[len(ret.Parts)-1] + switch expr := ch.(type) { + case *parser.OC_ReadingClauseContext: + lastPart.Read = append(lastPart.Read, oC_ReadingClause(expr)) + lastIsFull = true + case *parser.OC_UpdatingClauseContext: + lastPart.Update = append(lastPart.Update, oC_UpdatingClause(expr)) + lastIsFull = true + case *parser.OC_WithContext: + lastPart.With = oC_With(expr) + ret.Parts = append(ret.Parts, MultiPartQueryPart{}) + lastIsFull = false + case *parser.OC_SinglePartQueryContext: + ret.SingleQuery = oC_SinglePartQuery(expr) + } + } + if !lastIsFull { + ret.Parts = ret.Parts[:len(ret.Parts)-1] + } + return ret +} + +func oC_With(ctx *parser.OC_WithContext) WithClause { + ret := WithClause{ + Projection: oC_ProjectionBody(ctx.OC_ProjectionBody().(*parser.OC_ProjectionBodyContext)), + } + if w := ctx.OC_Where(); w != nil { + ret.Where = oC_Where(w.(*parser.OC_WhereContext)) + } + return ret +} + +func oC_ReadingClause(ctx *parser.OC_ReadingClauseContext) ReadingClause { + if match := ctx.OC_Match(); match != nil { + return oC_Match(match.(*parser.OC_MatchContext)) + } + if unwind := ctx.OC_Unwind(); unwind != nil { + return oC_Unwind(unwind.(*parser.OC_UnwindContext)) + } + return oC_InQueryCall(ctx.OC_InQueryCall().(*parser.OC_InQueryCallContext)) +} + +func oC_UpdatingClause(ctx *parser.OC_UpdatingClauseContext) UpdatingClause { + if create := ctx.OC_Create(); create != nil { + return oC_Create(create.(*parser.OC_CreateContext)) + } + if merge := ctx.OC_Merge(); merge != nil { + return oC_Merge(merge.(*parser.OC_MergeContext)) + } + if del := ctx.OC_Delete(); del != nil { + return oC_Delete(del.(*parser.OC_DeleteContext)) + } + if set := ctx.OC_Set(); set != nil { + return oC_Set(set.(*parser.OC_SetContext)) + } + return oC_Remove(ctx.OC_Remove().(*parser.OC_RemoveContext)) +} + +func oC_Return(ctx *parser.OC_ReturnContext) ReturnClause { + return ReturnClause{ + Projection: oC_ProjectionBody(ctx.OC_ProjectionBody().(*parser.OC_ProjectionBodyContext)), + } +} + +func oC_ProjectionBody(ctx *parser.OC_ProjectionBodyContext) ProjectionBody { + ret := ProjectionBody{ + Distinct: ctx.DISTINCT() != nil, + Items: oC_ProjectionItems(ctx.OC_ProjectionItems().(*parser.OC_ProjectionItemsContext)), + } + if o := ctx.OC_Order(); o != nil { + x := oC_Order(o.(*parser.OC_OrderContext)) + ret.Order = &x + } + if s := ctx.OC_Skip(); s != nil { + ret.Skip = oC_Skip(s.(*parser.OC_SkipContext)) + } + if l := ctx.OC_Limit(); l != nil { + ret.Limit = oC_Limit(l.(*parser.OC_LimitContext)) + } + return ret +} + +func oC_ProjectionItems(ctx *parser.OC_ProjectionItemsContext) ProjectionItems { + ret := ProjectionItems{} + if item, ok := ctx.GetChild(0).(antlr.TerminalNode); ok { + if item.GetText() == "*" { + ret.All = true + } + } + for _, x := range ctx.AllOC_ProjectionItem() { + ret.Items = append(ret.Items, oC_ProjectionItem(x.(*parser.OC_ProjectionItemContext))) + } + return ret +} + +func oC_ProjectionItem(ctx *parser.OC_ProjectionItemContext) ProjectionItem { + ret := ProjectionItem{ + Expr: oC_Expression(ctx.OC_Expression().(*parser.OC_ExpressionContext)), + } + if v := ctx.OC_Variable(); v != nil { + x := oC_Variable(v.(*parser.OC_VariableContext)) + ret.Var = &x + } + return ret +} + +func oC_Order(ctx *parser.OC_OrderContext) Order { + ret := Order{} + for _, x := range ctx.AllOC_SortItem() { + ret.Items = append(ret.Items, oC_SortItem(x.(*parser.OC_SortItemContext))) + } + return ret +} + +func oC_SortItem(ctx *parser.OC_SortItemContext) SortItem { + ret := SortItem{ + Expr: oC_Expression(ctx.OC_Expression().(*parser.OC_ExpressionContext)), + Asc: ctx.ASCENDING() != nil || ctx.ASC() != nil, + } + return ret +} + +func oC_Skip(ctx *parser.OC_SkipContext) Expression { + return oC_Expression(ctx.OC_Expression().(*parser.OC_ExpressionContext)) +} + +func oC_Limit(ctx *parser.OC_LimitContext) Expression { + return oC_Expression(ctx.OC_Expression().(*parser.OC_ExpressionContext)) +} + +func oC_Match(ctx *parser.OC_MatchContext) Match { + ret := Match{ + Optional: ctx.OPTIONAL() != nil, + Pattern: oC_Pattern(ctx.OC_Pattern().(*parser.OC_PatternContext)), + } + if w := ctx.OC_Where(); w != nil { + ret.Where = oC_Where(w.(*parser.OC_WhereContext)) + } + return ret +} + +func oC_Where(ctx *parser.OC_WhereContext) Expression { + return oC_Expression(ctx.OC_Expression().(*parser.OC_ExpressionContext)) +} + +func oC_Expression(ctx *parser.OC_ExpressionContext) Expression { + return oC_OrExpression(ctx.OC_OrExpression().(*parser.OC_OrExpressionContext)) +} + +func oC_OrExpression(ctx *parser.OC_OrExpressionContext) Expression { + ret := OrExpression{} + for _, x := range ctx.AllOC_XorExpression() { + ret.Parts = append(ret.Parts, oC_XorExpression(x.(*parser.OC_XorExpressionContext))) + } + return ret +} + +func oC_XorExpression(ctx *parser.OC_XorExpressionContext) Expression { + ret := XorExpression{} + for _, x := range ctx.AllOC_AndExpression() { + ret.Parts = append(ret.Parts, oC_AndExpression(x.(*parser.OC_AndExpressionContext))) + } + return ret +} + +func oC_AndExpression(ctx *parser.OC_AndExpressionContext) Expression { + ret := AndExpression{} + for _, x := range ctx.AllOC_NotExpression() { + ret.Parts = append(ret.Parts, oC_NotExpression(x.(*parser.OC_NotExpressionContext))) + } + return ret +} + +func oC_NotExpression(ctx *parser.OC_NotExpressionContext) Expression { + if len(ctx.AllNOT())%2 == 1 { + return NotExpression{ + Part: oC_ComparisonExpression(ctx.OC_ComparisonExpression().(*parser.OC_ComparisonExpressionContext)), + } + } + return oC_ComparisonExpression(ctx.OC_ComparisonExpression().(*parser.OC_ComparisonExpressionContext)) +} + +func oC_ComparisonExpression(ctx *parser.OC_ComparisonExpressionContext) ComparisonExpression { + ret := ComparisonExpression{ + First: oC_AddOrSubtractExpression(ctx.OC_AddOrSubtractExpression().(*parser.OC_AddOrSubtractExpressionContext)), + } + for _, x := range ctx.AllOC_PartialComparisonExpression() { + ret.Second = append(ret.Second, oC_PartialComparisonExpression(x.(*parser.OC_PartialComparisonExpressionContext))) + } + return ret +} + +// oC_AddOrSubtractExpression : +// oC_MultiplyDivideModuloExpression ( +// ( SP? '+' SP? oC_MultiplyDivideModuloExpression ) | +// ( SP? '-' SP? oC_MultiplyDivideModuloExpression ) +// )* +// +func oC_AddOrSubtractExpression(ctx *parser.OC_AddOrSubtractExpressionContext) *AddOrSubtractExpression { + ret := &AddOrSubtractExpression{} + target := &ret.Add + count := ctx.GetChildCount() + for child := 0; child < count; child++ { + ch := ctx.GetChild(child) + expr, ok := ch.(*parser.OC_MultiplyDivideModuloExpressionContext) + if ok { + (*target) = append(*target, oC_MultiplyDivideModuloExpression(expr)) + } else { + term, ok := ch.(antlr.TerminalNode) + if ok { + if term.GetText() == "+" { + target = &ret.Add + } else if term.GetText() == "-" { + target = &ret.Sub + } + } + } + } + return ret +} + +// oC_MultiplyDivideModuloExpression : +// oC_PowerOfExpression ( +// ( SP? '*' SP? oC_PowerOfExpression ) | +// ( SP? '/' SP? oC_PowerOfExpression ) | +// ( SP? '%' SP? oC_PowerOfExpression ) )* ; +func oC_MultiplyDivideModuloExpression(ctx *parser.OC_MultiplyDivideModuloExpressionContext) MultiplyDivideModuloExpression { + ret := MultiplyDivideModuloExpression{} + count := ctx.GetChildCount() + var lastOp rune + for child := 0; child < count; child++ { + ch := ctx.GetChild(child) + expr, ok := ch.(*parser.OC_PowerOfExpressionContext) + if ok { + ret.Parts = append(ret.Parts, MultiplyDivideModuloExpressionPart{ + Op: lastOp, + Expr: oC_PowerOfExpression(expr), + }) + } else { + term, ok := ch.(antlr.TerminalNode) + if ok { + t := term.GetText() + if t == "*" || t == "%" || t == "/" { + lastOp = rune(t[0]) + } + } + } + } + return ret +} + +// oC_PowerOfExpression : +// oC_UnaryAddOrSubtractExpression ( SP? '^' SP? oC_UnaryAddOrSubtractExpression )* ; +func oC_PowerOfExpression(ctx *parser.OC_PowerOfExpressionContext) PowerOfExpression { + ret := PowerOfExpression{} + for _, x := range ctx.AllOC_UnaryAddOrSubtractExpression() { + ret.Parts = append(ret.Parts, oC_UnaryAddOrSubtractExpression(x.(*parser.OC_UnaryAddOrSubtractExpressionContext))) + } + return ret +} + +func oC_UnaryAddOrSubtractExpression(ctx *parser.OC_UnaryAddOrSubtractExpressionContext) UnaryAddOrSubtractExpression { + ret := UnaryAddOrSubtractExpression{} + for child := 0; child < ctx.GetChildCount(); child++ { + ch := ctx.GetChild(child) + if tok, ok := ch.(antlr.TerminalNode); ok { + if tok.GetText() == "-" { + ret.Neg = !ret.Neg + } + } else if expr, ok := ch.(*parser.OC_StringListNullOperatorExpressionContext); ok { + ret.Expr = oC_StringListNullOperatorExpression(expr) + } + } + return ret +} + +func oC_StringListNullOperatorExpression(ctx *parser.OC_StringListNullOperatorExpressionContext) StringListNullOperatorExpression { + var ret StringListNullOperatorExpression + for child := 0; child < ctx.GetChildCount(); child++ { + switch t := ctx.GetChild(child).(type) { + case *parser.OC_PropertyOrLabelsExpressionContext: + ret.PropertyOrLabels = oC_PropertyOrLabelsExpression(t) + case *parser.OC_StringOperatorExpressionContext: + ret.Parts = append(ret.Parts, oC_StringOperatorExpression(t)) + case *parser.OC_ListOperatorExpressionContext: + ret.Parts = append(ret.Parts, oC_ListOperatorExpression(t)) + case *parser.OC_NullOperatorExpressionContext: + ret.Parts = append(ret.Parts, oC_NullOperatorExpression(t)) + } + } + return ret +} + +func oC_ListOperatorExpression(ctx *parser.OC_ListOperatorExpressionContext) StringListNullOperatorExpressionPart { + if x := ctx.OC_PropertyOrLabelsExpression(); x != nil { + return StringListNullOperatorExpressionPart{ + ListIn: oC_PropertyOrLabelsExpression(x.(*parser.OC_PropertyOrLabelsExpressionContext)), + } + } + expr := ctx.AllOC_Expression() + if len(expr) == 1 { + return StringListNullOperatorExpressionPart{ + ListIndex: oC_Expression(expr[0].(*parser.OC_ExpressionContext)), + } + } + return StringListNullOperatorExpressionPart{ + ListRange: &ListRangeExpression{ + First: oC_Expression(expr[0].(*parser.OC_ExpressionContext)), + Second: oC_Expression(expr[1].(*parser.OC_ExpressionContext)), + }} +} + +func oC_StringOperatorExpression(ctx *parser.OC_StringOperatorExpressionContext) StringListNullOperatorExpressionPart { + ret := StringListNullOperatorExpressionPart{ + String: &StringOperatorExpression{ + Expr: oC_PropertyOrLabelsExpression(ctx.OC_PropertyOrLabelsExpression().(*parser.OC_PropertyOrLabelsExpressionContext)), + }, + } + if ctx.STARTS() != nil { + ret.String.Operator = "STARTS" + } + if ctx.ENDS() != nil { + ret.String.Operator = "ENDS" + } + if ctx.CONTAINS() != nil { + ret.String.Operator = "CONTAINS" + } + return ret +} + +func oC_NullOperatorExpression(ctx *parser.OC_NullOperatorExpressionContext) StringListNullOperatorExpressionPart { + val := ctx.NOT() == nil + return StringListNullOperatorExpressionPart{ + IsNull: &val, + } +} + +func oC_PropertyOrLabelsExpression(ctx *parser.OC_PropertyOrLabelsExpressionContext) PropertyOrLabelsExpression { + ret := PropertyOrLabelsExpression{ + Atom: oC_Atom(ctx.OC_Atom().(*parser.OC_AtomContext)), + } + for _, x := range ctx.AllOC_PropertyLookup() { + ret.PropertyLookup = append(ret.PropertyLookup, oC_PropertyLookup(x.(*parser.OC_PropertyLookupContext))) + } + if l := ctx.OC_NodeLabels(); l != nil { + x := oC_NodeLabels(l.(*parser.OC_NodeLabelsContext)) + ret.NodeLabels = &x + } + return ret +} + +func oC_PartialComparisonExpression(ctx *parser.OC_PartialComparisonExpressionContext) PartialComparisonExpression { + ret := PartialComparisonExpression{Expr: *oC_AddOrSubtractExpression(ctx.OC_AddOrSubtractExpression().(*parser.OC_AddOrSubtractExpressionContext))} + for i := 0; i < ctx.GetChildCount(); i++ { + if tok, ok := ctx.GetChild(i).(antlr.TerminalNode); ok { + t := tok.GetText() + if t == "=" || t == "<>" || t == "<" || t == ">" || t == "<=" || t == "=>" { + ret.Op = t + } + } + } + return ret +} + +func oC_PropertyLookup(ctx *parser.OC_PropertyLookupContext) SchemaName { + return oC_PropertyKeyName(ctx.OC_PropertyKeyName().(*parser.OC_PropertyKeyNameContext)) +} + +func oC_PropertyKeyName(ctx *parser.OC_PropertyKeyNameContext) SchemaName { + return oC_SchemaName(ctx.OC_SchemaName().(*parser.OC_SchemaNameContext)) +} + +func oC_SchemaName(ctx *parser.OC_SchemaNameContext) SchemaName { + if x := ctx.OC_SymbolicName(); x != nil { + name := oC_SymbolicName(ctx.OC_SymbolicName().(*parser.OC_SymbolicNameContext)) + return SchemaName{SymbolicName: &name} + } + name := oC_ReservedWord(ctx.OC_ReservedWord().(*parser.OC_ReservedWordContext)) + return SchemaName{ReservedWord: &name} +} + +func oC_SymbolicName(ctx *parser.OC_SymbolicNameContext) SymbolicName { + if node := ctx.EscapedSymbolicName(); node != nil { + text := node.GetText() + return SymbolicName(text[1 : len(text)-1]) + } + return SymbolicName(ctx.GetText()) +} + +func oC_ReservedWord(ctx *parser.OC_ReservedWordContext) ReservedWord { + return ReservedWord(strings.ToUpper(ctx.GetText())) +} + +func oC_NodeLabels(ctx *parser.OC_NodeLabelsContext) NodeLabels { + children := ctx.AllOC_NodeLabel() + ret := make([]SchemaName, 0, len(children)) + for _, x := range children { + ret = append(ret, oC_SchemaName(x.(*parser.OC_NodeLabelContext).OC_LabelName().(*parser.OC_LabelNameContext).OC_SchemaName().(*parser.OC_SchemaNameContext))) + } + return ret +} + +func oC_Pattern(ctx *parser.OC_PatternContext) Pattern { + ret := Pattern{} + for _, x := range ctx.AllOC_PatternPart() { + ret.Parts = append(ret.Parts, oC_PatternPart(x.(*parser.OC_PatternPartContext))) + } + return ret +} + +func oC_PatternPart(ctx *parser.OC_PatternPartContext) PatternPart { + ret := PatternPart{} + if v := ctx.OC_Variable(); v != nil { + vr := oC_Variable(v.(*parser.OC_VariableContext)) + ret.Var = &vr + } + ret.Start, ret.Path = oC_AnonymousPatternPart(ctx.OC_AnonymousPatternPart().(*parser.OC_AnonymousPatternPartContext)) + return ret +} + +func oC_AnonymousPatternPart(ctx *parser.OC_AnonymousPatternPartContext) (NodePattern, []PatternChain) { + return oC_PatternElement(ctx.OC_PatternElement().(*parser.OC_PatternElementContext)) +} + +func oC_PatternElement(ctx *parser.OC_PatternElementContext) (NodePattern, []PatternChain) { + if p := ctx.OC_PatternElement(); p != nil { + return oC_PatternElement(p.(*parser.OC_PatternElementContext)) + } + np := oC_NodePattern(ctx.OC_NodePattern().(*parser.OC_NodePatternContext)) + chain := make([]PatternChain, 0) + for _, x := range ctx.AllOC_PatternElementChain() { + chain = append(chain, oC_PatternElementChain(x.(*parser.OC_PatternElementChainContext))) + } + return np, chain +} + +func oC_NodePattern(ctx *parser.OC_NodePatternContext) NodePattern { + ret := NodePattern{} + if x := ctx.OC_Variable(); x != nil { + v := oC_Variable(x.(*parser.OC_VariableContext)) + ret.Var = &v + } + if x := ctx.OC_NodeLabels(); x != nil { + l := oC_NodeLabels(x.(*parser.OC_NodeLabelsContext)) + ret.Labels = &l + } + if x := ctx.OC_Properties(); x != nil { + o := oC_Properties(x.(*parser.OC_PropertiesContext)) + ret.Properties = &o + } + return ret +} + +func oC_PatternElementChain(ctx *parser.OC_PatternElementChainContext) PatternChain { + return PatternChain{ + Rel: oC_RelationshipPattern(ctx.OC_RelationshipPattern().(*parser.OC_RelationshipPatternContext)), + Node: oC_NodePattern(ctx.OC_NodePattern().(*parser.OC_NodePatternContext)), + } +} + +func oC_RelationshipPattern(ctx *parser.OC_RelationshipPatternContext) RelationshipPattern { + ret := RelationshipPattern{ + Backwards: ctx.OC_LeftArrowHead() != nil, + } + if x := ctx.OC_RelationshipDetail(); x != nil { + detctx := x.(*parser.OC_RelationshipDetailContext) + if x := detctx.OC_Variable(); x != nil { + v := oC_Variable(x.(*parser.OC_VariableContext)) + ret.Var = &v + } + if x := detctx.OC_RelationshipTypes(); x != nil { + r := oC_RelationshipTypes(x.(*parser.OC_RelationshipTypesContext)) + ret.RelTypes = &r + } + if x := detctx.OC_RangeLiteral(); x != nil { + r := oC_RangeLiteral(x.(*parser.OC_RangeLiteralContext)) + ret.Range = &r + } + if x := detctx.OC_Properties(); x != nil { + p := oC_Properties(x.(*parser.OC_PropertiesContext)) + ret.Properties = &p + } + } + return ret +} + +func oC_Variable(ctx *parser.OC_VariableContext) Variable { + return Variable(oC_SymbolicName(ctx.OC_SymbolicName().(*parser.OC_SymbolicNameContext))) +} + +func oC_RelationshipTypes(ctx *parser.OC_RelationshipTypesContext) RelationshipTypes { + ret := RelationshipTypes{} + for _, x := range ctx.AllOC_RelTypeName() { + ret.Rel = append(ret.Rel, oC_RelTypeName(x.(*parser.OC_RelTypeNameContext))) + } + return ret +} + +func oC_RelTypeName(ctx *parser.OC_RelTypeNameContext) SchemaName { + return oC_SchemaName(ctx.OC_SchemaName().(*parser.OC_SchemaNameContext)) +} + +func oC_Properties(ctx *parser.OC_PropertiesContext) Properties { + ret := Properties{} + if x := ctx.OC_MapLiteral(); x != nil { + ret.Map = oC_MapLiteral(x.(*parser.OC_MapLiteralContext)) + return ret + } + c := oC_Parameter(ctx.OC_Parameter().(*parser.OC_ParameterContext)) + ret.Param = &c + return ret +} + +func oC_Parameter(ctx *parser.OC_ParameterContext) Parameter { + var ret Parameter + if x := ctx.OC_SymbolicName(); x != nil { + c := oC_SymbolicName(x.(*parser.OC_SymbolicNameContext)) + ret = Parameter("$" + string(c)) + return ret + } + ret = Parameter("$" + ctx.DecimalInteger().GetText()) + return ret +} + +func DecimalInteger(ctx antlr.TerminalNode) IntLiteral { + i, err := strconv.Atoi(ctx.GetText()) + if err != nil { + panic(err) + } + return IntLiteral(i) +} + +func oC_RangeLiteral(ctx *parser.OC_RangeLiteralContext) RangeLiteral { + ret := RangeLiteral{} + values := make([]IntLiteral, 0, 2) + rangeIndex := -1 + for i := 0; i < ctx.GetChildCount(); i++ { + ch := ctx.GetChild(i) + if tok, ok := ch.(antlr.TerminalNode); ok { + if tok.GetText() == ".." { + rangeIndex = len(values) + } + } else if i, ok := ch.(*parser.OC_IntegerLiteralContext); ok { + values = append(values, oC_IntegerLiteral(i)) + } + } + + switch len(values) { + case 2: + ret.From = &values[0] + ret.To = &values[1] + case 1: + switch rangeIndex { + case 0: // ..value + ret.To = &values[0] + case 1: // value.. + ret.From = &values[0] + case -1: // value + ret.From = &values[0] + ret.To = &values[0] + } + } + return ret +} + +func oC_IntegerLiteral(ctx *parser.OC_IntegerLiteralContext) IntLiteral { + if x := ctx.HexInteger(); x != nil { + t := x.GetText() + val, err := strconv.ParseInt(string(t[2:]), 16, 64) + if err != nil { + panic(err) + } + return IntLiteral(val) + } + if x := ctx.OctalInteger(); x != nil { + t := x.GetText() + val, err := strconv.ParseInt(t, 8, 64) + if err != nil { + panic(err) + } + return IntLiteral(val) + } + return DecimalInteger(ctx.DecimalInteger()) +} + +func oC_BooleanLiteral(ctx *parser.OC_BooleanLiteralContext) BooleanLiteral { + if ctx.TRUE() != nil { + return BooleanLiteral(true) + } + return BooleanLiteral(false) +} + +func oC_ListLiteral(ctx *parser.OC_ListLiteralContext) *ListLiteral { + ret := &ListLiteral{} + for _, x := range ctx.AllOC_Expression() { + ret.Values = append(ret.Values, oC_Expression(x.(*parser.OC_ExpressionContext))) + } + return ret +} + +func oC_MapLiteral(ctx *parser.OC_MapLiteralContext) *MapLiteral { + ret := &MapLiteral{} + var keyName SchemaName + for i := 0; i < ctx.GetChildCount(); i++ { + switch c := ctx.GetChild(i).(type) { + case *parser.OC_PropertyKeyNameContext: + keyName = oC_SchemaName(c.OC_SchemaName().(*parser.OC_SchemaNameContext)) + case *parser.OC_ExpressionContext: + value := MapKeyValue{ + Key: keyName.String(), + Value: oC_Expression(c), + } + ret.KeyValues = append(ret.KeyValues, value) + } + } + return ret +} + +func oC_Atom(ctx *parser.OC_AtomContext) Atom { + if lit := ctx.OC_Literal(); lit != nil { + return oC_Literal(lit.(*parser.OC_LiteralContext)) + } + if param := ctx.OC_Parameter(); param != nil { + return oC_Parameter(param.(*parser.OC_ParameterContext)) + } + if casee := ctx.OC_CaseExpression(); casee != nil { + return oC_CaseExpression(casee.(*parser.OC_CaseExpressionContext)) + } + if ctx.COUNT() != nil { + return CountAtom{} + } + + if l := ctx.OC_ListComprehension(); l != nil { + return oC_ListComprehension(l.(*parser.OC_ListComprehensionContext)) + } + if p := ctx.OC_PatternComprehension(); p != nil { + return oC_PatternComprehension(p.(*parser.OC_PatternComprehensionContext)) + } + if ctx.ALL() != nil { + return FilterAtom{ + Op: "ALL", + Filter: oC_FilterExpression(ctx.OC_FilterExpression().(*parser.OC_FilterExpressionContext)), + } + } + if ctx.ANY() != nil { + return FilterAtom{ + Op: "ANY", + Filter: oC_FilterExpression(ctx.OC_FilterExpression().(*parser.OC_FilterExpressionContext)), + } + } + if ctx.NONE() != nil { + return FilterAtom{ + Op: "NONE", + Filter: oC_FilterExpression(ctx.OC_FilterExpression().(*parser.OC_FilterExpressionContext)), + } + } + if ctx.SINGLE() != nil { + return FilterAtom{ + Op: "SINGLE", + Filter: oC_FilterExpression(ctx.OC_FilterExpression().(*parser.OC_FilterExpressionContext)), + } + } + if r := ctx.OC_RelationshipsPattern(); r != nil { + return oC_RelationshipsPattern(r.(*parser.OC_RelationshipsPatternContext)) + } + if p := ctx.OC_ParenthesizedExpression(); p != nil { + return oC_Expression(p.(*parser.OC_ParenthesizedExpressionContext).OC_Expression().(*parser.OC_ExpressionContext)) + } + if f := ctx.OC_FunctionInvocation(); f != nil { + return oC_FunctionInvocation(f.(*parser.OC_FunctionInvocationContext)) + } + return oC_Variable(ctx.OC_Variable().(*parser.OC_VariableContext)) +} + +func oC_FilterExpression(ctx *parser.OC_FilterExpressionContext) FilterExpression { + idInColl := ctx.OC_IdInColl().(*parser.OC_IdInCollContext) + ret := FilterExpression{ + Variable: oC_Variable(idInColl.OC_Variable().(*parser.OC_VariableContext)), + InExpr: oC_Expression(idInColl.OC_Expression().(*parser.OC_ExpressionContext)), + } + if w := ctx.OC_Where(); w != nil { + ret.Where = oC_Where(w.(*parser.OC_WhereContext)) + } + + return ret +} + +//oC_RelationshipsPattern : oC_NodePattern ( SP? oC_PatternElementChain )+ ; +// oC_PatternElementChain : oC_RelationshipPattern SP? oC_NodePattern ; +func oC_RelationshipsPattern(ctx *parser.OC_RelationshipsPatternContext) RelationshipsPattern { + ret := RelationshipsPattern{ + Start: oC_NodePattern(ctx.OC_NodePattern().(*parser.OC_NodePatternContext)), + } + for _, element := range ctx.AllOC_PatternElementChain() { + ret.Chain = append(ret.Chain, oC_PatternElementChain(element.(*parser.OC_PatternElementChainContext))) + } + return ret +} + +func oC_ListComprehension(ctx *parser.OC_ListComprehensionContext) ListComprehension { + ret := ListComprehension{ + Filter: oC_FilterExpression(ctx.OC_FilterExpression().(*parser.OC_FilterExpressionContext)), + } + if x := ctx.OC_Expression(); x != nil { + ret.Expr = oC_Expression(x.(*parser.OC_ExpressionContext)) + } + return ret +} + +func oC_FunctionInvocation(ctx *parser.OC_FunctionInvocationContext) *FunctionInvocation { + ret := &FunctionInvocation{ + Name: oC_FunctionName(ctx.OC_FunctionName().(*parser.OC_FunctionNameContext)), + Distinct: ctx.DISTINCT() != nil, + } + for _, x := range ctx.AllOC_Expression() { + ret.Args = append(ret.Args, oC_Expression(x.(*parser.OC_ExpressionContext))) + } + return ret +} + +func oC_FunctionName(ctx *parser.OC_FunctionNameContext) []SymbolicName { + if ctx.EXISTS() != nil { + return []SymbolicName{"EXISTS"} + } + ns := oC_Namespace(ctx.OC_Namespace().(*parser.OC_NamespaceContext)) + return append(ns, oC_SymbolicName(ctx.OC_SymbolicName().(*parser.OC_SymbolicNameContext))) +} + +func oC_Namespace(ctx *parser.OC_NamespaceContext) []SymbolicName { + ret := make([]SymbolicName, 0) + for _, x := range ctx.AllOC_SymbolicName() { + ret = append(ret, oC_SymbolicName(x.(*parser.OC_SymbolicNameContext))) + } + return ret +} + +func oC_PatternComprehension(ctx *parser.OC_PatternComprehensionContext) PatternComprehension { + ret := PatternComprehension{ + Rel: oC_RelationshipsPattern(ctx.OC_RelationshipsPattern().(*parser.OC_RelationshipsPatternContext)), + } + if v := ctx.OC_Variable(); v != nil { + x := oC_Variable(v.(*parser.OC_VariableContext)) + ret.Var = &x + } + expr := ctx.AllOC_Expression() + if len(expr) == 1 { + ret.Expr = oC_Expression(expr[0].(*parser.OC_ExpressionContext)) + } else { + ret.Where = oC_Expression(expr[0].(*parser.OC_ExpressionContext)) + ret.Expr = oC_Expression(expr[1].(*parser.OC_ExpressionContext)) + } + return ret +} + +func oC_CaseExpression(ctx *parser.OC_CaseExpressionContext) Case { + ret := Case{} + for _, alt := range ctx.AllOC_CaseAlternatives() { + ret.Alternatives = append(ret.Alternatives, oC_CaseAlternatives(alt.(*parser.OC_CaseAlternativesContext))) + } + elseSeen := false + for i := 0; i < ctx.GetChildCount(); i++ { + ch := ctx.GetChild(i) + if term, ok := ch.(antlr.TerminalNode); ok { + if strings.ToUpper(term.GetText()) == "ELSE" { + elseSeen = true + } + } else if expr, ok := ch.(*parser.OC_ExpressionContext); ok { + if elseSeen { + ret.Default = oC_Expression(expr) + } else { + ret.Test = oC_Expression(expr) + } + } + } + return ret +} + +func oC_CaseAlternatives(ctx *parser.OC_CaseAlternativesContext) CaseAlternative { + expr := ctx.AllOC_Expression() + return CaseAlternative{ + When: oC_Expression(expr[0].(*parser.OC_ExpressionContext)), + Then: oC_Expression(expr[1].(*parser.OC_ExpressionContext)), + } +} + +func oC_Literal(ctx *parser.OC_LiteralContext) Evaluatable { + if ctx.NULL() != nil { + return NullLiteral{} + } + if n := ctx.OC_NumberLiteral(); n != nil { + return oC_NumberLiteral(n.(*parser.OC_NumberLiteralContext)) + } + if s := ctx.StringLiteral(); s != nil { + text := s.GetText() + return StringLiteral(text[1 : len(text)-1]) + } + if b := ctx.OC_BooleanLiteral(); b != nil { + return oC_BooleanLiteral(b.(*parser.OC_BooleanLiteralContext)) + } + if m := ctx.OC_MapLiteral(); m != nil { + return oC_MapLiteral(m.(*parser.OC_MapLiteralContext)) + } + return oC_ListLiteral(ctx.OC_ListLiteral().(*parser.OC_ListLiteralContext)) +} + +func oC_NumberLiteral(ctx *parser.OC_NumberLiteralContext) Evaluatable { + if d := ctx.OC_DoubleLiteral(); d != nil { + return oC_DoubleLiteral(d.(*parser.OC_DoubleLiteralContext)) + } + return oC_IntegerLiteral(ctx.OC_IntegerLiteral().(*parser.OC_IntegerLiteralContext)) +} + +func oC_DoubleLiteral(ctx *parser.OC_DoubleLiteralContext) DoubleLiteral { + v, err := strconv.ParseFloat(ctx.GetText(), 64) + if err != nil { + panic(err) + } + return DoubleLiteral(v) +} + +func oC_Unwind(ctx *parser.OC_UnwindContext) Unwind { + return Unwind{ + Expr: oC_Expression(ctx.OC_Expression().(*parser.OC_ExpressionContext)), + As: oC_Variable(ctx.OC_Variable().(*parser.OC_VariableContext)), + } +} + +func oC_InQueryCall(ctx *parser.OC_InQueryCallContext) ReadingClause { + panic("Unsupported: inQueryCall") +} + +func oC_Create(ctx *parser.OC_CreateContext) Evaluatable { + panic("Unsupported: create") +} + +func oC_Merge(ctx *parser.OC_MergeContext) Evaluatable { + panic("Unsupported: merge") +} + +func oC_Delete(ctx *parser.OC_DeleteContext) Evaluatable { + panic("Unsupported: delete") +} + +func oC_Set(ctx *parser.OC_SetContext) Evaluatable { + panic("Unsupported: set") +} + +func oC_Remove(ctx *parser.OC_RemoveContext) Evaluatable { + panic("Unsupported: remove") +} + +func oC_StandaloneCall(ctx *parser.OC_StandaloneCallContext) Evaluatable { + panic("Unsupported: standaloneCall") +} diff --git a/compiler_test.go b/compiler_test.go new file mode 100644 index 0000000..4fff4fe --- /dev/null +++ b/compiler_test.go @@ -0,0 +1,83 @@ +package opencypher + +import ( + "testing" + + "github.com/cloudprivacylabs/opencypher/graph" + "github.com/cloudprivacylabs/opencypher/parser" +) + +func TestExpr(t *testing.T) { + c := GetParser(`5 + 7+1`).OC_Expression() + out := oC_Expression(c.(*parser.OC_ExpressionContext)) + result, err := out.Evaluate(NewEvalContext(graph.NewOCGraph())) + if err != nil { + t.Error(err) + } + if result.Value != 13 { + t.Errorf("Wrong result: %+v %T", result, result.Value) + } +} + +func runTestMatch(t *testing.T, expr string, g graph.Graph) ResultSet { + ctx := NewEvalContext(g) + ev, err := Parse(expr) + if err != nil { + t.Errorf("%s: %s", expr, err) + return ResultSet{} + } + value, err := ev.Evaluate(ctx) + if err != nil { + t.Errorf("%s: %s", expr, err) + return ResultSet{} + } + + return value.Value.(ResultSet) +} + +func TestBasicMatch(t *testing.T) { + + g := graph.NewOCGraph() + // (:t1:t2) + n1 := g.NewNode([]string{"t1", "t2"}, nil) + rs := runTestMatch(t, "match (n) return n", g) + if !rs.Rows[0]["1"].Value.(graph.Node).GetLabels().HasAll("t1", "t2") { + t.Errorf("Expecting to see one row with t1, t2") + } + + // (:t1:t2) (:t1:t3) + n2 := g.NewNode([]string{"t1", "t3"}, nil) + rs = runTestMatch(t, "match (n:t1) return n", g) + if !(len(rs.Rows) == 2 && rs.Rows[0]["1"].Value.(graph.Node).GetLabels().Has("t1") && + rs.Rows[1]["1"].Value.(graph.Node).GetLabels().Has("t1")) { + t.Errorf("Expecting to see two rows with t1, t2") + } + rs = runTestMatch(t, "match (n:t2) return n", g) + if !(len(rs.Rows) == 1 && rs.Rows[0]["1"].Value.(graph.Node).GetLabels().Has("t1")) { + t.Errorf("Expecting to see one row with t1: %v", rs) + } + + // (:t1:t2) --[:e1]-->(:t1:t3) + g.NewEdge(n1, n2, "e1", nil) + rs = runTestMatch(t, "match (m:t1)-[:e1]->(n:t3) return n", g) + if !(len(rs.Rows) == 1 && rs.Rows[0]["1"].Value.(graph.Node) == n2) { + t.Errorf("Expecting to see one row n2: %v", rs) + } + rs = runTestMatch(t, "match (m:t1)<-[:e1]-(n:t1) return n", g) + if !(len(rs.Rows) == 1 && rs.Rows[0]["1"].Value.(graph.Node) == n1) { + t.Errorf("Expecting to see one row n1: %v", rs) + } + rs = runTestMatch(t, "match (m:t1)<-[:e1]-(n:t1) return n,m", g) + if !(len(rs.Rows) == 1 && rs.Rows[0]["1"].Value.(graph.Node) == n1 && rs.Rows[0]["2"].Value.(graph.Node) == n2) { + t.Errorf("Expecting to see one row n1 n2: %v", rs) + } + + // (:t1:t2) --[:e1]-->(:t1:t3) --[:e2]-->(:t4) + n3 := g.NewNode([]string{"t4"}, nil) + g.NewEdge(n2, n3, "e2", nil) + rs = runTestMatch(t, "match (m:t1)-[*]->(n:t4) return n", g) + if !(len(rs.Rows) == 2 && rs.Rows[0]["1"].Value.(graph.Node) == n3 && rs.Rows[1]["1"].Value.(graph.Node) == n3) { + t.Errorf("Expecting to see two rows n3: %v", rs) + } + +} diff --git a/ctx.go b/ctx.go new file mode 100644 index 0000000..5b7d92f --- /dev/null +++ b/ctx.go @@ -0,0 +1,101 @@ +package opencypher + +import ( + "strings" + + "github.com/cloudprivacylabs/opencypher/graph" +) + +type ErrUnknownParameter struct { + Key string +} + +func (e ErrUnknownParameter) Error() string { return "Unknown parameter: " + e.Key } + +type Function func(*EvalContext, []Evaluatable) (Value, error) + +type EvalContext struct { + parent *EvalContext + funcMap map[string]Function + variables map[string]Value + parameters map[string]Value + graph graph.Graph +} + +func NewEvalContext(graph graph.Graph) *EvalContext { + return &EvalContext{ + funcMap: globalFuncs, + variables: make(map[string]Value), + parameters: make(map[string]Value), + graph: graph, + } +} + +// SubContext creates a new subcontext with a new variable set +func (ctx *EvalContext) SubContext() *EvalContext { + return &EvalContext{ + parent: ctx, + funcMap: ctx.funcMap, + variables: make(map[string]Value), + parameters: make(map[string]Value), + graph: ctx.graph, + } +} + +// SetParameter sets a parameter to be used in expressions +func (ctx *EvalContext) SetParameter(key string, value Value) *EvalContext { + ctx.parameters[key] = value + return ctx +} + +func (ctx *EvalContext) GetParameter(key string) (Value, error) { + value, ok := ctx.parameters[key] + if !ok { + return Value{}, ErrUnknownParameter{Key: key} + } + return value, nil +} + +type ErrUnknownFunction struct { + Name string +} + +func (e ErrUnknownFunction) Error() string { return "Unknown function: " + e.Name } + +type ErrUnknownVariable struct { + Name string +} + +func (e ErrUnknownVariable) Error() string { return "Unknown variable:" + e.Name } + +func (ctx *EvalContext) getFunction(name string) (Function, error) { + f := ctx.funcMap[name] + if f == nil { + return nil, ErrUnknownFunction{name} + } + return f, nil +} + +func (ctx *EvalContext) GetFunction(name []SymbolicName) (Function, error) { + bld := strings.Builder{} + for i, x := range name { + if i > 0 { + bld.WriteRune('.') + } + bld.WriteString(string(x)) + } + return ctx.getFunction(bld.String()) +} + +func (ctx *EvalContext) GetVar(name string) (Value, error) { + val, ok := ctx.variables[name] + if !ok { + return Value{}, ErrUnknownVariable{Name: name} + } + val.Constant = false + return val, nil +} + +func (ctx *EvalContext) SetVar(name string, value Value) { + ctx.variables[name] = value +} diff --git a/eval.go b/eval.go new file mode 100644 index 0000000..a36cf91 --- /dev/null +++ b/eval.go @@ -0,0 +1,431 @@ +package opencypher + +import ( + "errors" + "strconv" + "strings" + + "github.com/cloudprivacylabs/opencypher/graph" +) + +const ( + c_const uint = 0x001 + c_lvalue uint = 0x002 +) + +var ( + ErrDivideByZero = errors.New("Divide by zero") + ErrInvalidUnaryOperation = errors.New("Invalid unary operation") + ErrInvalidPowerOperation = errors.New("Invalid power operation") + ErrInvalidMultiplicativeOperation = errors.New("Invalid multiplicative operation") + ErrInvalidDurationOperation = errors.New("Invalid duration operation") + ErrOperationWithNull = errors.New("Operation with null") + ErrInvalidStringOperation = errors.New("Invalid string operation") + ErrInvalidDateOperation = errors.New("Invalid date operation") + ErrInvalidAdditiveOperation = errors.New("Invalid additive operation") + ErrInvalidComparison = errors.New("Invalid comparison") + ErrInvalidListIndex = errors.New("Invalid list index") + ErrNotAList = errors.New("Not a list") + ErrNotABooleanExpression = errors.New("Not a boolean expression") + ErrMapKeyNotString = errors.New("Map key is not a string") + ErrInvalidMapKey = errors.New("Invalid map key") + ErrNotAStringSet = errors.New("Not a string set") + ErrIntValueRequired = errors.New("Int value required") + ErrExpectingResultSet = errors.New("Expecting a result set") + ErrPropertiesParameterExpected = errors.New("Parameter value cannot be used for properties") + ErrPropertiesExpected = errors.New("Value cannot be used for properties") + ErrValueDoesNotHaveProperties = errors.New("Value does not have properties") +) + +func (expr Parameter) Evaluate(ctx *EvalContext) (Value, error) { + return ctx.GetParameter(string(expr)) +} + +func (expr StringListNullOperatorExpression) Evaluate(ctx *EvalContext) (Value, error) { + val, err := expr.PropertyOrLabels.Evaluate(ctx) + if err != nil { + return Value{}, err + } + for _, part := range expr.Parts { + val, err = part.evaluate(ctx, val) + if err != nil { + return Value{}, err + } + } + return val, nil +} + +func (expr StringListNullOperatorExpressionPart) evaluate(ctx *EvalContext, inputValue Value) (Value, error) { + switch { + case expr.IsNull != nil: + if *expr.IsNull { + return Value{Value: inputValue.Value == nil}, nil + } + return Value{Value: inputValue.Value != nil}, nil + + case expr.ListIndex != nil: + listValue, ok := inputValue.Value.([]Value) + if !ok { + if inputValue.Value != nil { + return Value{}, ErrNotAList + } + } + indexValue, err := expr.ListIndex.Evaluate(ctx) + if err != nil { + return Value{}, err + } + if indexValue.Value == nil { + return Value{}, nil + } + intValue, ok := indexValue.Value.(int) + if !ok { + return Value{}, ErrInvalidListIndex + } + if listValue == nil { + return Value{}, nil + } + if intValue >= 0 { + if intValue >= len(listValue) { + return Value{}, nil + } + return listValue[intValue], nil + } + index := len(listValue) + intValue + if index < 0 { + return Value{}, nil + } + return listValue[index], nil + + case expr.ListIn != nil: + listValue, err := expr.ListIn.Evaluate(ctx) + if err != nil { + return Value{}, err + } + list, ok := listValue.Value.([]Value) + if ok { + if listValue.Value != nil { + return Value{}, ErrNotAList + } + } + if inputValue.Value == nil { + return Value{}, nil + } + hasNull := false + for _, elem := range list { + if elem.Value == nil { + hasNull = true + } else { + v, err := comparePrimitiveValues(inputValue.Value, elem.Value) + if err != nil { + return Value{}, err + } + if v == 0 { + return Value{Value: true}, nil + } + } + } + if hasNull { + return Value{}, nil + } + return Value{Value: false}, nil + + case expr.ListRange != nil: + constant := inputValue.Constant + listValue, ok := inputValue.Value.([]Value) + if !ok { + if inputValue.Value != nil { + return Value{}, ErrNotAList + } + } + from, err := expr.ListRange.First.Evaluate(ctx) + if err != nil { + return Value{}, err + } + if from.Value == nil { + return Value{}, nil + } + if !from.Constant { + constant = false + } + fromi, ok := from.Value.(int) + if !ok { + return Value{}, ErrInvalidListIndex + } + to, err := expr.ListRange.Second.Evaluate(ctx) + if err != nil { + return Value{}, err + } + if to.Value == nil { + return Value{}, nil + } + if !to.Constant { + constant = false + } + toi, ok := to.Value.(int) + if !ok { + return Value{}, ErrInvalidListIndex + } + if fromi < 0 || toi < 0 { + return Value{}, ErrInvalidListIndex + } + if fromi >= len(listValue) { + fromi = len(listValue) - 1 + } + if toi >= len(listValue) { + toi = len(listValue) - 1 + } + if fromi > toi { + fromi = toi + } + arr := make([]Value, 0, toi-fromi) + for i := fromi; i < toi; i++ { + if !listValue[i].Constant { + constant = false + } + arr = append(arr, listValue[i]) + } + return Value{Value: arr, Constant: constant}, nil + } + return expr.String.evaluate(ctx, inputValue) +} + +func (expr StringOperatorExpression) evaluate(ctx *EvalContext, inputValue Value) (Value, error) { + inputStrValue, ok := inputValue.Value.(string) + if !ok { + return Value{}, ErrInvalidStringOperation + } + exprValue, err := expr.Expr.Evaluate(ctx) + if err != nil { + return Value{}, err + } + strValue, ok := exprValue.Value.(string) + if !ok { + return Value{}, ErrInvalidStringOperation + } + if expr.Operator == "STARTS" { + return Value{Value: strings.HasPrefix(inputStrValue, strValue)}, nil + } + if expr.Operator == "ENDS" { + return Value{Value: strings.HasSuffix(inputStrValue, strValue)}, nil + } + return Value{Value: strings.Contains(inputStrValue, strValue)}, nil +} + +func (pl PropertyOrLabelsExpression) Evaluate(ctx *EvalContext) (Value, error) { + val, err := pl.Atom.Evaluate(ctx) + if err != nil { + return Value{}, err + } + if pl.NodeLabels != nil { + gobj, ok := val.Value.(graph.StringSet) + if !ok { + return Value{}, ErrNotAStringSet + } + for _, label := range *pl.NodeLabels { + str := label.String() + gobj.Add(str) + } + val.Value = gobj + } + type withProperty interface { + GetProperty(string) (interface{}, bool) + } + type withNativeValue interface { + GetNativeValue() interface{} + } + for _, property := range pl.PropertyLookup { + if val.Value == nil { + return Value{}, nil + } + if wp, ok := val.Value.(withProperty); ok { + prop, ok := wp.GetProperty(property.String()) + if !ok { + return Value{}, nil + } + if n, ok := prop.(withNativeValue); ok { + val = ValueOf(n.GetNativeValue()) + } else { + val = ValueOf(prop) + } + } else { + return Value{}, ErrValueDoesNotHaveProperties + } + } + return val, nil +} + +func (f *FunctionInvocation) Evaluate(ctx *EvalContext) (Value, error) { + if f.function == nil { + fn, err := ctx.GetFunction(f.Name) + if err != nil { + return Value{}, err + } + f.function = fn + } + args := f.args + if args == nil { + args = make([]Evaluatable, 0, len(f.Args)) + isConst := false + + for a := range f.Args { + v, err := f.Args[a].Evaluate(ctx) + if err != nil { + return Value{}, err + } + if a == 0 { + isConst = v.Constant + } else if !v.Constant { + isConst = false + } + args = append(args, v) + } + if isConst { + f.args = args + } + } + return f.function(ctx, args) +} + +func (cs Case) Evaluate(ctx *EvalContext) (Value, error) { + var testValue Value + if cs.Test != nil { + v, err := cs.Test.Evaluate(ctx) + if err != nil { + return Value{}, err + } + testValue = v + } + for _, alternative := range cs.Alternatives { + when, err := alternative.When.Evaluate(ctx) + if err != nil { + return Value{}, err + } + if cs.Test != nil { + result, err := comparePrimitiveValues(testValue, when) + if err != nil { + return Value{}, err + } + if result == 0 { + return alternative.Then.Evaluate(ctx) + } + } else { + boolValue, ok := when.Value.(bool) + if !ok { + return Value{}, ErrNotABooleanExpression + } + if boolValue { + return alternative.Then.Evaluate(ctx) + } + } + } + if cs.Default != nil { + return cs.Default.Evaluate(ctx) + } + return Value{}, nil +} + +func (v Variable) Evaluate(ctx *EvalContext) (Value, error) { + return ctx.GetVar(string(v)) +} + +// Evaluate a regular query, which is a single query with an optional +// union list +func (query RegularQuery) Evaluate(ctx *EvalContext) (Value, error) { + result, err := query.SingleQuery.Evaluate(ctx) + if err != nil { + return Value{}, err + } + resultSet, ok := result.Value.(ResultSet) + if !ok { + return Value{}, ErrExpectingResultSet + } + for _, u := range query.Unions { + newResult, err := u.SingleQuery.Evaluate(ctx) + if err != nil { + return Value{}, err + } + newResultSet, ok := newResult.Value.(ResultSet) + if !ok { + return Value{}, ErrExpectingResultSet + } + if err := resultSet.Union(newResultSet, u.All); err != nil { + return Value{}, err + } + } + return Value{Value: resultSet}, nil +} + +func (query SinglePartQuery) Evaluate(ctx *EvalContext) (Value, error) { + if len(query.Update) > 0 { + panic("Updating Query is not implemented") + } + + ret := ResultSet{} + if len(query.Read) > 0 { + results := ResultSet{} + for _, r := range query.Read { + rs, err := r.GetResults(ctx) + if err != nil { + return Value{}, err + } + results.Add(rs) + } + if query.Return == nil { + return Value{}, nil + } + // Keys keep the order of each key in the result set + for _, item := range results.Rows { + val, err := query.Return.Projection.Items.Project(ctx, item) + if err != nil { + return Value{}, err + } + ret.Rows = append(ret.Rows, val) + } + return Value{Value: ret}, nil + } + if query.Return != nil { + val, err := query.Return.Projection.Items.Project(ctx, nil) + if err != nil { + return Value{}, err + } + ret.Rows = append(ret.Rows, val) + return Value{Value: ret}, nil + } + return Value{}, nil +} + +func (prj ProjectionItems) Project(ctx *EvalContext, values map[string]Value) (map[string]Value, error) { + ret := make(map[string]Value) + if prj.All { + for k, v := range values { + ret[k] = v + } + return ret, nil + } + + for k, v := range values { + ctx.SetVar(k, v) + } + for i, item := range prj.Items { + result, err := item.Expr.Evaluate(ctx) + if err != nil { + return nil, err + } + var varName string + if item.Var != nil { + varName = string(*item.Var) + } else { + varName = strconv.Itoa(i + 1) + } + ret[varName] = result + } + return ret, nil +} + +func (unwind Unwind) GetResults(ctx *EvalContext) (ResultSet, error) { panic("Unimplemented") } +func (ls ListComprehension) Evaluate(ctx *EvalContext) (Value, error) { panic("Unimplemented") } +func (p PatternComprehension) Evaluate(ctx *EvalContext) (Value, error) { panic("Unimplemented") } +func (flt FilterAtom) Evaluate(ctx *EvalContext) (Value, error) { panic("Unimplemented") } +func (rel RelationshipsPattern) Evaluate(ctx *EvalContext) (Value, error) { panic("Unimplemented") } +func (cnt CountAtom) Evaluate(ctx *EvalContext) (Value, error) { panic("Unimplemented") } +func (mq MultiPartQuery) Evaluate(ctx *EvalContext) (Value, error) { panic("Unimplemented") } diff --git a/functions.go b/functions.go new file mode 100644 index 0000000..305b0f1 --- /dev/null +++ b/functions.go @@ -0,0 +1,59 @@ +package opencypher + +func mustInt(v Value, err error) (int, error) { + if err != nil { + return 0, err + } + i, ok := v.Value.(int) + if !ok { + return 0, ErrIntValueRequired + } + return i, nil +} + +type ErrInvalidFunctionCall struct { + Msg string +} + +func (e ErrInvalidFunctionCall) Error() string { + return "Invalid function call: " + e.Msg +} + +var globalFuncs = map[string]Function{ + "range": rangeFunc, +} + +func rangeFunc(ctx *EvalContext, args []Evaluatable) (Value, error) { + if len(args) < 2 || len(args) > 3 { + return Value{}, ErrInvalidFunctionCall{"range(start,stop,[step]) needs 3 args"} + } + start, err := mustInt(args[0].Evaluate(ctx)) + if err != nil { + return Value{}, err + } + end, err := mustInt(args[1].Evaluate(ctx)) + if err != nil { + return Value{}, err + } + skip := 1 + if len(args) == 3 { + skip, err = mustInt(args[2].Evaluate(ctx)) + if err != nil { + return Value{}, err + } + } + if (end <= start && skip > 0) || (end >= start && skip < 0) || skip == 0 { + return Value{Value: []Value{}}, nil + } + arr := make([]Value, 0) + if end > start { + for at := start; at < end; at += skip { + arr = append(arr, Value{Value: at}) + } + } else { + for at := start; at > end; at += skip { + arr = append(arr, Value{Value: at}) + } + } + return Value{Value: arr}, nil +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..4eb1f8a --- /dev/null +++ b/go.mod @@ -0,0 +1,14 @@ +module github.com/cloudprivacylabs/opencypher + +go 1.18 + +require ( + github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20210803070921-b358b509191a + github.com/emirpasic/gods v1.18.0 + github.com/neo4j/neo4j-go-driver v1.8.3 +) + +require ( + golang.org/x/text v0.3.6 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..19e22eb --- /dev/null +++ b/go.sum @@ -0,0 +1,46 @@ +github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20210803070921-b358b509191a h1:6tPeghyQyDji+Q+jYDjpHNlLz/aexx/Cvk1ao92Nfbg= +github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20210803070921-b358b509191a/go.mod h1:F7bn7fEU90QkQ3tnmaTx3LTKLEDqnwWODIYppRQ5hnY= +github.com/emirpasic/gods v1.18.0 h1:voaQ8lgxXz4FMIm08RiGs9Nx//PvUUI0FcIXK5xRi6w= +github.com/emirpasic/gods v1.18.0/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/neo4j/neo4j-go-driver v1.8.3 h1:yfuo9YBAlezdIiogu92GwEir/81RD81dNwS5mY/wAIk= +github.com/neo4j/neo4j-go-driver v1.8.3/go.mod h1:ncO5VaFWh0Nrt+4KT4mOZboaczBZcLuHrG+/sUeP8gI= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.0 h1:Iw5WCbBcaAAd0fpRb1c9r5YCylv4XDoCSigm1zLevwU= +github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.9.0 h1:R1uwffexN6Pr340GtYRIdZmAiN4J+iw6WG4wog1DUXg= +github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e h1:N7DeIrjYszNmSW409R3frPPwglRwMkXSBzwVbkOjLLA= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/graph/alg.go b/graph/alg.go new file mode 100644 index 0000000..b792286 --- /dev/null +++ b/graph/alg.go @@ -0,0 +1,113 @@ +package graph + +import () + +// Sources finds all the source nodes in the graph +func SourcesItr(graph Graph) NodeIterator { + return &nodeIterator{ + &filterIterator{ + itr: graph.GetNodes(), + filter: func(item interface{}) bool { + node := item.(Node) + if edges := node.GetEdges(IncomingEdge); edges.Next() { + return false + } + return true + }, + }, + } +} + +// Sources finds all the source nodes in the graph +func Sources(graph Graph) []Node { + return NodeSlice(SourcesItr(graph)) +} + +// CheckIsomoprhism checks to see if graphs given are equal as defined +// by the edge equivalence and node equivalence functions. The +// nodeEquivalenceFunction will be called for nodes whose labels are +// the same. The edgeEquivalenceFunction will be called for edges +// connecting equivalent nodes with the same labels. +// +// Node isomorphism check will fail if one node is equivalent to +// multiple nodes +func CheckIsomorphism(g1, g2 Graph, nodeEquivalenceFunc func(n1, n2 Node) bool, edgeEquivalenceFunc func(e1, e2 Edge) bool) bool { + // Map of nodes1 -> nodes2 + nodeMapping1_2 := make(map[Node]Node) + // Map of nodes2 -> nodes1 + nodeMapping2_1 := make(map[Node]Node) + + if g1.NumNodes() != g2.NumNodes() || g1.NumEdges() != g2.NumEdges() { + return false + } + + for nodes := g1.GetNodes(); nodes.Next(); { + node1 := nodes.Node() + for nodes2 := g2.GetNodes(); nodes2.Next(); { + node2 := nodes2.Node() + if node1.GetLabels().IsEqual(node2.GetLabels()) { + if nodeEquivalenceFunc(node1, node2) { + if _, ok := nodeMapping1_2[node1]; ok { + return false + } + nodeMapping1_2[node1] = node2 + if _, ok := nodeMapping2_1[node2]; ok { + return false + } + nodeMapping2_1[node2] = node1 + } + } + } + } + if len(nodeMapping1_2) != g1.NumNodes() { + return false + } + // Node equivalences are established, now check edge equivalences + for node1, node2 := range nodeMapping1_2 { + // node1 and node2 are equivalent. Now we check if equivalent edges go to equivalent nodes + edges1 := EdgeSlice(node1.GetEdges(OutgoingEdge)) + edges2 := EdgeSlice(node2.GetEdges(OutgoingEdge)) + // There must be same number of edges + if len(edges1) != len(edges2) { + return false + } + // Find equivalent edges + edgeMap := make(map[Edge]Edge) + for _, edge1 := range edges1 { + found := false + for _, edge2 := range edges2 { + toNode1 := nodeMapping1_2[edge1.GetTo()] + toNode2 := edge2.GetTo() + if toNode1 == toNode2 { + if edge1.GetLabel() == edge2.GetLabel() && + edgeEquivalenceFunc(edge1, edge2) { + if found { + // Multiple edges match + return false + } + edgeMap[edge1] = edge2 + found = true + } + } + } + if !found { + return false + } + } + if len(edgeMap) != len(edges1) { + return false + } + } + return true +} + +// ForEachNode iterates through all the nodes of g until predicate +// returns false or all nodes are processed. +func ForEachNode(g Graph, predicate func(Node) bool) bool { + for nodes := g.GetNodes(); nodes.Next(); { + if !predicate(nodes.Node()) { + return false + } + } + return true +} diff --git a/graph/clone.go b/graph/clone.go new file mode 100644 index 0000000..9867c17 --- /dev/null +++ b/graph/clone.go @@ -0,0 +1,97 @@ +// Copyright 2021 Cloud Privacy Labs, LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package graph + +func copyLabels(in StringSet) []string { + srcLabels := in.Slice() + labels := make([]string, len(srcLabels)) + copy(labels, srcLabels) + return labels +} + +type withProperties interface { + ForEachProperty(func(string, interface{}) bool) bool +} + +func copyProperties(in withProperties, cloneProperty func(string, interface{}) interface{}) map[string]interface{} { + properties := make(map[string]interface{}) + in.ForEachProperty(func(key string, value interface{}) bool { + properties[key] = cloneProperty(key, value) + return true + }) + return properties +} + +// CopyGraph copies source graph into target, using clonePropertyFunc to clone properties +func CopyGraph(source, target Graph, clonePropertyFunc func(string, interface{}) interface{}) map[Node]Node { + return CopyGraphf(source, func(node Node, nodeMap map[Node]Node) Node { + return target.NewNode(copyLabels(node.GetLabels()), copyProperties(node, clonePropertyFunc)) + }, func(edge Edge, nodeMap map[Node]Node) Edge { + properties := make(map[string]interface{}) + edge.ForEachProperty(func(key string, value interface{}) bool { + properties[key] = clonePropertyFunc(key, value) + return true + }) + return target.NewEdge(nodeMap[edge.GetFrom()], nodeMap[edge.GetTo()], edge.GetLabel(), properties) + }) +} + +// CopyGraphf copies source graph into target, using the copeNodeFunc +// func to clone nodes. copyNodeFunc may return nil to prevent +// copying a node +func CopyGraphf(source Graph, copyNodeFunc func(Node, map[Node]Node) Node, copyEdgeFunc func(Edge, map[Node]Node) Edge) map[Node]Node { + nodeMap := make(map[Node]Node) + for nodes := source.GetNodes(); nodes.Next(); { + node := nodes.Node() + newNode := copyNodeFunc(node, nodeMap) + if newNode != nil { + nodeMap[node] = newNode + } + } + for edges := source.GetEdges(); edges.Next(); { + edge := edges.Edge() + if _, fromExists := nodeMap[edge.GetFrom()]; !fromExists { + continue + } + if _, toExists := nodeMap[edge.GetTo()]; !toExists { + continue + } + copyEdgeFunc(edge, nodeMap) + } + return nodeMap +} + +// CopySubgraph copies all nodes that are accessible from sourceNode to the target graph +func CopySubgraph(sourceNode Node, target Graph, clonePropertyFunc func(string, interface{}) interface{}, nodeMap map[Node]Node) { + if _, ok := nodeMap[sourceNode]; ok { + return + } + nodeMap[sourceNode] = CopyNode(sourceNode, target, clonePropertyFunc) + for edges := sourceNode.GetEdges(OutgoingEdge); edges.Next(); { + edge := edges.Edge() + CopySubgraph(edge.GetTo(), target, clonePropertyFunc, nodeMap) + CopyEdge(edge, target, clonePropertyFunc, nodeMap) + } +} + +// CopyNode copies the sourceNode into target graph +func CopyNode(sourceNode Node, target Graph, clonePropertyFunc func(string, interface{}) interface{}) Node { + return target.NewNode(copyLabels(sourceNode.GetLabels()), copyProperties(sourceNode, clonePropertyFunc)) +} + +// CopyEdge copies the edge into graph +func CopyEdge(edge Edge, target Graph, clonePropertyFunc func(string, interface{}) interface{}, nodeMap map[Node]Node) Edge { + return target.NewEdge(nodeMap[edge.GetFrom()], nodeMap[edge.GetTo()], edge.GetLabel(), copyProperties(edge, clonePropertyFunc)) +} diff --git a/graph/dotrenderer.go b/graph/dotrenderer.go new file mode 100644 index 0000000..17b0e93 --- /dev/null +++ b/graph/dotrenderer.go @@ -0,0 +1,104 @@ +package graph + +import ( + "fmt" + "io" +) + +// DOTRenderer renders a graph in Graphviz dot format +type DOTRenderer struct { + // NodeRenderer renderes a node. If the node is to be excluded, returns false. + NodeRenderer func(string, Node, io.Writer) (bool, error) + // EdgeRenderer renders an edge. The from and to nodes are rendered + // if this is called. If the edge is to be excluded, returns false + EdgeRenderer func(fromID string, toID string, edge Edge, w io.Writer) (bool, error) +} + +// RenderNode renders a node. If node renderer is not set, calls the default renderer +func (d DOTRenderer) RenderNode(ID string, node Node, w io.Writer) (bool, error) { + if d.NodeRenderer == nil { + return true, DefaultDOTNodeRender(ID, node, w) + } + return d.NodeRenderer(ID, node, w) +} + +// RenderEdge renders an edge. If edge renderer is not set, call the default rendeded +func (d DOTRenderer) RenderEdge(fromID, toID string, edge Edge, w io.Writer) (bool, error) { + if d.EdgeRenderer == nil { + return true, DefaultDOTEdgeRender(fromID, toID, edge, w) + } + return d.EdgeRenderer(fromID, toID, edge, w) +} + +// DefaultDOTNodeRender renders the node with the given ID. If the +// node has a label, it uses that label, otherwise node is not +// labeled. +func DefaultDOTNodeRender(ID string, node Node, w io.Writer) error { + _, err := fmt.Fprintf(w, " %s;\n", ID) + return err +} + +// DefaultDOTEdgeRender renders the edge with a label if there is +// one, or without a label if there is not a label. +func DefaultDOTEdgeRender(fromNode, toNode string, edge Edge, w io.Writer) error { + lbl := edge.GetLabel() + if len(lbl) != 0 { + if _, err := fmt.Fprintf(w, " %s -> %s [label=\"%s\"];\n", fromNode, toNode, lbl); err != nil { + return err + } + } else { + if _, err := fmt.Fprintf(w, " %s -> %s;\n", fromNode, toNode); err != nil { + return err + } + } + return nil +} + +func (d DOTRenderer) RenderNodesEdges(g Graph, out io.Writer) error { + // Give nodes unique IDs for the graph + nodeMap := map[Node]string{} + x := 0 + for itr := g.GetNodes(); itr.Next(); { + node := itr.Node() + nodeId := fmt.Sprintf("n%d", x) + rendered, err := d.RenderNode(nodeId, node, out) + if err != nil { + return err + } + if rendered { + x++ + nodeMap[node] = nodeId + } + } + for edgeItr := g.GetEdges(); edgeItr.Next(); { + edge := edgeItr.Edge() + fromNodeId, ok1 := nodeMap[edge.GetFrom()] + toNodeId, ok2 := nodeMap[edge.GetTo()] + if ok1 && ok2 { + _, err := d.RenderEdge(fromNodeId, toNodeId, edge, out) + if err != nil { + return err + } + } + } + return nil +} + +// Render writes a DOT graph with the given name +func (d DOTRenderer) Render(g Graph, graphName string, out io.Writer) error { + if _, err := fmt.Fprintf(out, "digraph %s {\n", graphName); err != nil { + return err + } + if _, err := fmt.Fprintf(out, "rankdir=\"LR\";\n"); err != nil { + return err + } + + if err := d.RenderNodesEdges(g, out); err != nil { + return err + } + + if _, err := fmt.Fprintf(out, "}\n"); err != nil { + return err + } + return nil +} diff --git a/graph/indexes.go b/graph/indexes.go new file mode 100644 index 0000000..2a62fa1 --- /dev/null +++ b/graph/indexes.go @@ -0,0 +1,237 @@ +// Copyright 2021 Cloud Privacy Labs, LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package graph + +import ( + "github.com/emirpasic/gods/sets/linkedhashset" + "github.com/emirpasic/gods/trees/btree" +) + +// A setTree is a B-Tree of linkedhashsets +type setTree struct { + tree *btree.Tree +} + +func (s *setTree) add(key interface{}, item interface{}) { + if s.tree == nil { + s.tree = btree.NewWith(16, ComparePropertyValue) + } + v, found := s.tree.Get(key) + if !found { + v = linkedhashset.New() + s.tree.Put(key, v) + } + set := v.(*linkedhashset.Set) + set.Add(item) +} + +func (s setTree) remove(key interface{}, item interface{}) { + if s.tree == nil { + return + } + v, found := s.tree.Get(key) + if !found { + return + } + set := v.(*linkedhashset.Set) + set.Remove(item) + if set.Size() == 0 { + s.tree.Remove(key) + } +} + +// find returns the iterator and expected size. +func (s setTree) find(key interface{}) Iterator { + if s.tree == nil { + return emptyIterator{} + } + v, found := s.tree.Get(key) + if !found { + return emptyIterator{} + } + set := v.(*linkedhashset.Set) + itr := set.Iterator() + return withSize(&itr, set.Size()) +} + +func (s setTree) valueItr() Iterator { + if s.tree == nil { + return emptyIterator{} + } + treeItr := s.tree.Iterator() + return &funcIterator{ + iteratorFunc: func() Iterator { + if !treeItr.Next() { + return nil + } + set := treeItr.Value().(*linkedhashset.Set) + itr := set.Iterator() + return withSize(&itr, set.Size()) + }, + } +} + +type graphIndex struct { + nodesByLabel NodeMap + + nodeProperties map[string]*setTree + edgeProperties map[string]*setTree +} + +// NodePropertyIndex sets up an index for the given node property +func (g *graphIndex) NodePropertyIndex(propertyName string, graph Graph) { + if g.nodeProperties == nil { + g.nodeProperties = make(map[string]*setTree) + } + _, exists := g.nodeProperties[propertyName] + if exists { + return + } + index := &setTree{} + g.nodeProperties[propertyName] = index + // Reindex + for nodes := graph.GetNodes(); nodes.Next(); { + node := nodes.Node().(*OCNode) + value, ok := node.Properties[propertyName] + if ok { + index.add(value, node) + } + } +} + +func (g *graphIndex) IsNodePropertyIndexed(propertyName string) bool { + if g == nil || g.nodeProperties == nil { + return false + } + _, indexed := g.nodeProperties[propertyName] + return indexed +} + +func (g *graphIndex) IsEdgePropertyIndexed(propertyName string) bool { + if g == nil || g.edgeProperties == nil { + return false + } + _, indexed := g.edgeProperties[propertyName] + return indexed +} + +// GetIteratorForNodeProperty returns an iterator for the given +// key/value, and the max size of the resultset. If no index found, +// returns nil,-1 +func (g *graphIndex) GetIteratorForNodeProperty(key string, value interface{}) NodeIterator { + index, found := g.nodeProperties[key] + if !found { + return nil + } + itr := index.find(value) + return &nodeIterator{itr} +} + +// NodesWithProperty returns an iterator that will go through the +// nodes that has the property +func (g *graphIndex) NodesWithProperty(key string) NodeIterator { + index, found := g.nodeProperties[key] + if !found { + return nil + } + return &nodeIterator{index.valueItr()} +} + +// EdgesWithProperty returns an iterator that will go through the +// edges that has the property +func (g *graphIndex) EdgesWithProperty(key string) EdgeIterator { + index, found := g.edgeProperties[key] + if !found { + return nil + } + return &edgeIterator{index.valueItr()} +} + +func (g *graphIndex) addNodeToIndex(node *OCNode) { + g.nodesByLabel.Add(node) + + for k, v := range node.Properties { + index, found := g.nodeProperties[k] + if !found { + continue + } + index.add(v, node) + } +} + +func (g *graphIndex) removeNodeFromIndex(node *OCNode) { + g.nodesByLabel.Remove(node) + + for k, v := range node.Properties { + index, found := g.nodeProperties[k] + if !found { + continue + } + index.remove(v, node) + } +} + +// EdgePropertyIndex sets up an index for the given edge property +func (g *graphIndex) EdgePropertyIndex(propertyName string, graph Graph) { + if g.edgeProperties == nil { + g.edgeProperties = make(map[string]*setTree) + } + _, exists := g.edgeProperties[propertyName] + if exists { + return + } + index := &setTree{} + g.edgeProperties[propertyName] = index + // Reindex + for edges := graph.GetEdges(); edges.Next(); { + edge := edges.Edge().(*OCEdge) + value, ok := edge.Properties[propertyName] + if ok { + index.add(value, edge) + } + } +} + +func (g *graphIndex) addEdgeToIndex(edge *OCEdge) { + for k, v := range edge.Properties { + index, found := g.edgeProperties[k] + if !found { + continue + } + index.add(v, edge) + } +} + +func (g *graphIndex) removeEdgeFromIndex(edge *OCEdge) { + for k, v := range edge.Properties { + index, found := g.edgeProperties[k] + if !found { + continue + } + index.remove(v, edge) + } +} + +// GetIteratorForEdgeProperty returns an iterator for the given +// key/value, and the max size of the resultset. If no index found, +// returns nil,-1 +func (g *graphIndex) GetIteratorForEdgeProperty(key string, value interface{}) EdgeIterator { + index, found := g.edgeProperties[key] + if !found { + return nil + } + itr := index.find(value) + return &edgeIterator{itr} +} diff --git a/graph/indexes_test.go b/graph/indexes_test.go new file mode 100644 index 0000000..5750198 --- /dev/null +++ b/graph/indexes_test.go @@ -0,0 +1,32 @@ +package graph + +import ( + "fmt" + "testing" +) + +func TestNodeIndex(t *testing.T) { + g := NewOCGraph() + g.index.NodePropertyIndex("index", g) + labels := []string{"a", "b", "c", "d", "e", "f"} + data := make(map[string]struct{}) + for _, l := range labels { + for i := 0; i < 10; i++ { + g.NewNode([]string{l}, map[string]interface{}{"index": fmt.Sprint(i)}) + data[fmt.Sprintf("%s:%d", l, i)] = struct{}{} + } + } + itr := g.index.GetIteratorForNodeProperty("index", "0") + if size := itr.MaxSize(); size != 6 { + t.Errorf("Expecting 6, got %d", size) + } + foundLabel := make(map[string]struct{}) + for itr.Next() { + foundLabel[itr.Node().GetLabels().Slice()[0]] = struct{}{} + } + for _, l := range labels { + if _, found := foundLabel[l]; !found { + t.Errorf("Not found: %s", l) + } + } +} diff --git a/graph/itr.go b/graph/itr.go new file mode 100644 index 0000000..223916c --- /dev/null +++ b/graph/itr.go @@ -0,0 +1,193 @@ +// Copyright 2021 Cloud Privacy Labs, LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package graph + +import ( + "container/list" +) + +type emptyIterator struct{} + +func (emptyIterator) Next() bool { return false } +func (emptyIterator) Value() interface{} { return nil } +func (emptyIterator) MaxSize() int { return 0 } + +// filterIterator filters the items of the underlying iterator +type filterIterator struct { + itr Iterator + filter func(interface{}) bool + current interface{} +} + +func (itr *filterIterator) Next() bool { + for itr.itr.Next() { + itr.current = itr.itr.Value() + if itr.filter(itr.current) { + return true + } + itr.current = nil + } + return false +} + +func (itr *filterIterator) Value() interface{} { + return itr.current +} + +func (itr *filterIterator) MaxSize() int { return itr.itr.MaxSize() } + +// makeUniqueIterator returns a filter iterator that will filter out duplicates +func makeUniqueIterator(itr Iterator) Iterator { + seenItems := make(map[interface{}]struct{}) + return &filterIterator{ + itr: itr, + filter: func(item interface{}) bool { + if _, seen := seenItems[item]; seen { + return false + } + seenItems[item] = struct{}{} + return true + }, + } +} + +// funcIterator iterates through a set of underlying iterators obtained from a function +type funcIterator struct { + // Returns a new iterator every time it is called. When returns nil, iteration stops + iteratorFunc func() Iterator + current Iterator +} + +func (itr *funcIterator) Next() bool { + for { + if itr.current != nil { + if itr.current.Next() { + return true + } + itr.current = nil + } + itr.current = itr.iteratorFunc() + if itr.current == nil { + return false + } + } +} + +func (itr *funcIterator) Value() interface{} { + return itr.current.Value() +} + +func (itr *funcIterator) MaxSize() int { return -1 } + +// MultiIterator returns an iterator that contatenates all the given iterators +func MultiIterator(iterators ...Iterator) Iterator { + return &funcIterator{ + iteratorFunc: func() Iterator { + if len(iterators) == 0 { + return nil + } + ret := iterators[0] + iterators = iterators[1:] + return ret + }, + } +} + +// nodeIterator is a type-safe iterator for nodes +type nodeIterator struct { + Iterator +} + +func (n *nodeIterator) Node() Node { + return n.Value().(Node) +} + +// edgeIterator is a type-safe iterator for edges +type edgeIterator struct { + Iterator +} + +func (n *edgeIterator) Edge() Edge { + return n.Value().(Edge) +} + +type arrEdgeIterator struct { + edges []Edge + current Edge +} + +func (n *arrEdgeIterator) Next() bool { + if len(n.edges) == 0 { + return false + } + n.current = n.edges[0] + n.edges = n.edges[1:] + return true +} + +func (n *arrEdgeIterator) Value() interface{} { + return n.current +} + +func (n *arrEdgeIterator) Edge() Edge { + return n.current +} + +func (n *arrEdgeIterator) MaxSize() int { + return len(n.edges) +} + +func NewEdgeIterator(edges ...Edge) EdgeIterator { + return &arrEdgeIterator{edges: edges} +} + +type iteratorWithoutSize interface { + Next() bool + Value() interface{} +} + +type iteratorWithSize struct { + itr iteratorWithoutSize + size int +} + +func (i *iteratorWithSize) Next() bool { return i.itr.Next() } +func (i *iteratorWithSize) Value() interface{} { return i.itr.Value() } +func (i *iteratorWithSize) MaxSize() int { return i.size } + +func withSize(itr iteratorWithoutSize, size int) Iterator { + return &iteratorWithSize{ + itr: itr, + size: size} +} + +type listIterator struct { + next, current *list.Element + size int +} + +func (l *listIterator) Next() bool { + l.current = l.next + if l.next != nil { + l.next = l.next.Next() + } + return l.current != nil +} + +func (l *listIterator) Value() interface{} { + return l.current.Value +} + +func (l *listIterator) MaxSize() int { return l.size } diff --git a/graph/maps.go b/graph/maps.go new file mode 100644 index 0000000..23e0adc --- /dev/null +++ b/graph/maps.go @@ -0,0 +1,308 @@ +// Copyright 2021 Cloud Privacy Labs, LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package graph + +import ( + "github.com/emirpasic/gods/maps/linkedhashmap" + "github.com/emirpasic/gods/sets/linkedhashset" +) + +// An EdgeMap stores edges indexed by edge label +type EdgeMap struct { + // m[string]*linkedhashset + m *linkedhashmap.Map + n int +} + +func (em *EdgeMap) Add(edge *OCEdge) { + if em.m == nil { + em.m = linkedhashmap.New() + } + + var set *linkedhashset.Set + v, found := em.m.Get(edge.label) + if !found { + set = linkedhashset.New() + em.m.Put(edge.label, set) + } else { + set = v.(*linkedhashset.Set) + } + k := set.Size() + set.Add(edge) + if set.Size() > k { + em.n++ + } +} + +func (em EdgeMap) Remove(edge *OCEdge) { + if em.m == nil { + return + } + var set *linkedhashset.Set + v, found := em.m.Get(edge.label) + if !found { + return + } + set = v.(*linkedhashset.Set) + k := set.Size() + set.Remove(edge) + if set.Size() < k { + em.n-- + } + if set.Size() == 0 { + em.m.Remove(edge.label) + } +} + +func (em EdgeMap) IsEmpty() bool { + if em.m == nil { + return true + } + if em.m.Size() == 0 { + return true + } + return false +} + +func (em EdgeMap) Len() int { return em.n } + +type edgeMapIterator struct { + labels iteratorWithoutSize + current EdgeIterator + size int +} + +func (itr *edgeMapIterator) Next() bool { + if itr.current != nil { + if itr.current.Next() { + return true + } + itr.current = nil + } + if itr.labels == nil { + return false + } + if !itr.labels.Next() { + return false + } + set := itr.labels.Value().(*linkedhashset.Set) + setItr := set.Iterator() + itr.current = &edgeIterator{withSize(&setItr, -1)} + itr.current.Next() + return true +} + +func (itr *edgeMapIterator) Value() interface{} { + return itr.current.Value() +} + +func (itr *edgeMapIterator) Edge() Edge { + return itr.current.Edge() +} + +func (itr *edgeMapIterator) MaxSize() int { return itr.size } + +func (em EdgeMap) Iterator() EdgeIterator { + if em.m == nil { + return &edgeIterator{&emptyIterator{}} + } + i := em.m.Iterator() + return &edgeMapIterator{labels: &i, size: em.Len()} +} + +func (em EdgeMap) IteratorLabel(label string) EdgeIterator { + if em.m == nil { + return &edgeIterator{&emptyIterator{}} + } + v, found := em.m.Get(label) + if !found { + return &edgeIterator{&emptyIterator{}} + } + set := v.(*linkedhashset.Set) + i := set.Iterator() + return &edgeIterator{withSize(&i, set.Size())} +} + +func (em EdgeMap) IteratorAnyLabel(labels StringSet) EdgeIterator { + if em.m == nil { + return &edgeIterator{&emptyIterator{}} + } + strings := labels.Slice() + return &edgeIterator{&funcIterator{ + iteratorFunc: func() Iterator { + for len(strings) != 0 { + v, found := em.m.Get(strings[0]) + strings = strings[1:] + if !found { + continue + } + itr := v.(*linkedhashset.Set).Iterator() + return withSize(&itr, -1) + } + return nil + }, + }, + } +} + +// An NodeMap stores nodes indexed by node labels +type NodeMap struct { + // m[string]*FastSet + m *linkedhashmap.Map + nolabels FastSet +} + +func (nm *NodeMap) Add(node *OCNode) { + if nm.m == nil { + nm.m = linkedhashmap.New() + } + if len(node.labels) == 0 { + nm.nolabels.Add(node) + return + } + + var set *FastSet + for label := range node.labels { + v, found := nm.m.Get(label) + if !found { + set = &FastSet{} + nm.m.Put(label, set) + } else { + set = v.(*FastSet) + } + set.Add(node) + } +} + +func (nm NodeMap) Remove(node *OCNode) { + if nm.m == nil { + return + } + if len(node.labels) == 0 { + nm.nolabels.Remove(node) + return + } + var set *FastSet + for label := range node.labels { + v, found := nm.m.Get(label) + if !found { + continue + } + set = v.(*FastSet) + set.Remove(node) + if set.Len() == 0 { + nm.m.Remove(label) + } + } +} + +func (nm NodeMap) IsEmpty() bool { + if nm.m == nil { + return true + } + if nm.m.Size() == 0 { + return true + } + return false +} + +type nodeMapIterator struct { + labels *linkedhashmap.Iterator + seenLabels []string + current NodeIterator +} + +func (itr *nodeMapIterator) Next() bool { + if itr.current != nil { + if itr.current.Next() { + return true + } + itr.current = nil + } + if itr.labels == nil { + return false + } + if !itr.labels.Next() { + return false + } + itr.seenLabels = append(itr.seenLabels, itr.labels.Key().(string)) + set := itr.labels.Value().(*FastSet) + setItr := set.Iterator() + itr.current = &nodeIterator{withSize(setItr, -1)} + itr.current.Next() + return true +} + +func (itr *nodeMapIterator) Value() interface{} { + return itr.current.Value() +} + +func (itr *nodeMapIterator) Node() Node { + return itr.current.Node() +} + +func (nm NodeMap) Iterator() NodeIterator { + if nm.m == nil { + return &nodeIterator{&emptyIterator{}} + } + i := nm.m.Iterator() + + nmIterator := &nodeMapIterator{labels: &i} + return &nodeIterator{ + MultiIterator( + &filterIterator{ + itr: withSize(nmIterator, -1), + filter: func(node interface{}) bool { + onode := node.(*OCNode) + nSeen := 0 + for _, l := range nmIterator.seenLabels { + if onode.labels.Has(l) { + nSeen++ + } + } + return nSeen < 2 + }, + }, + nm.nolabels.Iterator(), + ), + } +} + +func (nm NodeMap) IteratorAllLabels(labels StringSet) NodeIterator { + if nm.m == nil { + return &nodeIterator{&emptyIterator{}} + } + // Find the smallest map element, iterate that + var minSet *FastSet + for label := range labels { + v, found := nm.m.Get(label) + if !found { + return &nodeIterator{&emptyIterator{}} + } + mp := v.(*FastSet) + if minSet == nil || minSet.Len() > mp.Len() { + minSet = mp + } + } + itr := minSet.Iterator() + flt := &filterIterator{ + itr: withSize(itr, minSet.Len()), + filter: func(item interface{}) bool { + onode := item.(*OCNode) + return onode.labels.HasAllSet(labels) + }, + } + return &nodeIterator{flt} +} diff --git a/graph/maps_test.go b/graph/maps_test.go new file mode 100644 index 0000000..f301669 --- /dev/null +++ b/graph/maps_test.go @@ -0,0 +1,101 @@ +package graph + +import ( + "fmt" + "testing" +) + +func TestEdgeMap(t *testing.T) { + m := EdgeMap{} + labels := []string{"a", "b", "c", "d", "e", "f"} + data := make(map[string]struct{}) + for _, l := range labels { + for i := 0; i < 10; i++ { + edge := &OCEdge{label: l} + edge.Properties = make(Properties) + edge.Properties["index"] = i + m.Add(edge) + data[fmt.Sprintf("%s:%d", l, i)] = struct{}{} + } + } + // itr: 60 items + itr := m.Iterator() + found := make(map[string]struct{}) + for itr.Next() { + edge := itr.Edge().(*OCEdge) + found[fmt.Sprintf("%s:%d", edge.label, edge.Properties["index"])] = struct{}{} + } + if len(found) != len(data) { + t.Errorf("found: %v", found) + } + + // Label-based iteration + for _, label := range labels { + itr = m.IteratorLabel(label) + found = make(map[string]struct{}) + for itr.Next() { + edge := itr.Edge().(*OCEdge) + if edge.label != label { + t.Errorf("Expecting %s got %+v", label, edge) + } + found[fmt.Sprint(edge.Properties["index"])] = struct{}{} + } + if len(found) != 10 { + t.Errorf("10 entries were expected, got %v", found) + } + } + + itr = m.IteratorAnyLabel(NewStringSet("a", "c", "e", "g")) + found = make(map[string]struct{}) + for itr.Next() { + edge := itr.Edge().(*OCEdge) + if edge.label != "a" && edge.label != "c" && edge.label != "e" { + t.Errorf("Unexpected label: %s", edge.label) + } + found[fmt.Sprintf("%s:%d", edge.label, edge.Properties["index"])] = struct{}{} + } + if len(found) != 30 { + t.Errorf("Expecting 30, got %v", found) + } +} + +func TestNodeMap(t *testing.T) { + m := NodeMap{} + labels := [][]string{{"a"}, {"b", "c", "d"}, {"e", "f"}} + data := make(map[string]struct{}) + for _, l := range labels { + for i := 0; i < 10; i++ { + node := &OCNode{labels: NewStringSet(l...)} + node.Properties = make(Properties) + node.Properties["index"] = i + m.Add(node) + data[fmt.Sprintf("%d:%d", len(l), i)] = struct{}{} + } + } + // itr: 30 items + itr := m.Iterator() + found := make(map[string]struct{}) + for itr.Next() { + node := itr.Node().(*OCNode) + found[fmt.Sprintf("%d:%d", len(node.labels), node.Properties["index"])] = struct{}{} + } + if len(found) != len(data) { + t.Errorf("found: %v", found) + } + + // Label-based iteration + for _, label := range labels { + itr = m.IteratorAllLabels(NewStringSet(label...)) + found = make(map[string]struct{}) + for itr.Next() { + node := itr.Node().(*OCNode) + if !node.labels.HasAll(label...) { + t.Errorf("Expecting %v got %+v", label, node) + } + found[fmt.Sprint(node.Properties["index"])] = struct{}{} + } + if len(found) != 10 { + t.Errorf("10 entries were expected, got %v", found) + } + } +} diff --git a/graph/model.go b/graph/model.go new file mode 100644 index 0000000..24b553c --- /dev/null +++ b/graph/model.go @@ -0,0 +1,172 @@ +// Copyright 2021 Cloud Privacy Labs, LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package graph + +// An Iterator iterates the items of a collection +type Iterator interface { + // Next moves to the next item in the iterator, and returns true if + // move was successful. If there are no next items remaining, returns false + Next() bool + + // Value returns the current item in the iterator. This is undefined + // before the first call to Next, and after Next returns false. + Value() interface{} + + // MaxSize returns an estimation of maximum number of elements. If unknown, returns -1 + MaxSize() int +} + +// NodeIterator iterates nodes of an underlying list +type NodeIterator interface { + Iterator + // Returns the current node + Node() Node +} + +// NodeSlice reads all the remaining items of a node iterator and returns them in a slice +func NodeSlice(in NodeIterator) []Node { + ret := make([]Node, 0) + for in.Next() { + ret = append(ret, in.Node()) + } + return ret +} + +// EdgeIterator iterates the edges of an underlying list +type EdgeIterator interface { + Iterator + // Returns the current edge + Edge() Edge +} + +// EdgeSlice reads all the remaining items of an edge iterator and returns them in a slice +func EdgeSlice(in EdgeIterator) []Edge { + ret := make([]Edge, 0) + for in.Next() { + ret = append(ret, in.Edge()) + } + return ret +} + +// TargetNodes returns the target nodes of all edges +func TargetNodes(in EdgeIterator) []Node { + set := make(map[Node]struct{}) + for in.Next() { + set[in.Edge().GetTo()] = struct{}{} + } + ret := make([]Node, 0, len(set)) + for x := range set { + ret = append(ret, x) + } + return ret +} + +// SourceNodes returns the source nodes of all edges +func SourceNodes(in EdgeIterator) []Node { + set := make(map[Node]struct{}) + for in.Next() { + set[in.Edge().GetFrom()] = struct{}{} + } + ret := make([]Node, 0, len(set)) + for x := range set { + ret = append(ret, x) + } + return ret +} + +// EdgeDir is used to show edge direction +type EdgeDir int + +// Incoming and outgoing edge direction constants +const ( + IncomingEdge EdgeDir = -1 + OutgoingEdge EdgeDir = 1 +) + +// Node represents a graph node. A node is owned by a graph +type Node interface { + GetGraph() Graph + + GetLabels() StringSet + SetLabels(StringSet) + + GetProperty(string) (interface{}, bool) + SetProperty(string, interface{}) + RemoveProperty(string) + + // Iterate properties until function returns false. Returns false if + // function returns false, true if all properties are iterated (may be none) + ForEachProperty(func(string, interface{}) bool) bool + + // Remove all connected edges, and remove the node + DetachAndRemove() + // Remove all connected edges + Detach() + + // Returns an edge iterator for incoming or outgoing edges + GetEdges(EdgeDir) EdgeIterator + // Returns an edge iterator for incoming or outgoing edges with the given label + GetEdgesWithLabel(EdgeDir, string) EdgeIterator + // Returns an edge iterator for incoming or outgoingn edges that has the given labels + GetEdgesWithAnyLabel(EdgeDir, StringSet) EdgeIterator +} + +// NextNodesWith returns the nodes reachable from source with the given label at one step +func NextNodesWith(source Node, label string) []Node { + return TargetNodes(source.GetEdgesWithLabel(OutgoingEdge, label)) +} + +// PrevNodesWith returns the nodes reachable from source with the given label at one step +func PrevNodesWith(source Node, label string) []Node { + return SourceNodes(source.GetEdgesWithLabel(IncomingEdge, label)) +} + +type Edge interface { + GetGraph() Graph + + GetLabel() string + SetLabel(string) + + GetFrom() Node + GetTo() Node + + GetProperty(string) (interface{}, bool) + SetProperty(string, interface{}) + RemoveProperty(string) + // Iterate properties until function returns false. Returns false if + // function returns false, true if all properties are iterated (may be none) + ForEachProperty(func(string, interface{}) bool) bool + + // Remove an edge + Remove() +} + +// A Graph is a collection of nodes and edges. +type Graph interface { + NewNode(labels []string, properties map[string]interface{}) Node + + // NewEdge will add the nodes to the graph if they are not in the graph, and connect them + NewEdge(from, to Node, label string, properties map[string]interface{}) Edge + + GetNodes() NodeIterator + GetNodesWithAllLabels(StringSet) NodeIterator + GetNodesWithProperty(string) NodeIterator + NumNodes() int + + GetEdges() EdgeIterator + GetEdgesWithAnyLabel(StringSet) EdgeIterator + GetEdgesWithProperty(string) EdgeIterator + NumEdges() int +} diff --git a/graph/ocedge.go b/graph/ocedge.go new file mode 100644 index 0000000..5a94957 --- /dev/null +++ b/graph/ocedge.go @@ -0,0 +1,45 @@ +// Copyright 2021 Cloud Privacy Labs, LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package graph + +type OCEdge struct { + id int + from, to *OCNode + label string + Properties + graph *OCGraph +} + +func (edge *OCEdge) GetGraph() Graph { return edge.graph } +func (edge *OCEdge) GetLabel() string { return edge.label } +func (edge *OCEdge) GetFrom() Node { return edge.from } +func (edge *OCEdge) GetTo() Node { return edge.to } + +func (edge *OCEdge) SetLabel(label string) { + edge.graph.SetEdgeLabel(edge, label) +} + +func (edge *OCEdge) SetProperty(key string, value interface{}) { + edge.graph.SetEdgeProperty(edge, key, value) +} + +func (edge *OCEdge) RemoveProperty(key string) { + edge.graph.RemoveEdgeProperty(edge, key) +} + +// Remove an edge +func (edge *OCEdge) Remove() { + edge.graph.RemoveEdge(edge) +} diff --git a/graph/ocgraph.go b/graph/ocgraph.go new file mode 100644 index 0000000..4f43d84 --- /dev/null +++ b/graph/ocgraph.go @@ -0,0 +1,448 @@ +// Copyright 2021 Cloud Privacy Labs, LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package graph + +type OCGraph struct { + index *graphIndex + store OCStore + idBase int +} + +func NewOCGraph() *OCGraph { + return &OCGraph{ + store: *NewOCStore(), + index: &graphIndex{}, + } +} + +// NewNode creates a new node with the given labels and properties +func (g *OCGraph) NewNode(labels []string, properties map[string]interface{}) Node { + return g.NewOCNode(labels, properties) +} + +// NewOCNode creates a new node with the given labels and properties +func (g *OCGraph) NewOCNode(labels []string, properties map[string]interface{}) *OCNode { + node := &OCNode{id: g.idBase, labels: NewStringSet(labels...), Properties: Properties(properties), graph: g} + g.idBase++ + g.addNode(node) + return node +} + +func (g *OCGraph) addNode(node *OCNode) { + g.store.AddNode(node) + if g.index != nil { + g.index.addNodeToIndex(node) + } +} + +func (g *OCGraph) SetNodeLabels(node *OCNode, labels StringSet) { + if g.index != nil { + g.index.removeNodeFromIndex(node) + } + node.labels = labels.Clone() + if g.index != nil { + g.index.addNodeToIndex(node) + } +} + +func (g *OCGraph) SetNodeProperty(node *OCNode, key string, value interface{}) { + if node.Properties == nil { + node.Properties = make(Properties) + } + indexed := g.index.IsNodePropertyIndexed(key) + if indexed { + g.index.removeNodeFromIndex(node) + } + node.Properties[key] = value + if indexed { + g.index.addNodeToIndex(node) + } +} + +func (g *OCGraph) RemoveNodeProperty(node *OCNode, key string) { + if node.Properties == nil { + return + } + if g.index.IsNodePropertyIndexed(key) { + g.index.removeNodeFromIndex(node) + } + delete(node.Properties, key) +} + +func (g *OCGraph) DetachRemoveNode(node *OCNode) { + g.store.DetachRemoveNode(node) + if g.index != nil { + g.index.removeNodeFromIndex(node) + } +} + +func (g *OCGraph) DetachNode(node *OCNode) { + g.store.DetachNode(node) +} + +func (g *OCGraph) NewEdge(from, to Node, label string, properties map[string]interface{}) Edge { + ofrom := from.(*OCNode) + oto := to.(*OCNode) + if ofrom.graph != g { + panic("from node is not in graph") + } + if oto.graph != g { + panic("to node is not in graph") + } + newEdge := &OCEdge{ + id: g.idBase, + from: ofrom, + to: oto, + label: label, + Properties: Properties(properties), + graph: g, + } + g.idBase++ + g.store.AddEdge(newEdge) + return newEdge +} + +func (g *OCGraph) connect(edge *OCEdge) { + g.store.connect(edge) +} + +func (g *OCGraph) disconnect(edge *OCEdge) { + g.store.disconnect(edge) +} + +func (g *OCGraph) SetEdgeLabel(edge *OCEdge, label string) { + g.disconnect(edge) + edge.label = label + g.connect(edge) +} + +func (g *OCGraph) RemoveEdge(edge *OCEdge) { + g.store.RemoveEdge(edge) +} + +func (g *OCGraph) SetEdgeProperty(edge *OCEdge, key string, value interface{}) { + if edge.Properties == nil { + edge.Properties = make(Properties) + } + indexed := g.index.IsEdgePropertyIndexed(key) + if indexed { + g.index.removeEdgeFromIndex(edge) + } + edge.Properties[key] = value + if indexed { + g.index.addEdgeToIndex(edge) + } +} + +func (g *OCGraph) RemoveEdgeProperty(edge *OCEdge, key string) { + if edge.Properties == nil { + return + } + if g.index.IsEdgePropertyIndexed(key) { + g.index.removeEdgeFromIndex(edge) + } + delete(edge.Properties, key) +} + +func (g *OCGraph) NumNodes() int { + return g.store.NumNodes() +} + +func (g *OCGraph) NumEdges() int { + return g.store.NumEdges() +} + +func (g *OCGraph) GetNodes() NodeIterator { + return g.store.GetNodes() +} + +func (g *OCGraph) GetNodesWithAllLabels(labels StringSet) NodeIterator { + return g.index.nodesByLabel.IteratorAllLabels(labels) +} + +func (g *OCGraph) GetEdges() EdgeIterator { + return g.store.GetEdges() +} + +func (g *OCGraph) GetEdgesWithAnyLabel(set StringSet) EdgeIterator { + return g.store.GetEdgesWithAnyLabel(set) +} + +func (g *OCGraph) GetNodeEdges(node Node, dir EdgeDir) EdgeIterator { + onode := node.(*OCNode) + return g.store.GetNodeEdges(onode, dir) +} + +func (g *OCGraph) GetNodeEdgesWithLabel(node Node, dir EdgeDir, label string) EdgeIterator { + onode := node.(*OCNode) + return g.store.GetNodeEdgesWithLabel(onode, dir, label) +} + +func (g *OCGraph) GetNodeEdgesWithAnyLabel(node Node, dir EdgeDir, set StringSet) EdgeIterator { + onode := node.(*OCNode) + return g.store.GetNodeEdgesWithAnyLabel(onode, dir, set) +} + +// FindNodes returns an iterator that will iterate through all the +// nodes that have all of the given labels and properties. If +// allLabels is nil or empty, it does not look at the labels. If +// properties is nil or empty, it does not look at the properties +func (g *OCGraph) FindNodes(allLabels StringSet, properties map[string]interface{}) NodeIterator { + if len(allLabels) == 0 && len(properties) == 0 { + // Return all nodes + return g.GetNodes() + } + + var nodesByLabelItr NodeIterator + if len(allLabels) > 0 { + nodesByLabelItr = g.index.nodesByLabel.IteratorAllLabels(allLabels) + } + // Select the iterator with minimum max size + nodesByLabelSize := nodesByLabelItr.MaxSize() + propertyIterators := make(map[string]NodeIterator) + if len(properties) > 0 { + for k, v := range properties { + itr := g.index.GetIteratorForNodeProperty(k, v) + if itr == nil { + continue + } + propertyIterators[k] = itr + } + } + var minimumPropertyItrKey string + minPropertySize := -1 + for k, itr := range propertyIterators { + maxSize := itr.MaxSize() + if maxSize == -1 { + continue + } + if minPropertySize == -1 || minPropertySize > maxSize { + minPropertySize = maxSize + minimumPropertyItrKey = k + } + } + + nodeFilterFunc := GetNodeFilterFunc(allLabels, properties) + // Iterate the minimum iterator, with a filter + if nodesByLabelSize != -1 && (minPropertySize == -1 || minPropertySize > nodesByLabelSize) { + // Iterate by node label + // build a filter from properties + return &nodeIterator{ + &filterIterator{ + itr: nodesByLabelItr, + filter: func(item interface{}) bool { + return nodeFilterFunc(item.(Node)) + }, + }, + } + } + if minPropertySize != -1 { + // Iterate by property + return &nodeIterator{ + &filterIterator{ + itr: propertyIterators[minimumPropertyItrKey], + filter: func(item interface{}) bool { + return nodeFilterFunc(item.(Node)) + }, + }, + } + } + // Iterate all + return g.GetNodes() +} + +// AddEdgePropertyIndex adds an index for the given edge property +func (g *OCGraph) AddEdgePropertyIndex(propertyName string) { + g.index.EdgePropertyIndex(propertyName, g) +} + +// AddNodePropertyIndex adds an index for the given node property +func (g *OCGraph) AddNodePropertyIndex(propertyName string) { + g.index.NodePropertyIndex(propertyName, g) +} + +// GetNodesWithProperty returns an iterator for the nodes that has the property +func (g *OCGraph) GetNodesWithProperty(property string) NodeIterator { + itr := g.index.NodesWithProperty(property) + if itr != nil { + return itr + } + return &nodeIterator{&filterIterator{ + itr: g.GetNodes(), + filter: func(v interface{}) bool { + wp, ok := v.(Node) + if !ok { + return false + } + _, exists := wp.GetProperty(property) + return exists + }, + }} +} + +// GetEdgesWithProperty returns an iterator for the edges that has the property +func (g *OCGraph) GetEdgesWithProperty(property string) EdgeIterator { + itr := g.index.EdgesWithProperty(property) + if itr != nil { + return itr + } + return &edgeIterator{&filterIterator{ + itr: g.GetEdges(), + filter: func(v interface{}) bool { + wp, ok := v.(Edge) + if !ok { + return false + } + _, exists := wp.GetProperty(property) + return exists + }, + }} + +} + +// FindEdges returns an iterator that will iterate through all the +// edges whose label is in the given labels and have all the +// properties. If labels is nil or empty, it does not look at the +// labels. If properties is nil or empty, it does not look at the +// properties +func (g *OCGraph) FindEdges(labels StringSet, properties map[string]interface{}) EdgeIterator { + if len(labels) == 0 && len(properties) == 0 { + // Return all edges + return g.GetEdges() + } + + var edgesByLabelItr EdgeIterator + if len(labels) > 0 { + edgesByLabelItr = g.GetEdgesWithAnyLabel(labels) + } + // Select the iterator with minimum max size + edgesByLabelSize := edgesByLabelItr.MaxSize() + propertyIterators := make(map[string]EdgeIterator) + if len(properties) > 0 { + for k, v := range properties { + itr := g.index.GetIteratorForEdgeProperty(k, v) + if itr == nil { + continue + } + propertyIterators[k] = itr + } + } + var minimumPropertyItrKey string + minPropertySize := -1 + for k, itr := range propertyIterators { + maxSize := itr.MaxSize() + if maxSize == -1 { + continue + } + if minPropertySize == -1 || minPropertySize > maxSize { + minPropertySize = maxSize + minimumPropertyItrKey = k + } + } + + edgeFilterFunc := GetEdgeFilterFunc(labels, properties) + // Iterate the minimum iterator, with a filter + if edgesByLabelSize != -1 && (minPropertySize == -1 || minPropertySize > edgesByLabelSize) { + // Iterate by edge label + // build a filter from properties + return &edgeIterator{ + &filterIterator{ + itr: edgesByLabelItr, + filter: func(item interface{}) bool { + return edgeFilterFunc(item.(Edge)) + }, + }, + } + } + if minPropertySize != -1 { + // Iterate by property + return &edgeIterator{ + &filterIterator{ + itr: propertyIterators[minimumPropertyItrKey], + filter: func(item interface{}) bool { + return edgeFilterFunc(item.(Edge)) + }, + }, + } + } + // Iterate all + return g.GetEdges() +} + +// GetNodeFilterFunc returns a function that can be used to pass +// nodes that have all the specified labels, with correct property +// values +func GetNodeFilterFunc(labels StringSet, properties map[string]interface{}) func(Node) bool { + return func(node Node) bool { + onode := node.(*OCNode) + if len(labels) > 0 { + if !onode.labels.HasAllSet(labels) { + return false + } + } + for k, v := range properties { + nodeValue, exists := onode.GetProperty(k) + if !exists { + if v != nil { + return false + } + } + if ComparePropertyValue(v, nodeValue) != 0 { + return false + } + } + return true + } +} + +// GetEdgeFilterFunc returns a function that can be used to pass edges +// that have at least one of the specified labels, with correct +// property values +func GetEdgeFilterFunc(labels StringSet, properties map[string]interface{}) func(Edge) bool { + return func(edge Edge) bool { + oedge := edge.(*OCEdge) + if len(labels) > 0 { + if !labels.Has(oedge.label) { + return false + } + } + for k, v := range properties { + edgeValue, exists := oedge.GetProperty(k) + if !exists { + if v != nil { + return false + } + } + if ComparePropertyValue(v, edgeValue) != 0 { + return false + } + } + return true + } +} + +type WithProperties interface { + GetProperty(key string) (interface{}, bool) +} + +func buildPropertyFilterFunc(key string, value interface{}) func(WithProperties) bool { + return func(properties WithProperties) bool { + pvalue, exists := properties.GetProperty(key) + if !exists { + return value == nil + } + return ComparePropertyValue(value, pvalue) == 0 + } +} diff --git a/graph/ocgraph_test.go b/graph/ocgraph_test.go new file mode 100644 index 0000000..0ba624f --- /dev/null +++ b/graph/ocgraph_test.go @@ -0,0 +1,46 @@ +// Copyright 2021 Cloud Privacy Labs, LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package graph + +import ( + "fmt" + "testing" +) + +func TestGraphCRUD(t *testing.T) { + g := NewOCGraph() + nodes := make([]Node, 0) + for i := 0; i < 10; i++ { + nodes = append(nodes, g.NewNode([]string{fmt.Sprint(i)}, nil)) + } + for i := 0; i < len(nodes)-1; i++ { + g.NewEdge(nodes[i], nodes[i+1], "e", nil) + } + + if len(NodeSlice(g.GetNodes())) != len(nodes) { + t.Errorf("Wrong node count") + } + if g.NumNodes() != len(nodes) { + t.Errorf("Wrong numNodes") + } + nodes[2].DetachAndRemove() + if len(NodeSlice(g.GetNodes())) != len(nodes)-1 { + t.Errorf("Wrong node count") + } + if g.NumNodes() != len(nodes)-1 { + t.Errorf("Wrong numNodes") + } + +} diff --git a/graph/ocnode.go b/graph/ocnode.go new file mode 100644 index 0000000..23d6b0c --- /dev/null +++ b/graph/ocnode.go @@ -0,0 +1,75 @@ +// Copyright 2021 Cloud Privacy Labs, LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package graph + +import ( + "fmt" + "strings" +) + +type OCNode struct { + id int + labels StringSet + Properties + graph *OCGraph +} + +func (node *OCNode) GetGraph() Graph { return node.graph } +func (node *OCNode) GetLabels() StringSet { return node.labels.Clone() } + +// Returns an edge iterator for incoming or outgoing edges +func (node *OCNode) GetEdges(dir EdgeDir) EdgeIterator { + return node.graph.GetNodeEdges(node, dir) +} + +// Returns an edge iterator for incoming or outgoing edges with the given label +func (node *OCNode) GetEdgesWithLabel(dir EdgeDir, label string) EdgeIterator { + return node.graph.GetNodeEdgesWithLabel(node, dir, label) +} + +// Returns an edge iterator for incoming or outgoingn edges that has the given labels +func (node *OCNode) GetEdgesWithAnyLabel(dir EdgeDir, labels StringSet) EdgeIterator { + return node.graph.GetNodeEdgesWithAnyLabel(node, dir, labels) +} + +func (node *OCNode) SetLabels(labels StringSet) { + node.graph.SetNodeLabels(node, labels) +} + +func (node *OCNode) SetProperty(key string, value interface{}) { + node.graph.SetNodeProperty(node, key, value) +} + +func (node *OCNode) RemoveProperty(key string) { + node.graph.RemoveNodeProperty(node, key) +} + +// Remove all connected edges, and remove the node +func (node *OCNode) DetachAndRemove() { + node.graph.DetachRemoveNode(node) +} + +// Remove all connected edges +func (node *OCNode) Detach() { + node.graph.DetachNode(node) +} + +func (node OCNode) String() string { + labels := strings.Join(node.labels.Slice(), ":") + if len(node.labels) > 0 { + labels = ":" + labels + } + return fmt.Sprintf("(%s %s)", labels, node.Properties) +} diff --git a/graph/pattern.go b/graph/pattern.go new file mode 100644 index 0000000..b98b711 --- /dev/null +++ b/graph/pattern.go @@ -0,0 +1,588 @@ +// Copyright 2021 Cloud Privacy Labs, LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package graph + +import () + +type ErrNodeVariableExpected string + +func (e ErrNodeVariableExpected) Error() string { + return "Node variable expected: " + string(e) +} + +type ErrEdgeVariableExpected string + +func (e ErrEdgeVariableExpected) Error() string { + return "Edge variable expected:" + string(e) +} + +// Pattern contains pattern items, with even numbered elements +// corresponding to nodes, and odd numbered elements corresponding to +// edges +type Pattern []PatternItem + +// A PatternSymbol contains either nodes, or edges. +type PatternSymbol struct { + Nodes *NodeSet + Edges *EdgeSet +} + +// A PatternItem can be a node or an edge element of a pattern +type PatternItem struct { + Labels StringSet + Properties map[string]interface{} + // Min=-1 and Max=-1 for variable length + Min int + Max int + Backwards bool + // Name of the variable associated with this processing node. If the + // name is defined, it is used to constrain values. If not, it is + // used to store values + Name string +} + +func (p PatternItem) getEdgeFilter() func(Edge) bool { + return GetEdgeFilterFunc(p.Labels, p.Properties) +} + +func (p PatternItem) getNodeFilter() func(Node) bool { + return GetNodeFilterFunc(p.Labels, p.Properties) +} + +// Returns the set of nodes constraining the pattern item. That is, +// the set of nodes in the symbols +func (p PatternItem) isConstrainedNodes(ctx *MatchContext) (*NodeSet, error) { + if len(p.Name) == 0 { + return nil, nil + } + // Is this a symbol created in this pattern? + sym, exists := ctx.LocalSymbols[p.Name] + if exists { + if sym.Edges != nil { + return nil, ErrNodeVariableExpected(p.Name) + } + return sym.Nodes, nil + } + sym, exists = ctx.Symbols[p.Name] + if exists { + if sym.Edges != nil { + return nil, ErrNodeVariableExpected(p.Name) + } + return sym.Nodes, nil + } + return nil, nil +} + +// Returns the set of edges constraining the pattern item. That is, +// the set of edges in the symbols +func (p PatternItem) isConstrainedEdges(ctx *MatchContext) (*EdgeSet, error) { + if len(p.Name) == 0 { + return nil, nil + } + // Is this a symbol created in this pattern? + sym, exists := ctx.LocalSymbols[p.Name] + if exists { + if sym.Nodes != nil { + return nil, ErrEdgeVariableExpected(p.Name) + } + return sym.Edges, nil + } + sym, exists = ctx.Symbols[p.Name] + if exists { + if sym.Nodes != nil { + return nil, ErrEdgeVariableExpected(p.Name) + } + return sym.Edges, nil + } + return nil, nil +} + +func (p PatternItem) estimateNodeSize(gr Graph, symbols map[string]*PatternSymbol) (Iterator, int) { + g := gr.(*OCGraph) + max := -1 + var ret Iterator + if len(p.Labels) > 0 { + itr := g.index.nodesByLabel.IteratorAllLabels(p.Labels) + if sz := itr.MaxSize(); sz != -1 { + max = sz + ret = itr + } + } + if len(p.Properties) > 0 { + for k, v := range p.Properties { + itr := g.index.GetIteratorForNodeProperty(k, v) + if itr == nil { + continue + } + maxSize := itr.MaxSize() + if maxSize == -1 { + continue + } + if max == -1 || maxSize < max { + max = maxSize + ret = itr + } + } + } + if len(p.Name) > 0 { + sym, ok := symbols[p.Name] + if ok { + if max == -1 || sym.Nodes.Len() < max { + max = sym.Nodes.Len() + ret = sym.Nodes.Iterator() + } + } + } + if ret == nil { + ret = g.GetNodes() + if sz := ret.MaxSize(); sz != -1 { + max = sz + } + } + return ret, max +} + +func (p PatternItem) estimateEdgeSize(gr Graph, symbols map[string]*PatternSymbol) (Iterator, int) { + g := gr.(*OCGraph) + max := -1 + var ret Iterator + + allEdges := func() (Iterator, int) { + ret := g.GetEdges() + max := -1 + if sz := ret.MaxSize(); sz != -1 { + max = sz + } + return ret, max + } + + if p.Min > 1 || p.Max > 1 || p.Min == -1 || p.Max == -1 { + return g.GetEdges(), -1 + } + + if len(p.Labels) > 0 { + itr := g.GetEdgesWithAnyLabel(p.Labels) + if sz := itr.MaxSize(); sz != -1 { + max = sz + ret = itr + } + } + if len(p.Properties) > 0 { + for k, v := range p.Properties { + itr := g.index.GetIteratorForEdgeProperty(k, v) + if itr == nil { + continue + } + maxSize := itr.MaxSize() + if maxSize == -1 { + continue + } + if maxSize < max { + max = maxSize + ret = itr + } + } + } + if len(p.Name) > 0 { + sym, ok := symbols[p.Name] + if ok { + if max == -1 || sym.Edges.Len() < max { + max = sym.Edges.Len() + ret = sym.Edges.Iterator() + } + } + } + if ret == nil { + return allEdges() + } + return ret, max +} + +func (p *PatternSymbol) Add(item interface{}) bool { + switch k := item.(type) { + case *OCNode: + p.AddNode(k) + + case *OCEdge: + if p.Edges == nil { + p.Edges = &EdgeSet{} + } + p.Edges.Add(k) + + case []Edge: + p.AddPath(k) + } + return true +} + +func (p *PatternSymbol) AddNode(item Node) { + if p.Nodes == nil { + p.Nodes = &NodeSet{} + } + p.Nodes.Add(item.(*OCNode)) +} + +func (p *PatternSymbol) AddPath(path []Edge) { + if p.Edges == nil { + p.Edges = &EdgeSet{} + } + for _, x := range path { + p.Edges.Add(x.(*OCEdge)) + } +} + +func (p *PatternSymbol) NodeSlice() []Node { + if p.Nodes != nil { + return p.Nodes.Slice() + } + return nil +} + +func (p *PatternSymbol) EdgeSlice() []Edge { + if p.Edges != nil { + return p.Edges.Slice() + } + return nil +} + +type MatchPlan struct { + steps []planProcessor +} + +type planProcessor interface { + Run(*MatchContext, matchAccumulator) error + GetResult() interface{} + GetPatternItem() PatternItem +} + +type MatchAccumulator interface { + // path is either a Node or []Edge, the matching path symbols + // contains the current values for each symbol. The values of the + // map is either Node or []Edge + StoreResult(ctx *MatchContext, path interface{}, symbols map[string]interface{}) +} + +type MatchContext struct { + Graph Graph + // These are symbols that are used as constraints in the matching process. + Symbols map[string]*PatternSymbol + + // localSymbols are symbols defined in the pattern. + LocalSymbols map[string]*PatternSymbol +} + +// If the current step has a local symbol, it will be recorded in the context +func (ctx *MatchContext) recordStepResult(step planProcessor) { + name := step.GetPatternItem().Name + if len(name) == 0 { + return + } + if _, global := ctx.Symbols[name]; global { + return + } + result := &PatternSymbol{} + result.Add(step.GetResult()) + ctx.LocalSymbols[name] = result +} + +// resetStepResult will remove the step's local symbol from the context +func (ctx *MatchContext) resetStepResult(step planProcessor) { + name := step.GetPatternItem().Name + if len(name) == 0 { + return + } + if _, global := ctx.Symbols[name]; global { + return + } + delete(ctx.LocalSymbols, name) +} + +func (pattern Pattern) Run(graph Graph, symbols map[string]*PatternSymbol, result MatchAccumulator) error { + plan, err := pattern.GetPlan(graph, symbols) + if err != nil { + return err + } + logf("Starting plan run\n") + return plan.Run(graph, symbols, result) +} + +func (pattern Pattern) FindPaths(graph Graph, symbols map[string]*PatternSymbol) (DefaultMatchAccumulator, error) { + acc := DefaultMatchAccumulator{} + if err := pattern.Run(graph, symbols, &acc); err != nil { + return acc, err + } + return acc, nil +} + +// FindNodes runs the pattern with the given symbols, and returns all the head nodes found +func (pattern Pattern) FindNodes(graph Graph, symbols map[string]*PatternSymbol) ([]Node, error) { + acc := DefaultMatchAccumulator{} + if err := pattern.Run(graph, symbols, &acc); err != nil { + return nil, err + } + return acc.GetHeadNodes(), nil +} + +func (pattern Pattern) getFastestElement(graph Graph, symbols map[string]*PatternSymbol) (Iterator, int) { + maxSize := -1 + index := 0 + var itr Iterator + for i := range pattern { + sz := -1 + var t Iterator + if (i % 2) == 0 { + t, sz = pattern[i].estimateNodeSize(graph, symbols) + } else { + t, sz = pattern[i].estimateEdgeSize(graph, symbols) + } + if sz != -1 { + if maxSize == -1 || sz < maxSize { + maxSize = sz + index = i + itr = t + } + } + } + return itr, index +} + +func (pattern Pattern) GetSymbolNames() StringSet { + ret := NewStringSet() + for _, p := range pattern { + if len(p.Name) > 0 { + ret.Add(p.Name) + } + } + return ret +} + +// GetPlan returns a match execution plan +func (pattern Pattern) GetPlan(graph Graph, symbols map[string]*PatternSymbol) (MatchPlan, error) { + itr, index := pattern.getFastestElement(graph, symbols) + plan := MatchPlan{} + processors := make([]planProcessor, len(pattern)) + if (index % 2) == 0 { + // start with a node + processors[index] = &iterateNodes{itr: itr.(NodeIterator), patternItem: pattern[index]} + plan.steps = append(plan.steps, processors[index]) + // Go forward + for i := index + 1; i < len(pattern); i++ { + if (i % 2) == 1 { + // There is a node before this edge. + if pattern[i].Backwards { + // n<-- + processors[i] = newIterateConnectedEdges(processors[i-1], pattern[i], IncomingEdge) + } else { + // n--> + processors[i] = newIterateConnectedEdges(processors[i-1], pattern[i], OutgoingEdge) + } + } else { + // There is an edge before this node, and that determines the direction + if pattern[i-1].Backwards { + // <--n + processors[i] = newIterateConnectedNodes(processors[i-1], pattern[i], useFromNode) + } else { + // -->n + processors[i] = newIterateConnectedNodes(processors[i-1], pattern[i], useToNode) + } + } + plan.steps = append(plan.steps, processors[i]) + } + // Go backwards + for i := index - 1; i >= 0; i-- { + if (i % 2) == 1 { + // There is a node after this edge + if pattern[i].Backwards { + // <--n + processors[i] = newIterateConnectedEdges(processors[i+1], pattern[i], OutgoingEdge) + } else { + // -->n + processors[i] = newIterateConnectedEdges(processors[i+1], pattern[i], IncomingEdge) + } + } else { + // There is an edge after this node, and that determines the direction + if pattern[i+1].Backwards { + // n<-- + processors[i] = newIterateConnectedNodes(processors[i+1], pattern[i], useToNode) + } else { + // n--> + processors[i] = newIterateConnectedNodes(processors[i+1], pattern[i], useFromNode) + } + } + plan.steps = append(plan.steps, processors[i]) + } + } else { + // start with an edge + processors[index] = &iterateEdges{itr: itr.(EdgeIterator), patternItem: pattern[index]} + plan.steps = append(plan.steps, processors[index]) + // Go forward + for i := index + 1; i < len(pattern); i++ { + if (i % 2) == 1 { + // There is a node before this edge + if pattern[i].Backwards { + // n<-- + processors[i] = newIterateConnectedEdges(processors[i-1], pattern[i], IncomingEdge) + } else { + // n--> + processors[i] = newIterateConnectedEdges(processors[i-1], pattern[i], OutgoingEdge) + } + } else { + // There is an edge before this node, and that determines the direction + if pattern[i-1].Backwards { + processors[i] = newIterateConnectedNodes(processors[i-1], pattern[i], useFromNode) + } else { + processors[i] = newIterateConnectedNodes(processors[i-1], pattern[i], useToNode) + } + } + plan.steps = append(plan.steps, processors[i]) + } + // Go backwards + for i := index - 1; i >= 0; i-- { + if (i % 2) == 1 { + // There is a node after this edge + if pattern[i].Backwards { + // <--n + processors[i] = newIterateConnectedEdges(processors[i+1], pattern[i], OutgoingEdge) + } else { + // -->n + processors[i] = newIterateConnectedEdges(processors[i+1], pattern[i], IncomingEdge) + } + } else { + // There is an edge after this node, and that determines the direction + if pattern[i+1].Backwards { + processors[i] = newIterateConnectedNodes(processors[i+1], pattern[i], useToNode) + } else { + processors[i] = newIterateConnectedNodes(processors[i+1], pattern[i], useFromNode) + } + } + plan.steps = append(plan.steps, processors[i]) + } + } + return plan, nil +} + +type matchAccumulator interface { + Run(*MatchContext) error +} + +type nextAccumulator struct { + run planProcessor + next matchAccumulator +} + +func (n nextAccumulator) Run(ctx *MatchContext) error { + return n.run.Run(ctx, n.next) +} + +type resultAccumulator struct { + acc MatchAccumulator + plan MatchPlan +} + +// Capture the current results +func (n *resultAccumulator) Run(ctx *MatchContext) error { + n.acc.StoreResult(ctx, n.plan.GetCurrentPath(), n.plan.CaptureSymbolValues()) + return nil +} + +// GetCurrentPath returns the current path recoded in the stages of the pattern. The result is either a single node, or a path +func (plan MatchPlan) GetCurrentPath() interface{} { + if len(plan.steps) == 1 { + return plan.steps[0].GetResult() + } + out := make([]Edge, 0) + for i := range plan.steps { + if edges, ok := plan.steps[i].GetResult().([]Edge); ok { + out = append(out, edges...) + } + } + return out +} + +// CaptureSymbolValues captures the current symbol values as nodes or []Edges +func (plan MatchPlan) CaptureSymbolValues() map[string]interface{} { + ret := make(map[string]interface{}) + for _, step := range plan.steps { + if len(step.GetPatternItem().Name) > 0 { + if _, exists := ret[step.GetPatternItem().Name]; !exists { + ret[step.GetPatternItem().Name] = step.GetResult() + } + } + } + return ret +} + +type DefaultMatchAccumulator struct { + // Each element of the paths is either a Node or []Edge + Paths []interface{} + Symbols []map[string]interface{} +} + +func (acc *DefaultMatchAccumulator) StoreResult(_ *MatchContext, path interface{}, symbols map[string]interface{}) { + acc.Paths = append(acc.Paths, path) + acc.Symbols = append(acc.Symbols, symbols) +} + +// Returns the unique nodes in the accumulator that start a path +func (acc *DefaultMatchAccumulator) GetHeadNodes() []Node { + ret := make(map[Node]struct{}) + for _, x := range acc.Paths { + if n, ok := x.(Node); ok { + ret[n] = struct{}{} + } else if e, ok := x.([]Edge); ok { + ret[e[0].GetFrom()] = struct{}{} + } + } + arr := make([]Node, 0, len(ret)) + for x := range ret { + arr = append(arr, x) + } + return arr +} + +// Returns the unique nodes in the accumulator that ends a path +func (acc *DefaultMatchAccumulator) GetTailNodes() []Node { + ret := make(map[Node]struct{}) + for _, x := range acc.Paths { + if n, ok := x.(Node); ok { + ret[n] = struct{}{} + } else if e, ok := x.([]Edge); ok { + ret[e[len(e)-1].GetTo()] = struct{}{} + } + } + arr := make([]Node, 0, len(ret)) + for x := range ret { + arr = append(arr, x) + } + return arr +} + +func (plan MatchPlan) Run(graph Graph, symbols map[string]*PatternSymbol, result MatchAccumulator) error { + ctx := &MatchContext{ + Graph: graph, + Symbols: symbols, + LocalSymbols: make(map[string]*PatternSymbol), + } + + res := resultAccumulator{acc: result, plan: plan} + acc := matchAccumulator(&res) + for i := len(plan.steps) - 1; i > 0; i-- { + acc = nextAccumulator{ + run: plan.steps[i], + next: acc, + } + } + return plan.steps[0].Run(ctx, acc) +} diff --git a/graph/pattern_test.go b/graph/pattern_test.go new file mode 100644 index 0000000..9b762b5 --- /dev/null +++ b/graph/pattern_test.go @@ -0,0 +1,159 @@ +package graph + +import ( + "testing" +) + +func TestPattern(t *testing.T) { + graph := NewOCGraph() + graph.index.NodePropertyIndex("key", graph) + nodes := make([]Node, 0) + for i := 0; i < 10; i++ { + nodes = append(nodes, graph.NewNode([]string{"a"}, nil)) + } + for i := 0; i < 8; i++ { + graph.NewEdge(nodes[i], nodes[i+1], "label", nil) + } + nodes[5].SetProperty("key", "value") + symbols := make(map[string]*PatternSymbol) + pat := Pattern{ + {}, + {Min: 1, Max: 1}, + {Name: "nodes", Labels: nil, Properties: map[string]interface{}{"key": "value"}}} + if _, i := pat.getFastestElement(graph, map[string]*PatternSymbol{}); i != 2 { + t.Errorf("Expecting 2, got %d", i) + } + plan, err := pat.GetPlan(graph, symbols) + if err != nil { + t.Error(err) + return + } + acc := &DefaultMatchAccumulator{} + plan.Run(graph, symbols, acc) + if _, ok := acc.Symbols[0]["nodes"].(Node); !ok { + t.Errorf("Expecting one node, got: %v", acc) + } + + pat = Pattern{ + {Labels: NewStringSet("bogus")}, + {Min: 1, Max: 1}, + {Name: "nodes", Properties: map[string]interface{}{"key": "value"}}, + } + + symbols = make(map[string]*PatternSymbol) + plan, err = pat.GetPlan(graph, symbols) + if err != nil { + t.Error(err) + return + } + acc = &DefaultMatchAccumulator{} + plan.Run(graph, symbols, acc) + if len(acc.Paths) != 0 { + t.Errorf("Expecting 0 node, got: %+v", acc) + } + + pat = Pattern{ + {}, + {}, + {Properties: map[string]interface{}{"key": "value2"}}, + } + if _, i := pat.getFastestElement(graph, map[string]*PatternSymbol{}); i != 2 { + t.Errorf("Expecting 2, got %d", i) + } + pat = Pattern{ + {Properties: map[string]interface{}{"key": "value2"}}, + {}, + {}, + } + if _, i := pat.getFastestElement(graph, map[string]*PatternSymbol{}); i != 0 { + t.Errorf("Expecting 0, got %d", i) + } + +} + +func TestLoopPattern(t *testing.T) { + graph := NewOCGraph() + graph.index.NodePropertyIndex("key", graph) + nodes := make([]Node, 0) + for i := 0; i < 10; i++ { + nodes = append(nodes, graph.NewNode([]string{"a"}, nil)) + } + for i := 0; i < 8; i++ { + graph.NewEdge(nodes[i], nodes[i+1], "label", nil) + } + symbols := make(map[string]*PatternSymbol) + symbols["n"] = &PatternSymbol{} + symbols["n"].Add(nodes[0]) + pat := Pattern{ + {Name: "n"}, + {Min: 1, Max: 1}, + {Name: "n"}, + } + out := DefaultMatchAccumulator{} + err := pat.Run(graph, symbols, &out) + if err != nil { + t.Error(err) + return + } + if len(out.Symbols) > 0 { + t.Errorf("Expecting 0 node, got: %+v", out) + } + + // Create a loop + graph.NewEdge(nodes[0], nodes[0], "label", nil) + out = DefaultMatchAccumulator{} + err = pat.Run(graph, symbols, &out) + if err != nil { + t.Error(err) + return + } + if len(out.Symbols) != 1 { + t.Errorf("Expecting 1 node, got: %v", out) + } +} + +func TestVariableLengthPath(t *testing.T) { + graph := NewOCGraph() + graph.index.NodePropertyIndex("key", graph) + nodes := make([]Node, 0) + for i := 0; i < 10; i++ { + nodes = append(nodes, graph.NewNode([]string{"a"}, nil)) + } + for i := 0; i < 8; i++ { + graph.NewEdge(nodes[i], nodes[i+1], "label", nil) + } + + nodes[1].SetProperty("property", "value") + nodes[4].SetProperty("property", "value") + + symbols := make(map[string]*PatternSymbol) + pat := Pattern{ + {Name: "n", Properties: map[string]interface{}{"property": "value"}}, + {Min: 1, Max: 1}, + {Properties: map[string]interface{}{"property": "value"}}, + } + out := DefaultMatchAccumulator{} + err := pat.Run(graph, symbols, &out) + if err != nil { + t.Error(err) + return + } + if len(out.Paths) != 0 { + t.Errorf("Expecting 0 nodes") + } + pat = Pattern{ + {Name: "n", Properties: map[string]interface{}{"property": "value"}}, + {Min: 1, Max: 4}, + {Properties: map[string]interface{}{"property": "value"}}, + } + out = DefaultMatchAccumulator{} + err = pat.Run(graph, symbols, &out) + if err != nil { + t.Error(err) + return + } + if len(out.Paths[0].([]Edge)) != 3 { + t.Errorf("Expecting 3 nodes: %+v", out) + } + +} diff --git a/graph/planprocessors.go b/graph/planprocessors.go new file mode 100644 index 0000000..7db4f6a --- /dev/null +++ b/graph/planprocessors.go @@ -0,0 +1,242 @@ +// Copyright 2021 Cloud Privacy Labs, LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +package graph + +import ( +// "fmt" +) + +func logf(pattern string, args ...interface{}) { + //fmt.Printf(pattern, args...) +} + +type iterateNodes struct { + itr NodeIterator + patternItem PatternItem + result Node + initialized bool +} + +func (processor *iterateNodes) init(ctx *MatchContext) error { + if !processor.initialized { + nodeFilter := processor.patternItem.getNodeFilter() + processor.itr = &nodeIterator{ + &filterIterator{ + itr: processor.itr, + filter: func(item interface{}) bool { + return nodeFilter(item.(*OCNode)) + }, + }, + } + nodes, err := processor.patternItem.isConstrainedNodes(ctx) + if err != nil { + return err + } + if nodes != nil { + processor.itr = &nodeIterator{ + &filterIterator{ + itr: processor.itr, + filter: func(item interface{}) bool { + return nodes.Has(item.(*OCNode)) + }, + }, + } + } + processor.initialized = true + } + return nil +} + +func (processor *iterateNodes) Run(ctx *MatchContext, next matchAccumulator) error { + if err := processor.init(ctx); err != nil { + return err + } + for processor.itr.Next() { + processor.result = processor.itr.Node() + ctx.recordStepResult(processor) + logf("iterateNodes: %+v\n", processor.result) + if err := next.Run(ctx); err != nil { + return err + } + ctx.resetStepResult(processor) + } + return nil +} + +func (processor *iterateNodes) GetPatternItem() PatternItem { return processor.patternItem } +func (processor *iterateNodes) GetResult() interface{} { return processor.result } +func (processor *iterateNodes) IsNode() {} + +type iterateEdges struct { + itr EdgeIterator + patternItem PatternItem + result []Edge + initialized bool +} + +func (processor *iterateEdges) init(ctx *MatchContext) { + if !processor.initialized { + processor.initialized = true + filterFunc := processor.patternItem.getEdgeFilter() + processor.itr = &edgeIterator{ + &filterIterator{ + itr: processor.itr, + filter: func(edge interface{}) bool { + return filterFunc(edge.(*OCEdge)) + }, + }, + } + } +} + +func (processor *iterateEdges) Run(ctx *MatchContext, next matchAccumulator) error { + processor.init(ctx) + for processor.itr.Next() { + processor.result = []Edge{processor.itr.Edge()} + ctx.recordStepResult(processor) + if err := next.Run(ctx); err != nil { + return err + } + ctx.resetStepResult(processor) + } + return nil +} + +func (processor *iterateEdges) GetPatternItem() PatternItem { return processor.patternItem } +func (processor *iterateEdges) GetResult() interface{} { return processor.result } +func (processor *iterateEdges) IsEdge() {} + +type iterateConnectedEdges struct { + patternItem PatternItem + source planProcessor + dir EdgeDir + result []Edge + edgeFilter func(Edge) bool + edgeItr EdgeIterator +} + +func newIterateConnectedEdges(source planProcessor, item PatternItem, dir EdgeDir) *iterateConnectedEdges { + return &iterateConnectedEdges{ + patternItem: item, + source: source, + dir: dir, + edgeFilter: item.getEdgeFilter(), + } +} + +func (processor *iterateConnectedEdges) init(ctx *MatchContext) { + if processor.edgeItr == nil { + node := processor.source.GetResult().(Node) + processor.edgeItr = &edgeIterator{ + &filterIterator{ + itr: node.GetEdgesWithAnyLabel(processor.dir, processor.patternItem.Labels), + filter: func(item interface{}) bool { + return processor.edgeFilter(item.(*OCEdge)) + }, + }, + } + } +} + +func (processor *iterateConnectedEdges) Run(ctx *MatchContext, next matchAccumulator) error { + processor.init(ctx) + if processor.edgeItr == nil { + return nil + } + if processor.patternItem.Min == 1 && processor.patternItem.Max == 1 { + for processor.edgeItr.Next() { + processor.result = []Edge{processor.edgeItr.Edge()} + ctx.recordStepResult(processor) + logf("IterateConnectedEdges len=1 %+v\n", processor.result) + if err := next.Run(ctx); err != nil { + return err + } + ctx.resetStepResult(processor) + } + return nil + } + var err error + CollectAllPaths(ctx.Graph, processor.edgeItr, processor.edgeFilter, processor.dir, processor.patternItem.Min, processor.patternItem.Max, func(path []Edge) bool { + processor.result = path + logf("IterateConnectedEdges len>1 %+v\n", processor.result) + ctx.recordStepResult(processor) + if err = next.Run(ctx); err != nil { + return false + } + ctx.resetStepResult(processor) + return true + }) + return err +} + +func (processor *iterateConnectedEdges) GetPatternItem() PatternItem { return processor.patternItem } +func (processor *iterateConnectedEdges) GetResult() interface{} { return processor.result } +func (processor *iterateConnectedEdges) IsEdge() {} + +const useFromNode = -1 +const useToNode = 1 + +type iterateConnectedNodes struct { + patternItem PatternItem + source planProcessor + useNode int + result Node + nodeFilter func(Node) bool +} + +func newIterateConnectedNodes(source planProcessor, item PatternItem, useNode int) *iterateConnectedNodes { + return &iterateConnectedNodes{ + patternItem: item, + source: source, + useNode: useNode, + nodeFilter: item.getNodeFilter(), + } +} + +func (processor *iterateConnectedNodes) Run(ctx *MatchContext, next matchAccumulator) error { + edges := processor.source.GetResult().([]Edge) + edge := edges[len(edges)-1] + var node Node + if processor.useNode == useToNode { + node = edge.GetTo() + } else { + node = edge.GetFrom() + } + logf("Iterate connected nodes with node=%+v\n", node) + if processor.nodeFilter(node) { + + constraints, err := processor.patternItem.isConstrainedNodes(ctx) + if err != nil { + return err + } + if constraints != nil { + if !constraints.Has(node.(*OCNode)) { + return nil + } + } + + processor.result = node + ctx.recordStepResult(processor) + logf("Iterate connected nodes goes deeper\n") + if err := next.Run(ctx); err != nil { + return err + } + ctx.resetStepResult(processor) + } + return nil +} + +func (processor *iterateConnectedNodes) GetPatternItem() PatternItem { return processor.patternItem } +func (processor *iterateConnectedNodes) GetResult() interface{} { return processor.result } +func (processor *iterateConnectedNodes) IsNode() {} diff --git a/graph/properties.go b/graph/properties.go new file mode 100644 index 0000000..d2e3f3e --- /dev/null +++ b/graph/properties.go @@ -0,0 +1,212 @@ +// Copyright 2021 Cloud Privacy Labs, LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package graph + +import ( + "fmt" + "strings" +) + +type Properties map[string]interface{} + +// GetProperty returns the value for the key, and whether or not key +// exists. p can be nil +func (p *Properties) GetProperty(key string) (interface{}, bool) { + if p == nil { + return nil, false + } + x, ok := (*p)[key] + return x, ok +} + +// ForEachProperty calls f for each property in p until f returns +// false. Returns false if f returned false. p can be nil +func (p *Properties) ForEachProperty(f func(string, interface{}) bool) bool { + if p == nil { + return true + } + for k, v := range *p { + if !f(k, v) { + return false + } + } + return true +} + +// ComparePropertyValue compares a and b. They both must be of the +// same type. Supported types are +// +// int +// string +// []int +// []string +// []interface +// +// The []interface must have one of the supported types as its elements +// +// If one of the values implement GetNativeValue() method, then it is +// called to get the underlying value +func ComparePropertyValue(a, b interface{}) int { + + type withNativeValue interface { + GetNativeValue() interface{} + } + if n, ok := a.(withNativeValue); ok { + return ComparePropertyValue(n.GetNativeValue(), b) + } + if n, ok := b.(withNativeValue); ok { + return ComparePropertyValue(a, n.GetNativeValue()) + } + + switch v1 := a.(type) { + case string: + if v2, ok := b.(string); ok { + if v1 == v2 { + return 0 + } + if v1 < v2 { + return -1 + } + return 1 + } + + case int: + if v2, ok := b.(int); ok { + if v1 == v2 { + return 0 + } + if v1 < v2 { + return -1 + } + return 1 + } + + case []string: + if v2, ok := b.([]string); ok { + l1 := len(v1) + l2 := len(v2) + for i := 0; i < l1 && i < l2; i++ { + if v1[i] < v2[i] { + return -1 + } + if v1[i] > v2[i] { + return 1 + } + } + if l1 < l2 { + return -1 + } + if l1 > l2 { + return 1 + } + return 0 + } + if v2, ok := b.([]interface{}); ok { + l1 := len(v1) + l2 := len(v2) + for i := 0; i < l1 && i < l2; i++ { + switch ComparePropertyValue(v1[i], v2[i]) { + case -1: + return -1 + case 1: + return 1 + } + } + if l1 < l2 { + return -1 + } + if l1 > l2 { + return 1 + } + return 0 + } + + case []int: + if v2, ok := b.([]int); ok { + l1 := len(v1) + l2 := len(v2) + for i := 0; i < l1 && i < l2; i++ { + if v1[i] < v2[i] { + return -1 + } + if v1[i] > v2[i] { + return 1 + } + } + if l1 < l2 { + return -1 + } + if l1 > l2 { + return 1 + } + return 0 + } + if v2, ok := b.([]interface{}); ok { + l1 := len(v1) + l2 := len(v2) + for i := 0; i < l1 && i < l2; i++ { + switch ComparePropertyValue(v1[i], v2[i]) { + case -1: + return -1 + case 1: + return 1 + } + } + if l1 < l2 { + return -1 + } + if l1 > l2 { + return 1 + } + return 0 + } + + case []interface{}: + if v2, ok := b.([]interface{}); ok { + l1 := len(v1) + l2 := len(v2) + for i := 0; i < l1 && i < l2; i++ { + switch ComparePropertyValue(v1[i], v2[i]) { + case -1: + return -1 + case 1: + return 1 + } + } + if l1 < l2 { + return -1 + } + if l1 > l2 { + return 1 + } + return 0 + } + if v2, ok := b.([]string); ok { + return -ComparePropertyValue(v2, v1) + } + if v2, ok := b.([]int); ok { + return -ComparePropertyValue(v2, v1) + } + } + panic(fmt.Sprintf("Incomparable values: %v (%T) vs %v (%T)", a, a, b, b)) +} + +func (p Properties) String() string { + elements := make([]string, 0, len(p)) + for k, v := range p { + elements = append(elements, fmt.Sprintf("%s:%s", k, v)) + } + return "{" + strings.Join(elements, " ") + "}" +} diff --git a/graph/sets.go b/graph/sets.go new file mode 100644 index 0000000..616fb81 --- /dev/null +++ b/graph/sets.go @@ -0,0 +1,127 @@ +// Copyright 2021 Cloud Privacy Labs, LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package graph + +import ( + "container/list" +) + +// A FastSet is a set of objects with constant-time +// insertion/deletion, with iterator support +type FastSet struct { + m map[interface{}]*list.Element + l *list.List +} + +func NewFastSet() *FastSet { + return &FastSet{} +} + +func (f FastSet) Len() int { return len(f.m) } + +func (f *FastSet) Add(item interface{}) { + if f.m == nil { + f.m = make(map[interface{}]*list.Element) + f.l = list.New() + } + _, exists := f.m[item] + if exists { + return + } + el := f.l.PushBack(item) + f.m[item] = el +} + +func (f *FastSet) Remove(item interface{}) { + if f.m == nil { + return + } + el := f.m[item] + if el == nil { + return + } + delete(f.m, item) + f.l.Remove(el) +} + +func (f FastSet) Has(item interface{}) bool { + if f.m == nil { + return false + } + _, exists := f.m[item] + return exists +} + +func (f FastSet) Iterator() Iterator { + if f.m == nil { + return emptyIterator{} + } + return &listIterator{next: f.l.Front(), size: f.Len()} +} + +type NodeSet struct { + set FastSet +} + +func (set *NodeSet) Add(node *OCNode) { + set.set.Add(node) +} + +func (set NodeSet) Remove(node *OCNode) { + set.set.Remove(node) +} + +func (set NodeSet) Has(node *OCNode) bool { + return set.set.Has(node) +} + +func (set NodeSet) Len() int { + return set.set.Len() +} + +func (set NodeSet) Iterator() NodeIterator { + i := set.set.Iterator() + return &nodeIterator{withSize(i, set.set.Len())} +} + +func (set NodeSet) Slice() []Node { + return NodeSlice(set.Iterator()) +} + +// EdgeSet keeps an unordered set of edges +type EdgeSet struct { + set FastSet +} + +func (set *EdgeSet) Add(edge *OCEdge) { + set.set.Add(edge) +} + +func (set EdgeSet) Remove(edge *OCEdge) { + set.set.Remove(edge) +} + +func (set EdgeSet) Len() int { + return set.set.Len() +} + +func (set EdgeSet) Iterator() EdgeIterator { + i := set.set.Iterator() + return &edgeIterator{withSize(i, set.set.Len())} +} + +func (set EdgeSet) Slice() []Edge { + return EdgeSlice(set.Iterator()) +} diff --git a/graph/store.go b/graph/store.go new file mode 100644 index 0000000..ac4401a --- /dev/null +++ b/graph/store.go @@ -0,0 +1,148 @@ +// Copyright 2021 Cloud Privacy Labs, LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package graph + +// Store keeps the nodes, edges, and the connections of a graph +type Store interface { + AddNode(node *OCNode) + DetachNode(node *OCNode) + DetachRemoveNode(node *OCNode) + AddEdge(edge *OCEdge) + RemoveEdge(edge *OCEdge) + GetNodeEdges(node *OCNode, dir EdgeDir) EdgeIterator + GetNodeEdgesWithLabel(node *OCNode, dir EdgeDir, label string) EdgeIterator + GetNodeEdgesWithAnyLabel(node *OCNode, dir EdgeDir, set StringSet) EdgeIterator + NumNodes() int + GetNodes() NodeIterator + GetEdges() EdgeIterator + NumEdges() int + GetEdgesWithAnyLabel(set StringSet) EdgeIterator +} + +type OCStore struct { + allNodes NodeSet + allEdges EdgeMap + + incoming map[*OCNode]EdgeMap + outgoing map[*OCNode]EdgeMap +} + +func NewOCStore() *OCStore { + return &OCStore{ + incoming: make(map[*OCNode]EdgeMap), + outgoing: make(map[*OCNode]EdgeMap), + } +} + +func (store *OCStore) AddNode(node *OCNode) { + store.allNodes.Add(node) +} + +func (store *OCStore) DetachNode(node *OCNode) { + for _, e := range EdgeSlice(store.incoming[node].Iterator()) { + store.RemoveEdge(e.(*OCEdge)) + } + delete(store.incoming, node) + for _, e := range EdgeSlice(store.outgoing[node].Iterator()) { + store.RemoveEdge(e.(*OCEdge)) + } + delete(store.outgoing, node) +} + +func (store *OCStore) DetachRemoveNode(node *OCNode) { + store.DetachNode(node) + store.allNodes.Remove(node) +} + +func (store *OCStore) AddEdge(edge *OCEdge) { + store.AddNode(edge.from) + store.AddNode(edge.to) + store.allEdges.Add(edge) + store.connect(edge) +} + +func (store *OCStore) RemoveEdge(edge *OCEdge) { + store.disconnect(edge) + store.allEdges.Remove(edge) +} + +func (store *OCStore) GetNodeEdges(node *OCNode, dir EdgeDir) EdgeIterator { + if dir == IncomingEdge { + return store.incoming[node].Iterator() + } + return store.outgoing[node].Iterator() +} + +func (store *OCStore) GetNodeEdgesWithLabel(node *OCNode, dir EdgeDir, label string) EdgeIterator { + if dir == IncomingEdge { + return store.incoming[node].IteratorLabel(label) + } + return store.outgoing[node].IteratorLabel(label) +} + +func (store *OCStore) GetNodeEdgesWithAnyLabel(node *OCNode, dir EdgeDir, set StringSet) EdgeIterator { + if dir == IncomingEdge { + if len(set) == 0 { + return store.incoming[node].Iterator() + } + return store.incoming[node].IteratorAnyLabel(set) + } + if len(set) == 0 { + return store.outgoing[node].Iterator() + } + return store.outgoing[node].IteratorAnyLabel(set) +} + +func (store *OCStore) NumNodes() int { + return store.allNodes.Len() +} + +func (store *OCStore) GetNodes() NodeIterator { + return store.allNodes.Iterator() +} + +func (store *OCStore) GetEdges() EdgeIterator { + return store.allEdges.Iterator() +} + +func (store *OCStore) NumEdges() int { + return store.allEdges.Len() +} + +func (store *OCStore) GetEdgesWithAnyLabel(set StringSet) EdgeIterator { + return store.allEdges.IteratorAnyLabel(set) +} + +func (store *OCStore) connect(edge *OCEdge) { + in := store.incoming[edge.to] + in.Add(edge) + store.incoming[edge.to] = in + out := store.outgoing[edge.from] + out.Add(edge) + store.outgoing[edge.from] = out +} + +func (store *OCStore) disconnect(edge *OCEdge) { + in := store.incoming[edge.to] + in.Remove(edge) + if in.IsEmpty() { + delete(store.incoming, edge.to) + } + out := store.outgoing[edge.from] + out.Remove(edge) + if out.IsEmpty() { + delete(store.outgoing, edge.from) + } +} diff --git a/graph/stringset.go b/graph/stringset.go new file mode 100644 index 0000000..d0e606f --- /dev/null +++ b/graph/stringset.go @@ -0,0 +1,121 @@ +// Copyright 2021 Cloud Privacy Labs, LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +package graph + +import ( + "sort" + "strings" +) + +type StringSet map[string]struct{} + +func NewStringSet(s ...string) StringSet { + ret := make(StringSet) + for _, x := range s { + ret[x] = struct{}{} + } + return ret +} + +func (set StringSet) Clone() StringSet { + ret := make(StringSet) + for x := range set { + ret[x] = struct{}{} + } + return ret +} + +func (set StringSet) IsEqual(s StringSet) bool { + return len(set) == len(s) && set.HasAllSet(s) +} + +func (set StringSet) Has(s string) bool { + _, ok := set[s] + return ok +} + +func (set StringSet) HasAny(s ...string) bool { + for _, x := range s { + if _, ok := set[x]; ok { + return true + } + } + return false +} + +func (set StringSet) HasAnySet(s StringSet) bool { + for x := range s { + if _, ok := set[x]; ok { + return true + } + } + return false +} + +func (set StringSet) HasAll(s ...string) bool { + for _, x := range s { + if _, ok := set[x]; !ok { + return false + } + } + return true +} + +func (set StringSet) HasAllSet(s StringSet) bool { + for x := range s { + if _, ok := set[x]; !ok { + return false + } + } + return true +} + +func (set StringSet) Add(s ...string) StringSet { + for _, x := range s { + set[x] = struct{}{} + } + return set +} + +func (set StringSet) AddSet(s StringSet) StringSet { + for x := range s { + set[x] = struct{}{} + } + return set +} + +func (set StringSet) Remove(s ...string) StringSet { + for _, x := range s { + delete(set, x) + } + return set +} + +func (set StringSet) Slice() []string { + ret := make([]string, 0, len(set)) + for k := range set { + ret = append(ret, k) + } + return ret +} + +func (set StringSet) SortedSlice() []string { + ret := set.Slice() + sort.Strings(ret) + return ret +} + +func (set StringSet) String() string { + return strings.Join(set.Slice(), ", ") +} diff --git a/graph/vpathitr.go b/graph/vpathitr.go new file mode 100644 index 0000000..de392a7 --- /dev/null +++ b/graph/vpathitr.go @@ -0,0 +1,110 @@ +// Copyright 2021 Cloud Privacy Labs, LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package graph + +// CollectAllPaths iterates the variable length paths that have the +// edges in firstLeg. For each edge, it calls the edgeFilter +// function. If the edge is accepted, it recursively descends and +// calls accumulator.AddPath for each discovered path until AddPath +// returns false +func CollectAllPaths(graph Graph, firstLeg EdgeIterator, edgeFilter func(Edge) bool, dir EdgeDir, min, max int, accumulator func([]Edge) bool) { + var recurse func([]Edge) bool + + isLoop := func(node Node, edges []Edge) bool { + for _, e := range edges { + if e.GetFrom() == node { + return true + } + } + if len(edges) > 0 { + return edges[len(edges)-1].GetTo() == node + } + return false + } + + recurse = func(prefix []Edge) bool { + + if (min == -1 || len(prefix) >= min) && (max == -1 || len(prefix) <= max) { + // A valid path + entry := make([]Edge, len(prefix)) + copy(entry, prefix) + if !accumulator(entry) { + return false + } + } + + if max != -1 && len(prefix) >= max { + return true + } + + endNode := prefix[len(prefix)-1].GetTo() + if isLoop(endNode, prefix[:len(prefix)-1]) { + return true + } + itr := &edgeIterator{ + &filterIterator{ + itr: endNode.GetEdges(dir), + filter: func(item interface{}) bool { + return edgeFilter(item.(*OCEdge)) + }, + }, + } + for itr.Next() { + edge := itr.Edge() + if !recurse(append(prefix, edge.(*OCEdge))) { + return false + } + } + return true + } + + for firstLeg.Next() { + edge := firstLeg.Edge() + if !recurse([]Edge{edge}) { + break + } + } +} + +type VPathIterator struct { + paths [][]Edge + current []Edge +} + +func (v *VPathIterator) AddPath(path []Edge) bool { + v.paths = append(v.paths, path) + return true +} + +func (v *VPathIterator) Next() bool { + if len(v.paths) == 0 { + return false + } + v.current = v.paths[0] + v.paths = v.paths[1:] + return true +} + +func (v *VPathIterator) Path() []Edge { + ret := make([]Edge, len(v.current)) + copy(ret, v.current) + return ret +} + +func GetVPathIterator(graph Graph, firstLeg EdgeIterator, edgeFilter func(Edge) bool, dir EdgeDir, min, max int) *VPathIterator { + var paths VPathIterator + CollectAllPaths(graph, firstLeg, edgeFilter, dir, min, max, paths.AddPath) + return &paths +} diff --git a/lang.go b/lang.go new file mode 100644 index 0000000..dca4905 --- /dev/null +++ b/lang.go @@ -0,0 +1,120 @@ +package opencypher + +import ( + "fmt" + + "github.com/antlr/antlr4/runtime/Go/antlr" + "github.com/cloudprivacylabs/opencypher/parser" + "github.com/cloudprivacylabs/opencypher/graph" +) + +//go:generate antlr4 -Dlanguage=Go Cypher.g4 -o parser + +type errorListener struct { + antlr.DefaultErrorListener + err error +} + +type ErrSyntax string +type ErrInvalidExpression string + +func (e ErrSyntax) Error() string { return "Syntax error: " + string(e) } +func (e ErrInvalidExpression) Error() string { return "Invalid expression: " + string(e) } + +func (lst *errorListener) SyntaxError(recognizer antlr.Recognizer, offendingSymbol interface{}, line, column int, msg string, e antlr.RecognitionException) { + if lst.err == nil { + lst.err = ErrSyntax(fmt.Sprintf("line %d:%d %s ", line, column, msg)) + } +} + +// GetParser returns a parser that will parse the input string +func GetParser(input string) *parser.CypherParser { + lexer := parser.NewCypherLexer(antlr.NewInputStream(input)) + stream := antlr.NewCommonTokenStream(lexer, 0) + p := parser.NewCypherParser(stream) + p.BuildParseTrees = true + return p +} + +// GetEvaluatable returns an evaluatable object +func Parse(input string) (Evaluatable, error) { + pr := GetParser(input) + errListener := errorListener{} + pr.AddErrorListener(&errListener) + c := pr.OC_Cypher() + if errListener.err != nil { + return nil, errListener.err + } + out := oC_Cypher(c.(*parser.OC_CypherContext)) + return out, nil +} + +func ParseAndEvaluate(input string, ctx *EvalContext) (Value, error) { + e, err := Parse(input) + if err != nil { + return Value{}, err + } + return e.Evaluate(ctx) +} + +// ParsePatternExpr parses the pattern expression that starts at the +// current node named 'this', and describes a path reaching one or +// more nodes named 'target'. For instance: +// +// (this)-[]->(target) +// +// will return all nodes reachable from the current node by one step. +// +// This expression: +// +// (this)<[a]-()-[]->(target :x) +// +// will start from the current node, go back one nore following an +// edge with label `a`, and then move to a node with label `x` +func ParsePatternExpr(expr string) (PatternPart, error) { + pr := GetParser(expr) + errListener := errorListener{} + pr.AddErrorListener(&errListener) + c := pr.OC_PatternPart() + if errListener.err != nil { + return PatternPart{}, errListener.err + } + out := oC_PatternPart(c.(*parser.OC_PatternPartContext)) + return out, nil +} + +// FindRelative evaluates a pattern expression starting at the given +// node. It may return zero or more nodes reached from the node +func (p PatternPart) FindRelative(this graph.Node) ([]graph.Node, error) { + ctx := NewEvalContext(this.GetGraph()) + ctx.SetVar("this", Value{Value: this}) + pattern, err := p.getPattern(ctx) + if err != nil { + return nil, err + } + + symbols, err := BuildPatternSymbols(ctx, pattern) + if err != nil { + return nil, err + } + + resultAccumulator := matchResultAccumulator{ + evalCtx: ctx, + } + err = pattern.Run(ctx.graph, symbols, &resultAccumulator) + if err != nil { + return nil, err + } + + ret := make([]graph.Node, 0, len(resultAccumulator.result.Rows)) + for _, row := range resultAccumulator.result.Rows { + t, ok := row["target"] + if !ok { + continue + } + if n, ok := t.Value.(graph.Node); ok { + ret = append(ret, n) + } + } + return ret, nil +} diff --git a/literal.go b/literal.go new file mode 100644 index 0000000..6e905c1 --- /dev/null +++ b/literal.go @@ -0,0 +1,112 @@ +package opencypher + +import () + +func (literal IntLiteral) Evaluate(ctx *EvalContext) (Value, error) { + return Value{ + Value: int(literal), + Constant: true, + }, nil +} + +func (literal BooleanLiteral) Evaluate(ctx *EvalContext) (Value, error) { + return Value{ + Value: bool(literal), + Constant: true, + }, nil +} + +func (literal DoubleLiteral) Evaluate(ctx *EvalContext) (Value, error) { + return Value{ + Value: float64(literal), + Constant: true, + }, nil +} + +func (literal StringLiteral) Evaluate(ctx *EvalContext) (Value, error) { + return Value{ + Value: string(literal), + Constant: true, + }, nil +} + +func (literal NullLiteral) Evaluate(ctx *EvalContext) (Value, error) { + return Value{ + Constant: true, + }, nil +} + +func (lst *ListLiteral) Evaluate(ctx *EvalContext) (Value, error) { + if lst.constValue != nil { + return *lst.constValue, nil + } + ret := make([]Value, 0, len(lst.Values)) + var val Value + for i := range lst.Values { + v, err := lst.Values[i].Evaluate(ctx) + if err != nil { + return Value{}, err + } + if i == 0 { + val.Constant = v.Constant + } else { + val.Constant = val.Constant && v.Constant + } + ret = append(ret, v) + } + val.Value = ret + if val.Constant { + lst.constValue = &val + } + return val, nil +} + +func (mp *MapLiteral) Evaluate(ctx *EvalContext) (Value, error) { + if mp.constValue != nil { + return *mp.constValue, nil + } + var val Value + ret := make(map[string]Value) + for i := range mp.KeyValues { + keyStr := mp.KeyValues[i].Key + if len(keyStr) == 0 { + return Value{}, ErrInvalidMapKey + } + value, err := mp.KeyValues[i].Value.Evaluate(ctx) + if err != nil { + return Value{}, err + } + ret[keyStr] = value + if i == 0 { + val.Constant = value.Constant + } else { + val.Constant = val.Constant && value.Constant + } + } + val.Value = ret + if val.Constant { + mp.constValue = &val + } + return val, nil +} + +func (r *RangeLiteral) Evaluate(ctx *EvalContext) (from, to *int, err error) { + var v Value + if r.From != nil { + v, err = r.From.Evaluate(ctx) + if err != nil { + return + } + i := v.Value.(int) + from = &i + } + if r.To != nil { + v, err = r.To.Evaluate(ctx) + if err != nil { + return + } + i := v.Value.(int) + to = &i + } + return +} diff --git a/parser/Cypher.interp b/parser/Cypher.interp new file mode 100644 index 0000000..41b61ba --- /dev/null +++ b/parser/Cypher.interp @@ -0,0 +1,364 @@ +token literal names: +null +';' +',' +'=' +'+=' +'*' +'(' +')' +'[' +']' +':' +'|' +'..' +'+' +'-' +'/' +'%' +'^' +'<>' +'<' +'>' +'<=' +'>=' +'.' +'{' +'}' +'$' +'\u27e8' +'\u3008' +'\ufe64' +'\uff1c' +'\u27e9' +'\u3009' +'\ufe65' +'\uff1e' +'\u00ad' +'\u2010' +'\u2011' +'\u2012' +'\u2013' +'\u2014' +'\u2015' +'\u2212' +'\ufe58' +'\ufe63' +'\uff0d' +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +'0' +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null + +token symbolic names: +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +UNION +ALL +OPTIONAL +MATCH +UNWIND +AS +MERGE +ON +CREATE +SET +DETACH +DELETE +REMOVE +CALL +YIELD +WITH +RETURN +DISTINCT +ORDER +BY +L_SKIP +LIMIT +ASCENDING +ASC +DESCENDING +DESC +WHERE +OR +XOR +AND +NOT +IN +STARTS +ENDS +CONTAINS +IS +NULL +COUNT +ANY +NONE +SINGLE +TRUE +FALSE +EXISTS +CASE +ELSE +END +WHEN +THEN +StringLiteral +EscapedChar +HexInteger +DecimalInteger +OctalInteger +HexLetter +HexDigit +Digit +NonZeroDigit +NonZeroOctDigit +OctDigit +ZeroDigit +ExponentDecimalReal +RegularDecimalReal +CONSTRAINT +DO +FOR +REQUIRE +UNIQUE +MANDATORY +SCALAR +OF +ADD +DROP +FILTER +EXTRACT +UnescapedSymbolicName +IdentifierStart +IdentifierPart +EscapedSymbolicName +SP +WHITESPACE +Comment + +rule names: +oC_Cypher +oC_Statement +oC_Query +oC_RegularQuery +oC_Union +oC_SingleQuery +oC_SinglePartQuery +oC_MultiPartQuery +oC_UpdatingClause +oC_ReadingClause +oC_Match +oC_Unwind +oC_Merge +oC_MergeAction +oC_Create +oC_Set +oC_SetItem +oC_Delete +oC_Remove +oC_RemoveItem +oC_InQueryCall +oC_StandaloneCall +oC_YieldItems +oC_YieldItem +oC_With +oC_Return +oC_ProjectionBody +oC_ProjectionItems +oC_ProjectionItem +oC_Order +oC_Skip +oC_Limit +oC_SortItem +oC_Where +oC_Pattern +oC_PatternPart +oC_AnonymousPatternPart +oC_PatternElement +oC_NodePattern +oC_PatternElementChain +oC_RelationshipPattern +oC_RelationshipDetail +oC_Properties +oC_RelationshipTypes +oC_NodeLabels +oC_NodeLabel +oC_RangeLiteral +oC_LabelName +oC_RelTypeName +oC_Expression +oC_OrExpression +oC_XorExpression +oC_AndExpression +oC_NotExpression +oC_ComparisonExpression +oC_AddOrSubtractExpression +oC_MultiplyDivideModuloExpression +oC_PowerOfExpression +oC_UnaryAddOrSubtractExpression +oC_StringListNullOperatorExpression +oC_ListOperatorExpression +oC_StringOperatorExpression +oC_NullOperatorExpression +oC_PropertyOrLabelsExpression +oC_Atom +oC_Literal +oC_BooleanLiteral +oC_ListLiteral +oC_PartialComparisonExpression +oC_ParenthesizedExpression +oC_RelationshipsPattern +oC_FilterExpression +oC_IdInColl +oC_FunctionInvocation +oC_FunctionName +oC_ExplicitProcedureInvocation +oC_ImplicitProcedureInvocation +oC_ProcedureResultField +oC_ProcedureName +oC_Namespace +oC_ListComprehension +oC_PatternComprehension +oC_PropertyLookup +oC_CaseExpression +oC_CaseAlternatives +oC_Variable +oC_NumberLiteral +oC_MapLiteral +oC_Parameter +oC_PropertyExpression +oC_PropertyKeyName +oC_IntegerLiteral +oC_DoubleLiteral +oC_SchemaName +oC_ReservedWord +oC_SymbolicName +oC_LeftArrowHead +oC_RightArrowHead +oC_Dash + + +atn: +[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 3, 129, 1549, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, 28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9, 32, 4, 33, 9, 33, 4, 34, 9, 34, 4, 35, 9, 35, 4, 36, 9, 36, 4, 37, 9, 37, 4, 38, 9, 38, 4, 39, 9, 39, 4, 40, 9, 40, 4, 41, 9, 41, 4, 42, 9, 42, 4, 43, 9, 43, 4, 44, 9, 44, 4, 45, 9, 45, 4, 46, 9, 46, 4, 47, 9, 47, 4, 48, 9, 48, 4, 49, 9, 49, 4, 50, 9, 50, 4, 51, 9, 51, 4, 52, 9, 52, 4, 53, 9, 53, 4, 54, 9, 54, 4, 55, 9, 55, 4, 56, 9, 56, 4, 57, 9, 57, 4, 58, 9, 58, 4, 59, 9, 59, 4, 60, 9, 60, 4, 61, 9, 61, 4, 62, 9, 62, 4, 63, 9, 63, 4, 64, 9, 64, 4, 65, 9, 65, 4, 66, 9, 66, 4, 67, 9, 67, 4, 68, 9, 68, 4, 69, 9, 69, 4, 70, 9, 70, 4, 71, 9, 71, 4, 72, 9, 72, 4, 73, 9, 73, 4, 74, 9, 74, 4, 75, 9, 75, 4, 76, 9, 76, 4, 77, 9, 77, 4, 78, 9, 78, 4, 79, 9, 79, 4, 80, 9, 80, 4, 81, 9, 81, 4, 82, 9, 82, 4, 83, 9, 83, 4, 84, 9, 84, 4, 85, 9, 85, 4, 86, 9, 86, 4, 87, 9, 87, 4, 88, 9, 88, 4, 89, 9, 89, 4, 90, 9, 90, 4, 91, 9, 91, 4, 92, 9, 92, 4, 93, 9, 93, 4, 94, 9, 94, 4, 95, 9, 95, 4, 96, 9, 96, 4, 97, 9, 97, 4, 98, 9, 98, 4, 99, 9, 99, 4, 100, 9, 100, 3, 2, 5, 2, 202, 10, 2, 3, 2, 3, 2, 5, 2, 206, 10, 2, 3, 2, 5, 2, 209, 10, 2, 3, 2, 5, 2, 212, 10, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 4, 3, 4, 5, 4, 220, 10, 4, 3, 5, 3, 5, 5, 5, 224, 10, 5, 3, 5, 7, 5, 227, 10, 5, 12, 5, 14, 5, 230, 11, 5, 3, 6, 3, 6, 3, 6, 3, 6, 5, 6, 236, 10, 6, 3, 6, 3, 6, 3, 6, 5, 6, 241, 10, 6, 3, 6, 5, 6, 244, 10, 6, 3, 7, 3, 7, 5, 7, 248, 10, 7, 3, 8, 3, 8, 5, 8, 252, 10, 8, 7, 8, 254, 10, 8, 12, 8, 14, 8, 257, 11, 8, 3, 8, 3, 8, 3, 8, 5, 8, 262, 10, 8, 7, 8, 264, 10, 8, 12, 8, 14, 8, 267, 11, 8, 3, 8, 3, 8, 5, 8, 271, 10, 8, 3, 8, 7, 8, 274, 10, 8, 12, 8, 14, 8, 277, 11, 8, 3, 8, 5, 8, 280, 10, 8, 3, 8, 5, 8, 283, 10, 8, 5, 8, 285, 10, 8, 3, 9, 3, 9, 5, 9, 289, 10, 9, 7, 9, 291, 10, 9, 12, 9, 14, 9, 294, 11, 9, 3, 9, 3, 9, 5, 9, 298, 10, 9, 7, 9, 300, 10, 9, 12, 9, 14, 9, 303, 11, 9, 3, 9, 3, 9, 5, 9, 307, 10, 9, 6, 9, 309, 10, 9, 13, 9, 14, 9, 310, 3, 9, 3, 9, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 5, 10, 320, 10, 10, 3, 11, 3, 11, 3, 11, 5, 11, 325, 10, 11, 3, 12, 3, 12, 5, 12, 329, 10, 12, 3, 12, 3, 12, 5, 12, 333, 10, 12, 3, 12, 3, 12, 5, 12, 337, 10, 12, 3, 12, 5, 12, 340, 10, 12, 3, 13, 3, 13, 5, 13, 344, 10, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 14, 3, 14, 5, 14, 354, 10, 14, 3, 14, 3, 14, 3, 14, 7, 14, 359, 10, 14, 12, 14, 14, 14, 362, 11, 14, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 5, 15, 374, 10, 15, 3, 16, 3, 16, 5, 16, 378, 10, 16, 3, 16, 3, 16, 3, 17, 3, 17, 5, 17, 384, 10, 17, 3, 17, 3, 17, 5, 17, 388, 10, 17, 3, 17, 3, 17, 5, 17, 392, 10, 17, 3, 17, 7, 17, 395, 10, 17, 12, 17, 14, 17, 398, 11, 17, 3, 18, 3, 18, 5, 18, 402, 10, 18, 3, 18, 3, 18, 5, 18, 406, 10, 18, 3, 18, 3, 18, 3, 18, 3, 18, 5, 18, 412, 10, 18, 3, 18, 3, 18, 5, 18, 416, 10, 18, 3, 18, 3, 18, 3, 18, 3, 18, 5, 18, 422, 10, 18, 3, 18, 3, 18, 5, 18, 426, 10, 18, 3, 18, 3, 18, 3, 18, 3, 18, 5, 18, 432, 10, 18, 3, 18, 3, 18, 5, 18, 436, 10, 18, 3, 19, 3, 19, 5, 19, 440, 10, 19, 3, 19, 3, 19, 5, 19, 444, 10, 19, 3, 19, 3, 19, 5, 19, 448, 10, 19, 3, 19, 3, 19, 5, 19, 452, 10, 19, 3, 19, 7, 19, 455, 10, 19, 12, 19, 14, 19, 458, 11, 19, 3, 20, 3, 20, 3, 20, 3, 20, 5, 20, 464, 10, 20, 3, 20, 3, 20, 5, 20, 468, 10, 20, 3, 20, 7, 20, 471, 10, 20, 12, 20, 14, 20, 474, 11, 20, 3, 21, 3, 21, 3, 21, 3, 21, 5, 21, 480, 10, 21, 3, 22, 3, 22, 3, 22, 3, 22, 5, 22, 486, 10, 22, 3, 22, 3, 22, 3, 22, 5, 22, 491, 10, 22, 3, 23, 3, 23, 3, 23, 3, 23, 5, 23, 497, 10, 23, 3, 23, 3, 23, 3, 23, 3, 23, 5, 23, 503, 10, 23, 3, 24, 3, 24, 3, 24, 5, 24, 508, 10, 24, 3, 24, 3, 24, 5, 24, 512, 10, 24, 3, 24, 7, 24, 515, 10, 24, 12, 24, 14, 24, 518, 11, 24, 5, 24, 520, 10, 24, 3, 24, 5, 24, 523, 10, 24, 3, 24, 5, 24, 526, 10, 24, 3, 25, 3, 25, 3, 25, 3, 25, 3, 25, 5, 25, 533, 10, 25, 3, 25, 3, 25, 3, 26, 3, 26, 3, 26, 5, 26, 540, 10, 26, 3, 26, 5, 26, 543, 10, 26, 3, 27, 3, 27, 3, 27, 3, 28, 5, 28, 549, 10, 28, 3, 28, 5, 28, 552, 10, 28, 3, 28, 3, 28, 3, 28, 3, 28, 5, 28, 558, 10, 28, 3, 28, 3, 28, 5, 28, 562, 10, 28, 3, 28, 3, 28, 5, 28, 566, 10, 28, 3, 29, 3, 29, 5, 29, 570, 10, 29, 3, 29, 3, 29, 5, 29, 574, 10, 29, 3, 29, 7, 29, 577, 10, 29, 12, 29, 14, 29, 580, 11, 29, 3, 29, 3, 29, 5, 29, 584, 10, 29, 3, 29, 3, 29, 5, 29, 588, 10, 29, 3, 29, 7, 29, 591, 10, 29, 12, 29, 14, 29, 594, 11, 29, 5, 29, 596, 10, 29, 3, 30, 3, 30, 3, 30, 3, 30, 3, 30, 3, 30, 3, 30, 5, 30, 605, 10, 30, 3, 31, 3, 31, 3, 31, 3, 31, 3, 31, 3, 31, 3, 31, 5, 31, 614, 10, 31, 3, 31, 7, 31, 617, 10, 31, 12, 31, 14, 31, 620, 11, 31, 3, 32, 3, 32, 3, 32, 3, 32, 3, 33, 3, 33, 3, 33, 3, 33, 3, 34, 3, 34, 5, 34, 632, 10, 34, 3, 34, 5, 34, 635, 10, 34, 3, 35, 3, 35, 3, 35, 3, 35, 3, 36, 3, 36, 5, 36, 643, 10, 36, 3, 36, 3, 36, 5, 36, 647, 10, 36, 3, 36, 7, 36, 650, 10, 36, 12, 36, 14, 36, 653, 11, 36, 3, 37, 3, 37, 5, 37, 657, 10, 37, 3, 37, 3, 37, 5, 37, 661, 10, 37, 3, 37, 3, 37, 3, 37, 5, 37, 666, 10, 37, 3, 38, 3, 38, 3, 39, 3, 39, 5, 39, 672, 10, 39, 3, 39, 7, 39, 675, 10, 39, 12, 39, 14, 39, 678, 11, 39, 3, 39, 3, 39, 3, 39, 3, 39, 5, 39, 684, 10, 39, 3, 40, 3, 40, 5, 40, 688, 10, 40, 3, 40, 3, 40, 5, 40, 692, 10, 40, 5, 40, 694, 10, 40, 3, 40, 3, 40, 5, 40, 698, 10, 40, 5, 40, 700, 10, 40, 3, 40, 3, 40, 5, 40, 704, 10, 40, 5, 40, 706, 10, 40, 3, 40, 3, 40, 3, 41, 3, 41, 5, 41, 712, 10, 41, 3, 41, 3, 41, 3, 42, 3, 42, 5, 42, 718, 10, 42, 3, 42, 3, 42, 5, 42, 722, 10, 42, 3, 42, 5, 42, 725, 10, 42, 3, 42, 5, 42, 728, 10, 42, 3, 42, 3, 42, 5, 42, 732, 10, 42, 3, 42, 3, 42, 3, 42, 3, 42, 5, 42, 738, 10, 42, 3, 42, 3, 42, 5, 42, 742, 10, 42, 3, 42, 5, 42, 745, 10, 42, 3, 42, 5, 42, 748, 10, 42, 3, 42, 3, 42, 3, 42, 3, 42, 5, 42, 754, 10, 42, 3, 42, 5, 42, 757, 10, 42, 3, 42, 5, 42, 760, 10, 42, 3, 42, 3, 42, 5, 42, 764, 10, 42, 3, 42, 3, 42, 3, 42, 3, 42, 5, 42, 770, 10, 42, 3, 42, 5, 42, 773, 10, 42, 3, 42, 5, 42, 776, 10, 42, 3, 42, 3, 42, 5, 42, 780, 10, 42, 3, 43, 3, 43, 5, 43, 784, 10, 43, 3, 43, 3, 43, 5, 43, 788, 10, 43, 5, 43, 790, 10, 43, 3, 43, 3, 43, 5, 43, 794, 10, 43, 5, 43, 796, 10, 43, 3, 43, 5, 43, 799, 10, 43, 3, 43, 3, 43, 5, 43, 803, 10, 43, 5, 43, 805, 10, 43, 3, 43, 3, 43, 3, 44, 3, 44, 5, 44, 811, 10, 44, 3, 45, 3, 45, 5, 45, 815, 10, 45, 3, 45, 3, 45, 5, 45, 819, 10, 45, 3, 45, 3, 45, 5, 45, 823, 10, 45, 3, 45, 5, 45, 826, 10, 45, 3, 45, 7, 45, 829, 10, 45, 12, 45, 14, 45, 832, 11, 45, 3, 46, 3, 46, 5, 46, 836, 10, 46, 3, 46, 7, 46, 839, 10, 46, 12, 46, 14, 46, 842, 11, 46, 3, 47, 3, 47, 5, 47, 846, 10, 47, 3, 47, 3, 47, 3, 48, 3, 48, 5, 48, 852, 10, 48, 3, 48, 3, 48, 5, 48, 856, 10, 48, 5, 48, 858, 10, 48, 3, 48, 3, 48, 5, 48, 862, 10, 48, 3, 48, 3, 48, 5, 48, 866, 10, 48, 5, 48, 868, 10, 48, 5, 48, 870, 10, 48, 3, 49, 3, 49, 3, 50, 3, 50, 3, 51, 3, 51, 3, 52, 3, 52, 3, 52, 3, 52, 3, 52, 7, 52, 883, 10, 52, 12, 52, 14, 52, 886, 11, 52, 3, 53, 3, 53, 3, 53, 3, 53, 3, 53, 7, 53, 893, 10, 53, 12, 53, 14, 53, 896, 11, 53, 3, 54, 3, 54, 3, 54, 3, 54, 3, 54, 7, 54, 903, 10, 54, 12, 54, 14, 54, 906, 11, 54, 3, 55, 3, 55, 5, 55, 910, 10, 55, 7, 55, 912, 10, 55, 12, 55, 14, 55, 915, 11, 55, 3, 55, 3, 55, 3, 56, 3, 56, 5, 56, 921, 10, 56, 3, 56, 7, 56, 924, 10, 56, 12, 56, 14, 56, 927, 11, 56, 3, 57, 3, 57, 5, 57, 931, 10, 57, 3, 57, 3, 57, 5, 57, 935, 10, 57, 3, 57, 3, 57, 5, 57, 939, 10, 57, 3, 57, 3, 57, 5, 57, 943, 10, 57, 3, 57, 7, 57, 946, 10, 57, 12, 57, 14, 57, 949, 11, 57, 3, 58, 3, 58, 5, 58, 953, 10, 58, 3, 58, 3, 58, 5, 58, 957, 10, 58, 3, 58, 3, 58, 5, 58, 961, 10, 58, 3, 58, 3, 58, 5, 58, 965, 10, 58, 3, 58, 3, 58, 5, 58, 969, 10, 58, 3, 58, 3, 58, 5, 58, 973, 10, 58, 3, 58, 7, 58, 976, 10, 58, 12, 58, 14, 58, 979, 11, 58, 3, 59, 3, 59, 5, 59, 983, 10, 59, 3, 59, 3, 59, 5, 59, 987, 10, 59, 3, 59, 7, 59, 990, 10, 59, 12, 59, 14, 59, 993, 11, 59, 3, 60, 3, 60, 5, 60, 997, 10, 60, 7, 60, 999, 10, 60, 12, 60, 14, 60, 1002, 11, 60, 3, 60, 3, 60, 3, 61, 3, 61, 3, 61, 3, 61, 7, 61, 1010, 10, 61, 12, 61, 14, 61, 1013, 11, 61, 3, 62, 3, 62, 3, 62, 5, 62, 1018, 10, 62, 3, 62, 3, 62, 5, 62, 1022, 10, 62, 3, 62, 3, 62, 3, 62, 3, 62, 3, 62, 5, 62, 1029, 10, 62, 3, 62, 3, 62, 5, 62, 1033, 10, 62, 3, 62, 3, 62, 5, 62, 1037, 10, 62, 3, 62, 5, 62, 1040, 10, 62, 3, 63, 3, 63, 3, 63, 3, 63, 3, 63, 3, 63, 3, 63, 3, 63, 3, 63, 3, 63, 5, 63, 1052, 10, 63, 3, 63, 5, 63, 1055, 10, 63, 3, 63, 3, 63, 3, 64, 3, 64, 3, 64, 3, 64, 3, 64, 3, 64, 3, 64, 3, 64, 3, 64, 3, 64, 5, 64, 1069, 10, 64, 3, 65, 3, 65, 5, 65, 1073, 10, 65, 3, 65, 7, 65, 1076, 10, 65, 12, 65, 14, 65, 1079, 11, 65, 3, 65, 5, 65, 1082, 10, 65, 3, 65, 5, 65, 1085, 10, 65, 3, 66, 3, 66, 3, 66, 3, 66, 3, 66, 5, 66, 1092, 10, 66, 3, 66, 3, 66, 5, 66, 1096, 10, 66, 3, 66, 3, 66, 5, 66, 1100, 10, 66, 3, 66, 3, 66, 3, 66, 3, 66, 3, 66, 5, 66, 1107, 10, 66, 3, 66, 3, 66, 5, 66, 1111, 10, 66, 3, 66, 3, 66, 5, 66, 1115, 10, 66, 3, 66, 3, 66, 3, 66, 3, 66, 5, 66, 1121, 10, 66, 3, 66, 3, 66, 5, 66, 1125, 10, 66, 3, 66, 3, 66, 5, 66, 1129, 10, 66, 3, 66, 3, 66, 3, 66, 3, 66, 5, 66, 1135, 10, 66, 3, 66, 3, 66, 5, 66, 1139, 10, 66, 3, 66, 3, 66, 5, 66, 1143, 10, 66, 3, 66, 3, 66, 3, 66, 3, 66, 5, 66, 1149, 10, 66, 3, 66, 3, 66, 5, 66, 1153, 10, 66, 3, 66, 3, 66, 5, 66, 1157, 10, 66, 3, 66, 3, 66, 3, 66, 3, 66, 3, 66, 3, 66, 5, 66, 1165, 10, 66, 3, 67, 3, 67, 3, 67, 3, 67, 3, 67, 3, 67, 5, 67, 1173, 10, 67, 3, 68, 3, 68, 3, 69, 3, 69, 5, 69, 1179, 10, 69, 3, 69, 3, 69, 5, 69, 1183, 10, 69, 3, 69, 3, 69, 5, 69, 1187, 10, 69, 3, 69, 3, 69, 5, 69, 1191, 10, 69, 7, 69, 1193, 10, 69, 12, 69, 14, 69, 1196, 11, 69, 5, 69, 1198, 10, 69, 3, 69, 3, 69, 3, 70, 3, 70, 5, 70, 1204, 10, 70, 3, 70, 3, 70, 3, 70, 5, 70, 1209, 10, 70, 3, 70, 3, 70, 3, 70, 5, 70, 1214, 10, 70, 3, 70, 3, 70, 3, 70, 5, 70, 1219, 10, 70, 3, 70, 3, 70, 3, 70, 5, 70, 1224, 10, 70, 3, 70, 3, 70, 3, 70, 5, 70, 1229, 10, 70, 3, 70, 5, 70, 1232, 10, 70, 3, 71, 3, 71, 5, 71, 1236, 10, 71, 3, 71, 3, 71, 5, 71, 1240, 10, 71, 3, 71, 3, 71, 3, 72, 3, 72, 5, 72, 1246, 10, 72, 3, 72, 6, 72, 1249, 10, 72, 13, 72, 14, 72, 1250, 3, 73, 3, 73, 5, 73, 1255, 10, 73, 3, 73, 5, 73, 1258, 10, 73, 3, 74, 3, 74, 3, 74, 3, 74, 3, 74, 3, 74, 3, 75, 3, 75, 5, 75, 1268, 10, 75, 3, 75, 3, 75, 5, 75, 1272, 10, 75, 3, 75, 3, 75, 5, 75, 1276, 10, 75, 5, 75, 1278, 10, 75, 3, 75, 3, 75, 5, 75, 1282, 10, 75, 3, 75, 3, 75, 5, 75, 1286, 10, 75, 3, 75, 3, 75, 5, 75, 1290, 10, 75, 7, 75, 1292, 10, 75, 12, 75, 14, 75, 1295, 11, 75, 5, 75, 1297, 10, 75, 3, 75, 3, 75, 3, 76, 3, 76, 3, 76, 3, 76, 5, 76, 1305, 10, 76, 3, 77, 3, 77, 5, 77, 1309, 10, 77, 3, 77, 3, 77, 5, 77, 1313, 10, 77, 3, 77, 3, 77, 5, 77, 1317, 10, 77, 3, 77, 3, 77, 5, 77, 1321, 10, 77, 3, 77, 3, 77, 5, 77, 1325, 10, 77, 7, 77, 1327, 10, 77, 12, 77, 14, 77, 1330, 11, 77, 5, 77, 1332, 10, 77, 3, 77, 3, 77, 3, 78, 3, 78, 3, 79, 3, 79, 3, 80, 3, 80, 3, 80, 3, 81, 3, 81, 3, 81, 7, 81, 1346, 10, 81, 12, 81, 14, 81, 1349, 11, 81, 3, 82, 3, 82, 5, 82, 1353, 10, 82, 3, 82, 3, 82, 5, 82, 1357, 10, 82, 3, 82, 3, 82, 5, 82, 1361, 10, 82, 3, 82, 5, 82, 1364, 10, 82, 3, 82, 5, 82, 1367, 10, 82, 3, 82, 3, 82, 3, 83, 3, 83, 5, 83, 1373, 10, 83, 3, 83, 3, 83, 5, 83, 1377, 10, 83, 3, 83, 3, 83, 5, 83, 1381, 10, 83, 5, 83, 1383, 10, 83, 3, 83, 3, 83, 5, 83, 1387, 10, 83, 3, 83, 3, 83, 5, 83, 1391, 10, 83, 3, 83, 3, 83, 5, 83, 1395, 10, 83, 5, 83, 1397, 10, 83, 3, 83, 3, 83, 5, 83, 1401, 10, 83, 3, 83, 3, 83, 5, 83, 1405, 10, 83, 3, 83, 3, 83, 3, 84, 3, 84, 5, 84, 1411, 10, 84, 3, 84, 3, 84, 3, 85, 3, 85, 5, 85, 1417, 10, 85, 3, 85, 6, 85, 1420, 10, 85, 13, 85, 14, 85, 1421, 3, 85, 3, 85, 5, 85, 1426, 10, 85, 3, 85, 3, 85, 5, 85, 1430, 10, 85, 3, 85, 6, 85, 1433, 10, 85, 13, 85, 14, 85, 1434, 5, 85, 1437, 10, 85, 3, 85, 5, 85, 1440, 10, 85, 3, 85, 3, 85, 5, 85, 1444, 10, 85, 3, 85, 5, 85, 1447, 10, 85, 3, 85, 5, 85, 1450, 10, 85, 3, 85, 3, 85, 3, 86, 3, 86, 5, 86, 1456, 10, 86, 3, 86, 3, 86, 5, 86, 1460, 10, 86, 3, 86, 3, 86, 5, 86, 1464, 10, 86, 3, 86, 3, 86, 3, 87, 3, 87, 3, 88, 3, 88, 5, 88, 1472, 10, 88, 3, 89, 3, 89, 5, 89, 1476, 10, 89, 3, 89, 3, 89, 5, 89, 1480, 10, 89, 3, 89, 3, 89, 5, 89, 1484, 10, 89, 3, 89, 3, 89, 5, 89, 1488, 10, 89, 3, 89, 3, 89, 5, 89, 1492, 10, 89, 3, 89, 3, 89, 5, 89, 1496, 10, 89, 3, 89, 3, 89, 5, 89, 1500, 10, 89, 3, 89, 3, 89, 5, 89, 1504, 10, 89, 7, 89, 1506, 10, 89, 12, 89, 14, 89, 1509, 11, 89, 5, 89, 1511, 10, 89, 3, 89, 3, 89, 3, 90, 3, 90, 3, 90, 5, 90, 1518, 10, 90, 3, 91, 3, 91, 5, 91, 1522, 10, 91, 3, 91, 6, 91, 1525, 10, 91, 13, 91, 14, 91, 1526, 3, 92, 3, 92, 3, 93, 3, 93, 3, 94, 3, 94, 3, 95, 3, 95, 5, 95, 1537, 10, 95, 3, 96, 3, 96, 3, 97, 3, 97, 3, 98, 3, 98, 3, 99, 3, 99, 3, 100, 3, 100, 3, 100, 2, 2, 101, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 2, 12, 3, 2, 70, 73, 3, 2, 15, 16, 3, 2, 89, 90, 3, 2, 99, 101, 3, 2, 109, 110, 6, 2, 48, 60, 63, 84, 89, 96, 111, 120, 6, 2, 85, 88, 102, 102, 121, 123, 126, 126, 4, 2, 21, 21, 29, 32, 4, 2, 22, 22, 33, 36, 4, 2, 16, 16, 37, 47, 2, 1766, 2, 201, 3, 2, 2, 2, 4, 215, 3, 2, 2, 2, 6, 219, 3, 2, 2, 2, 8, 221, 3, 2, 2, 2, 10, 243, 3, 2, 2, 2, 12, 247, 3, 2, 2, 2, 14, 284, 3, 2, 2, 2, 16, 308, 3, 2, 2, 2, 18, 319, 3, 2, 2, 2, 20, 324, 3, 2, 2, 2, 22, 328, 3, 2, 2, 2, 24, 341, 3, 2, 2, 2, 26, 351, 3, 2, 2, 2, 28, 373, 3, 2, 2, 2, 30, 375, 3, 2, 2, 2, 32, 381, 3, 2, 2, 2, 34, 435, 3, 2, 2, 2, 36, 439, 3, 2, 2, 2, 38, 459, 3, 2, 2, 2, 40, 479, 3, 2, 2, 2, 42, 481, 3, 2, 2, 2, 44, 492, 3, 2, 2, 2, 46, 519, 3, 2, 2, 2, 48, 532, 3, 2, 2, 2, 50, 536, 3, 2, 2, 2, 52, 544, 3, 2, 2, 2, 54, 551, 3, 2, 2, 2, 56, 595, 3, 2, 2, 2, 58, 604, 3, 2, 2, 2, 60, 606, 3, 2, 2, 2, 62, 621, 3, 2, 2, 2, 64, 625, 3, 2, 2, 2, 66, 629, 3, 2, 2, 2, 68, 636, 3, 2, 2, 2, 70, 640, 3, 2, 2, 2, 72, 665, 3, 2, 2, 2, 74, 667, 3, 2, 2, 2, 76, 683, 3, 2, 2, 2, 78, 685, 3, 2, 2, 2, 80, 709, 3, 2, 2, 2, 82, 779, 3, 2, 2, 2, 84, 781, 3, 2, 2, 2, 86, 810, 3, 2, 2, 2, 88, 812, 3, 2, 2, 2, 90, 833, 3, 2, 2, 2, 92, 843, 3, 2, 2, 2, 94, 849, 3, 2, 2, 2, 96, 871, 3, 2, 2, 2, 98, 873, 3, 2, 2, 2, 100, 875, 3, 2, 2, 2, 102, 877, 3, 2, 2, 2, 104, 887, 3, 2, 2, 2, 106, 897, 3, 2, 2, 2, 108, 913, 3, 2, 2, 2, 110, 918, 3, 2, 2, 2, 112, 928, 3, 2, 2, 2, 114, 950, 3, 2, 2, 2, 116, 980, 3, 2, 2, 2, 118, 1000, 3, 2, 2, 2, 120, 1005, 3, 2, 2, 2, 122, 1039, 3, 2, 2, 2, 124, 1051, 3, 2, 2, 2, 126, 1068, 3, 2, 2, 2, 128, 1070, 3, 2, 2, 2, 130, 1164, 3, 2, 2, 2, 132, 1172, 3, 2, 2, 2, 134, 1174, 3, 2, 2, 2, 136, 1176, 3, 2, 2, 2, 138, 1231, 3, 2, 2, 2, 140, 1233, 3, 2, 2, 2, 142, 1243, 3, 2, 2, 2, 144, 1252, 3, 2, 2, 2, 146, 1259, 3, 2, 2, 2, 148, 1265, 3, 2, 2, 2, 150, 1304, 3, 2, 2, 2, 152, 1306, 3, 2, 2, 2, 154, 1335, 3, 2, 2, 2, 156, 1337, 3, 2, 2, 2, 158, 1339, 3, 2, 2, 2, 160, 1347, 3, 2, 2, 2, 162, 1350, 3, 2, 2, 2, 164, 1370, 3, 2, 2, 2, 166, 1408, 3, 2, 2, 2, 168, 1436, 3, 2, 2, 2, 170, 1453, 3, 2, 2, 2, 172, 1467, 3, 2, 2, 2, 174, 1471, 3, 2, 2, 2, 176, 1473, 3, 2, 2, 2, 178, 1514, 3, 2, 2, 2, 180, 1519, 3, 2, 2, 2, 182, 1528, 3, 2, 2, 2, 184, 1530, 3, 2, 2, 2, 186, 1532, 3, 2, 2, 2, 188, 1536, 3, 2, 2, 2, 190, 1538, 3, 2, 2, 2, 192, 1540, 3, 2, 2, 2, 194, 1542, 3, 2, 2, 2, 196, 1544, 3, 2, 2, 2, 198, 1546, 3, 2, 2, 2, 200, 202, 7, 127, 2, 2, 201, 200, 3, 2, 2, 2, 201, 202, 3, 2, 2, 2, 202, 203, 3, 2, 2, 2, 203, 208, 5, 4, 3, 2, 204, 206, 7, 127, 2, 2, 205, 204, 3, 2, 2, 2, 205, 206, 3, 2, 2, 2, 206, 207, 3, 2, 2, 2, 207, 209, 7, 3, 2, 2, 208, 205, 3, 2, 2, 2, 208, 209, 3, 2, 2, 2, 209, 211, 3, 2, 2, 2, 210, 212, 7, 127, 2, 2, 211, 210, 3, 2, 2, 2, 211, 212, 3, 2, 2, 2, 212, 213, 3, 2, 2, 2, 213, 214, 7, 2, 2, 3, 214, 3, 3, 2, 2, 2, 215, 216, 5, 6, 4, 2, 216, 5, 3, 2, 2, 2, 217, 220, 5, 8, 5, 2, 218, 220, 5, 44, 23, 2, 219, 217, 3, 2, 2, 2, 219, 218, 3, 2, 2, 2, 220, 7, 3, 2, 2, 2, 221, 228, 5, 12, 7, 2, 222, 224, 7, 127, 2, 2, 223, 222, 3, 2, 2, 2, 223, 224, 3, 2, 2, 2, 224, 225, 3, 2, 2, 2, 225, 227, 5, 10, 6, 2, 226, 223, 3, 2, 2, 2, 227, 230, 3, 2, 2, 2, 228, 226, 3, 2, 2, 2, 228, 229, 3, 2, 2, 2, 229, 9, 3, 2, 2, 2, 230, 228, 3, 2, 2, 2, 231, 232, 7, 48, 2, 2, 232, 233, 7, 127, 2, 2, 233, 235, 7, 49, 2, 2, 234, 236, 7, 127, 2, 2, 235, 234, 3, 2, 2, 2, 235, 236, 3, 2, 2, 2, 236, 237, 3, 2, 2, 2, 237, 244, 5, 12, 7, 2, 238, 240, 7, 48, 2, 2, 239, 241, 7, 127, 2, 2, 240, 239, 3, 2, 2, 2, 240, 241, 3, 2, 2, 2, 241, 242, 3, 2, 2, 2, 242, 244, 5, 12, 7, 2, 243, 231, 3, 2, 2, 2, 243, 238, 3, 2, 2, 2, 244, 11, 3, 2, 2, 2, 245, 248, 5, 14, 8, 2, 246, 248, 5, 16, 9, 2, 247, 245, 3, 2, 2, 2, 247, 246, 3, 2, 2, 2, 248, 13, 3, 2, 2, 2, 249, 251, 5, 20, 11, 2, 250, 252, 7, 127, 2, 2, 251, 250, 3, 2, 2, 2, 251, 252, 3, 2, 2, 2, 252, 254, 3, 2, 2, 2, 253, 249, 3, 2, 2, 2, 254, 257, 3, 2, 2, 2, 255, 253, 3, 2, 2, 2, 255, 256, 3, 2, 2, 2, 256, 258, 3, 2, 2, 2, 257, 255, 3, 2, 2, 2, 258, 285, 5, 52, 27, 2, 259, 261, 5, 20, 11, 2, 260, 262, 7, 127, 2, 2, 261, 260, 3, 2, 2, 2, 261, 262, 3, 2, 2, 2, 262, 264, 3, 2, 2, 2, 263, 259, 3, 2, 2, 2, 264, 267, 3, 2, 2, 2, 265, 263, 3, 2, 2, 2, 265, 266, 3, 2, 2, 2, 266, 268, 3, 2, 2, 2, 267, 265, 3, 2, 2, 2, 268, 275, 5, 18, 10, 2, 269, 271, 7, 127, 2, 2, 270, 269, 3, 2, 2, 2, 270, 271, 3, 2, 2, 2, 271, 272, 3, 2, 2, 2, 272, 274, 5, 18, 10, 2, 273, 270, 3, 2, 2, 2, 274, 277, 3, 2, 2, 2, 275, 273, 3, 2, 2, 2, 275, 276, 3, 2, 2, 2, 276, 282, 3, 2, 2, 2, 277, 275, 3, 2, 2, 2, 278, 280, 7, 127, 2, 2, 279, 278, 3, 2, 2, 2, 279, 280, 3, 2, 2, 2, 280, 281, 3, 2, 2, 2, 281, 283, 5, 52, 27, 2, 282, 279, 3, 2, 2, 2, 282, 283, 3, 2, 2, 2, 283, 285, 3, 2, 2, 2, 284, 255, 3, 2, 2, 2, 284, 265, 3, 2, 2, 2, 285, 15, 3, 2, 2, 2, 286, 288, 5, 20, 11, 2, 287, 289, 7, 127, 2, 2, 288, 287, 3, 2, 2, 2, 288, 289, 3, 2, 2, 2, 289, 291, 3, 2, 2, 2, 290, 286, 3, 2, 2, 2, 291, 294, 3, 2, 2, 2, 292, 290, 3, 2, 2, 2, 292, 293, 3, 2, 2, 2, 293, 301, 3, 2, 2, 2, 294, 292, 3, 2, 2, 2, 295, 297, 5, 18, 10, 2, 296, 298, 7, 127, 2, 2, 297, 296, 3, 2, 2, 2, 297, 298, 3, 2, 2, 2, 298, 300, 3, 2, 2, 2, 299, 295, 3, 2, 2, 2, 300, 303, 3, 2, 2, 2, 301, 299, 3, 2, 2, 2, 301, 302, 3, 2, 2, 2, 302, 304, 3, 2, 2, 2, 303, 301, 3, 2, 2, 2, 304, 306, 5, 50, 26, 2, 305, 307, 7, 127, 2, 2, 306, 305, 3, 2, 2, 2, 306, 307, 3, 2, 2, 2, 307, 309, 3, 2, 2, 2, 308, 292, 3, 2, 2, 2, 309, 310, 3, 2, 2, 2, 310, 308, 3, 2, 2, 2, 310, 311, 3, 2, 2, 2, 311, 312, 3, 2, 2, 2, 312, 313, 5, 14, 8, 2, 313, 17, 3, 2, 2, 2, 314, 320, 5, 30, 16, 2, 315, 320, 5, 26, 14, 2, 316, 320, 5, 36, 19, 2, 317, 320, 5, 32, 17, 2, 318, 320, 5, 38, 20, 2, 319, 314, 3, 2, 2, 2, 319, 315, 3, 2, 2, 2, 319, 316, 3, 2, 2, 2, 319, 317, 3, 2, 2, 2, 319, 318, 3, 2, 2, 2, 320, 19, 3, 2, 2, 2, 321, 325, 5, 22, 12, 2, 322, 325, 5, 24, 13, 2, 323, 325, 5, 42, 22, 2, 324, 321, 3, 2, 2, 2, 324, 322, 3, 2, 2, 2, 324, 323, 3, 2, 2, 2, 325, 21, 3, 2, 2, 2, 326, 327, 7, 50, 2, 2, 327, 329, 7, 127, 2, 2, 328, 326, 3, 2, 2, 2, 328, 329, 3, 2, 2, 2, 329, 330, 3, 2, 2, 2, 330, 332, 7, 51, 2, 2, 331, 333, 7, 127, 2, 2, 332, 331, 3, 2, 2, 2, 332, 333, 3, 2, 2, 2, 333, 334, 3, 2, 2, 2, 334, 339, 5, 70, 36, 2, 335, 337, 7, 127, 2, 2, 336, 335, 3, 2, 2, 2, 336, 337, 3, 2, 2, 2, 337, 338, 3, 2, 2, 2, 338, 340, 5, 68, 35, 2, 339, 336, 3, 2, 2, 2, 339, 340, 3, 2, 2, 2, 340, 23, 3, 2, 2, 2, 341, 343, 7, 52, 2, 2, 342, 344, 7, 127, 2, 2, 343, 342, 3, 2, 2, 2, 343, 344, 3, 2, 2, 2, 344, 345, 3, 2, 2, 2, 345, 346, 5, 100, 51, 2, 346, 347, 7, 127, 2, 2, 347, 348, 7, 53, 2, 2, 348, 349, 7, 127, 2, 2, 349, 350, 5, 172, 87, 2, 350, 25, 3, 2, 2, 2, 351, 353, 7, 54, 2, 2, 352, 354, 7, 127, 2, 2, 353, 352, 3, 2, 2, 2, 353, 354, 3, 2, 2, 2, 354, 355, 3, 2, 2, 2, 355, 360, 5, 72, 37, 2, 356, 357, 7, 127, 2, 2, 357, 359, 5, 28, 15, 2, 358, 356, 3, 2, 2, 2, 359, 362, 3, 2, 2, 2, 360, 358, 3, 2, 2, 2, 360, 361, 3, 2, 2, 2, 361, 27, 3, 2, 2, 2, 362, 360, 3, 2, 2, 2, 363, 364, 7, 55, 2, 2, 364, 365, 7, 127, 2, 2, 365, 366, 7, 51, 2, 2, 366, 367, 7, 127, 2, 2, 367, 374, 5, 32, 17, 2, 368, 369, 7, 55, 2, 2, 369, 370, 7, 127, 2, 2, 370, 371, 7, 56, 2, 2, 371, 372, 7, 127, 2, 2, 372, 374, 5, 32, 17, 2, 373, 363, 3, 2, 2, 2, 373, 368, 3, 2, 2, 2, 374, 29, 3, 2, 2, 2, 375, 377, 7, 56, 2, 2, 376, 378, 7, 127, 2, 2, 377, 376, 3, 2, 2, 2, 377, 378, 3, 2, 2, 2, 378, 379, 3, 2, 2, 2, 379, 380, 5, 70, 36, 2, 380, 31, 3, 2, 2, 2, 381, 383, 7, 57, 2, 2, 382, 384, 7, 127, 2, 2, 383, 382, 3, 2, 2, 2, 383, 384, 3, 2, 2, 2, 384, 385, 3, 2, 2, 2, 385, 396, 5, 34, 18, 2, 386, 388, 7, 127, 2, 2, 387, 386, 3, 2, 2, 2, 387, 388, 3, 2, 2, 2, 388, 389, 3, 2, 2, 2, 389, 391, 7, 4, 2, 2, 390, 392, 7, 127, 2, 2, 391, 390, 3, 2, 2, 2, 391, 392, 3, 2, 2, 2, 392, 393, 3, 2, 2, 2, 393, 395, 5, 34, 18, 2, 394, 387, 3, 2, 2, 2, 395, 398, 3, 2, 2, 2, 396, 394, 3, 2, 2, 2, 396, 397, 3, 2, 2, 2, 397, 33, 3, 2, 2, 2, 398, 396, 3, 2, 2, 2, 399, 401, 5, 180, 91, 2, 400, 402, 7, 127, 2, 2, 401, 400, 3, 2, 2, 2, 401, 402, 3, 2, 2, 2, 402, 403, 3, 2, 2, 2, 403, 405, 7, 5, 2, 2, 404, 406, 7, 127, 2, 2, 405, 404, 3, 2, 2, 2, 405, 406, 3, 2, 2, 2, 406, 407, 3, 2, 2, 2, 407, 408, 5, 100, 51, 2, 408, 436, 3, 2, 2, 2, 409, 411, 5, 172, 87, 2, 410, 412, 7, 127, 2, 2, 411, 410, 3, 2, 2, 2, 411, 412, 3, 2, 2, 2, 412, 413, 3, 2, 2, 2, 413, 415, 7, 5, 2, 2, 414, 416, 7, 127, 2, 2, 415, 414, 3, 2, 2, 2, 415, 416, 3, 2, 2, 2, 416, 417, 3, 2, 2, 2, 417, 418, 5, 100, 51, 2, 418, 436, 3, 2, 2, 2, 419, 421, 5, 172, 87, 2, 420, 422, 7, 127, 2, 2, 421, 420, 3, 2, 2, 2, 421, 422, 3, 2, 2, 2, 422, 423, 3, 2, 2, 2, 423, 425, 7, 6, 2, 2, 424, 426, 7, 127, 2, 2, 425, 424, 3, 2, 2, 2, 425, 426, 3, 2, 2, 2, 426, 427, 3, 2, 2, 2, 427, 428, 5, 100, 51, 2, 428, 436, 3, 2, 2, 2, 429, 431, 5, 172, 87, 2, 430, 432, 7, 127, 2, 2, 431, 430, 3, 2, 2, 2, 431, 432, 3, 2, 2, 2, 432, 433, 3, 2, 2, 2, 433, 434, 5, 90, 46, 2, 434, 436, 3, 2, 2, 2, 435, 399, 3, 2, 2, 2, 435, 409, 3, 2, 2, 2, 435, 419, 3, 2, 2, 2, 435, 429, 3, 2, 2, 2, 436, 35, 3, 2, 2, 2, 437, 438, 7, 58, 2, 2, 438, 440, 7, 127, 2, 2, 439, 437, 3, 2, 2, 2, 439, 440, 3, 2, 2, 2, 440, 441, 3, 2, 2, 2, 441, 443, 7, 59, 2, 2, 442, 444, 7, 127, 2, 2, 443, 442, 3, 2, 2, 2, 443, 444, 3, 2, 2, 2, 444, 445, 3, 2, 2, 2, 445, 456, 5, 100, 51, 2, 446, 448, 7, 127, 2, 2, 447, 446, 3, 2, 2, 2, 447, 448, 3, 2, 2, 2, 448, 449, 3, 2, 2, 2, 449, 451, 7, 4, 2, 2, 450, 452, 7, 127, 2, 2, 451, 450, 3, 2, 2, 2, 451, 452, 3, 2, 2, 2, 452, 453, 3, 2, 2, 2, 453, 455, 5, 100, 51, 2, 454, 447, 3, 2, 2, 2, 455, 458, 3, 2, 2, 2, 456, 454, 3, 2, 2, 2, 456, 457, 3, 2, 2, 2, 457, 37, 3, 2, 2, 2, 458, 456, 3, 2, 2, 2, 459, 460, 7, 60, 2, 2, 460, 461, 7, 127, 2, 2, 461, 472, 5, 40, 21, 2, 462, 464, 7, 127, 2, 2, 463, 462, 3, 2, 2, 2, 463, 464, 3, 2, 2, 2, 464, 465, 3, 2, 2, 2, 465, 467, 7, 4, 2, 2, 466, 468, 7, 127, 2, 2, 467, 466, 3, 2, 2, 2, 467, 468, 3, 2, 2, 2, 468, 469, 3, 2, 2, 2, 469, 471, 5, 40, 21, 2, 470, 463, 3, 2, 2, 2, 471, 474, 3, 2, 2, 2, 472, 470, 3, 2, 2, 2, 472, 473, 3, 2, 2, 2, 473, 39, 3, 2, 2, 2, 474, 472, 3, 2, 2, 2, 475, 476, 5, 172, 87, 2, 476, 477, 5, 90, 46, 2, 477, 480, 3, 2, 2, 2, 478, 480, 5, 180, 91, 2, 479, 475, 3, 2, 2, 2, 479, 478, 3, 2, 2, 2, 480, 41, 3, 2, 2, 2, 481, 482, 7, 61, 2, 2, 482, 483, 7, 127, 2, 2, 483, 490, 5, 152, 77, 2, 484, 486, 7, 127, 2, 2, 485, 484, 3, 2, 2, 2, 485, 486, 3, 2, 2, 2, 486, 487, 3, 2, 2, 2, 487, 488, 7, 62, 2, 2, 488, 489, 7, 127, 2, 2, 489, 491, 5, 46, 24, 2, 490, 485, 3, 2, 2, 2, 490, 491, 3, 2, 2, 2, 491, 43, 3, 2, 2, 2, 492, 493, 7, 61, 2, 2, 493, 496, 7, 127, 2, 2, 494, 497, 5, 152, 77, 2, 495, 497, 5, 154, 78, 2, 496, 494, 3, 2, 2, 2, 496, 495, 3, 2, 2, 2, 497, 502, 3, 2, 2, 2, 498, 499, 7, 127, 2, 2, 499, 500, 7, 62, 2, 2, 500, 501, 7, 127, 2, 2, 501, 503, 5, 46, 24, 2, 502, 498, 3, 2, 2, 2, 502, 503, 3, 2, 2, 2, 503, 45, 3, 2, 2, 2, 504, 520, 7, 7, 2, 2, 505, 516, 5, 48, 25, 2, 506, 508, 7, 127, 2, 2, 507, 506, 3, 2, 2, 2, 507, 508, 3, 2, 2, 2, 508, 509, 3, 2, 2, 2, 509, 511, 7, 4, 2, 2, 510, 512, 7, 127, 2, 2, 511, 510, 3, 2, 2, 2, 511, 512, 3, 2, 2, 2, 512, 513, 3, 2, 2, 2, 513, 515, 5, 48, 25, 2, 514, 507, 3, 2, 2, 2, 515, 518, 3, 2, 2, 2, 516, 514, 3, 2, 2, 2, 516, 517, 3, 2, 2, 2, 517, 520, 3, 2, 2, 2, 518, 516, 3, 2, 2, 2, 519, 504, 3, 2, 2, 2, 519, 505, 3, 2, 2, 2, 520, 525, 3, 2, 2, 2, 521, 523, 7, 127, 2, 2, 522, 521, 3, 2, 2, 2, 522, 523, 3, 2, 2, 2, 523, 524, 3, 2, 2, 2, 524, 526, 5, 68, 35, 2, 525, 522, 3, 2, 2, 2, 525, 526, 3, 2, 2, 2, 526, 47, 3, 2, 2, 2, 527, 528, 5, 156, 79, 2, 528, 529, 7, 127, 2, 2, 529, 530, 7, 53, 2, 2, 530, 531, 7, 127, 2, 2, 531, 533, 3, 2, 2, 2, 532, 527, 3, 2, 2, 2, 532, 533, 3, 2, 2, 2, 533, 534, 3, 2, 2, 2, 534, 535, 5, 172, 87, 2, 535, 49, 3, 2, 2, 2, 536, 537, 7, 63, 2, 2, 537, 542, 5, 54, 28, 2, 538, 540, 7, 127, 2, 2, 539, 538, 3, 2, 2, 2, 539, 540, 3, 2, 2, 2, 540, 541, 3, 2, 2, 2, 541, 543, 5, 68, 35, 2, 542, 539, 3, 2, 2, 2, 542, 543, 3, 2, 2, 2, 543, 51, 3, 2, 2, 2, 544, 545, 7, 64, 2, 2, 545, 546, 5, 54, 28, 2, 546, 53, 3, 2, 2, 2, 547, 549, 7, 127, 2, 2, 548, 547, 3, 2, 2, 2, 548, 549, 3, 2, 2, 2, 549, 550, 3, 2, 2, 2, 550, 552, 7, 65, 2, 2, 551, 548, 3, 2, 2, 2, 551, 552, 3, 2, 2, 2, 552, 553, 3, 2, 2, 2, 553, 554, 7, 127, 2, 2, 554, 557, 5, 56, 29, 2, 555, 556, 7, 127, 2, 2, 556, 558, 5, 60, 31, 2, 557, 555, 3, 2, 2, 2, 557, 558, 3, 2, 2, 2, 558, 561, 3, 2, 2, 2, 559, 560, 7, 127, 2, 2, 560, 562, 5, 62, 32, 2, 561, 559, 3, 2, 2, 2, 561, 562, 3, 2, 2, 2, 562, 565, 3, 2, 2, 2, 563, 564, 7, 127, 2, 2, 564, 566, 5, 64, 33, 2, 565, 563, 3, 2, 2, 2, 565, 566, 3, 2, 2, 2, 566, 55, 3, 2, 2, 2, 567, 578, 7, 7, 2, 2, 568, 570, 7, 127, 2, 2, 569, 568, 3, 2, 2, 2, 569, 570, 3, 2, 2, 2, 570, 571, 3, 2, 2, 2, 571, 573, 7, 4, 2, 2, 572, 574, 7, 127, 2, 2, 573, 572, 3, 2, 2, 2, 573, 574, 3, 2, 2, 2, 574, 575, 3, 2, 2, 2, 575, 577, 5, 58, 30, 2, 576, 569, 3, 2, 2, 2, 577, 580, 3, 2, 2, 2, 578, 576, 3, 2, 2, 2, 578, 579, 3, 2, 2, 2, 579, 596, 3, 2, 2, 2, 580, 578, 3, 2, 2, 2, 581, 592, 5, 58, 30, 2, 582, 584, 7, 127, 2, 2, 583, 582, 3, 2, 2, 2, 583, 584, 3, 2, 2, 2, 584, 585, 3, 2, 2, 2, 585, 587, 7, 4, 2, 2, 586, 588, 7, 127, 2, 2, 587, 586, 3, 2, 2, 2, 587, 588, 3, 2, 2, 2, 588, 589, 3, 2, 2, 2, 589, 591, 5, 58, 30, 2, 590, 583, 3, 2, 2, 2, 591, 594, 3, 2, 2, 2, 592, 590, 3, 2, 2, 2, 592, 593, 3, 2, 2, 2, 593, 596, 3, 2, 2, 2, 594, 592, 3, 2, 2, 2, 595, 567, 3, 2, 2, 2, 595, 581, 3, 2, 2, 2, 596, 57, 3, 2, 2, 2, 597, 598, 5, 100, 51, 2, 598, 599, 7, 127, 2, 2, 599, 600, 7, 53, 2, 2, 600, 601, 7, 127, 2, 2, 601, 602, 5, 172, 87, 2, 602, 605, 3, 2, 2, 2, 603, 605, 5, 100, 51, 2, 604, 597, 3, 2, 2, 2, 604, 603, 3, 2, 2, 2, 605, 59, 3, 2, 2, 2, 606, 607, 7, 66, 2, 2, 607, 608, 7, 127, 2, 2, 608, 609, 7, 67, 2, 2, 609, 610, 7, 127, 2, 2, 610, 618, 5, 66, 34, 2, 611, 613, 7, 4, 2, 2, 612, 614, 7, 127, 2, 2, 613, 612, 3, 2, 2, 2, 613, 614, 3, 2, 2, 2, 614, 615, 3, 2, 2, 2, 615, 617, 5, 66, 34, 2, 616, 611, 3, 2, 2, 2, 617, 620, 3, 2, 2, 2, 618, 616, 3, 2, 2, 2, 618, 619, 3, 2, 2, 2, 619, 61, 3, 2, 2, 2, 620, 618, 3, 2, 2, 2, 621, 622, 7, 68, 2, 2, 622, 623, 7, 127, 2, 2, 623, 624, 5, 100, 51, 2, 624, 63, 3, 2, 2, 2, 625, 626, 7, 69, 2, 2, 626, 627, 7, 127, 2, 2, 627, 628, 5, 100, 51, 2, 628, 65, 3, 2, 2, 2, 629, 634, 5, 100, 51, 2, 630, 632, 7, 127, 2, 2, 631, 630, 3, 2, 2, 2, 631, 632, 3, 2, 2, 2, 632, 633, 3, 2, 2, 2, 633, 635, 9, 2, 2, 2, 634, 631, 3, 2, 2, 2, 634, 635, 3, 2, 2, 2, 635, 67, 3, 2, 2, 2, 636, 637, 7, 74, 2, 2, 637, 638, 7, 127, 2, 2, 638, 639, 5, 100, 51, 2, 639, 69, 3, 2, 2, 2, 640, 651, 5, 72, 37, 2, 641, 643, 7, 127, 2, 2, 642, 641, 3, 2, 2, 2, 642, 643, 3, 2, 2, 2, 643, 644, 3, 2, 2, 2, 644, 646, 7, 4, 2, 2, 645, 647, 7, 127, 2, 2, 646, 645, 3, 2, 2, 2, 646, 647, 3, 2, 2, 2, 647, 648, 3, 2, 2, 2, 648, 650, 5, 72, 37, 2, 649, 642, 3, 2, 2, 2, 650, 653, 3, 2, 2, 2, 651, 649, 3, 2, 2, 2, 651, 652, 3, 2, 2, 2, 652, 71, 3, 2, 2, 2, 653, 651, 3, 2, 2, 2, 654, 656, 5, 172, 87, 2, 655, 657, 7, 127, 2, 2, 656, 655, 3, 2, 2, 2, 656, 657, 3, 2, 2, 2, 657, 658, 3, 2, 2, 2, 658, 660, 7, 5, 2, 2, 659, 661, 7, 127, 2, 2, 660, 659, 3, 2, 2, 2, 660, 661, 3, 2, 2, 2, 661, 662, 3, 2, 2, 2, 662, 663, 5, 74, 38, 2, 663, 666, 3, 2, 2, 2, 664, 666, 5, 74, 38, 2, 665, 654, 3, 2, 2, 2, 665, 664, 3, 2, 2, 2, 666, 73, 3, 2, 2, 2, 667, 668, 5, 76, 39, 2, 668, 75, 3, 2, 2, 2, 669, 676, 5, 78, 40, 2, 670, 672, 7, 127, 2, 2, 671, 670, 3, 2, 2, 2, 671, 672, 3, 2, 2, 2, 672, 673, 3, 2, 2, 2, 673, 675, 5, 80, 41, 2, 674, 671, 3, 2, 2, 2, 675, 678, 3, 2, 2, 2, 676, 674, 3, 2, 2, 2, 676, 677, 3, 2, 2, 2, 677, 684, 3, 2, 2, 2, 678, 676, 3, 2, 2, 2, 679, 680, 7, 8, 2, 2, 680, 681, 5, 76, 39, 2, 681, 682, 7, 9, 2, 2, 682, 684, 3, 2, 2, 2, 683, 669, 3, 2, 2, 2, 683, 679, 3, 2, 2, 2, 684, 77, 3, 2, 2, 2, 685, 687, 7, 8, 2, 2, 686, 688, 7, 127, 2, 2, 687, 686, 3, 2, 2, 2, 687, 688, 3, 2, 2, 2, 688, 693, 3, 2, 2, 2, 689, 691, 5, 172, 87, 2, 690, 692, 7, 127, 2, 2, 691, 690, 3, 2, 2, 2, 691, 692, 3, 2, 2, 2, 692, 694, 3, 2, 2, 2, 693, 689, 3, 2, 2, 2, 693, 694, 3, 2, 2, 2, 694, 699, 3, 2, 2, 2, 695, 697, 5, 90, 46, 2, 696, 698, 7, 127, 2, 2, 697, 696, 3, 2, 2, 2, 697, 698, 3, 2, 2, 2, 698, 700, 3, 2, 2, 2, 699, 695, 3, 2, 2, 2, 699, 700, 3, 2, 2, 2, 700, 705, 3, 2, 2, 2, 701, 703, 5, 86, 44, 2, 702, 704, 7, 127, 2, 2, 703, 702, 3, 2, 2, 2, 703, 704, 3, 2, 2, 2, 704, 706, 3, 2, 2, 2, 705, 701, 3, 2, 2, 2, 705, 706, 3, 2, 2, 2, 706, 707, 3, 2, 2, 2, 707, 708, 7, 9, 2, 2, 708, 79, 3, 2, 2, 2, 709, 711, 5, 82, 42, 2, 710, 712, 7, 127, 2, 2, 711, 710, 3, 2, 2, 2, 711, 712, 3, 2, 2, 2, 712, 713, 3, 2, 2, 2, 713, 714, 5, 78, 40, 2, 714, 81, 3, 2, 2, 2, 715, 717, 5, 194, 98, 2, 716, 718, 7, 127, 2, 2, 717, 716, 3, 2, 2, 2, 717, 718, 3, 2, 2, 2, 718, 719, 3, 2, 2, 2, 719, 721, 5, 198, 100, 2, 720, 722, 7, 127, 2, 2, 721, 720, 3, 2, 2, 2, 721, 722, 3, 2, 2, 2, 722, 724, 3, 2, 2, 2, 723, 725, 5, 84, 43, 2, 724, 723, 3, 2, 2, 2, 724, 725, 3, 2, 2, 2, 725, 727, 3, 2, 2, 2, 726, 728, 7, 127, 2, 2, 727, 726, 3, 2, 2, 2, 727, 728, 3, 2, 2, 2, 728, 729, 3, 2, 2, 2, 729, 731, 5, 198, 100, 2, 730, 732, 7, 127, 2, 2, 731, 730, 3, 2, 2, 2, 731, 732, 3, 2, 2, 2, 732, 733, 3, 2, 2, 2, 733, 734, 5, 196, 99, 2, 734, 780, 3, 2, 2, 2, 735, 737, 5, 194, 98, 2, 736, 738, 7, 127, 2, 2, 737, 736, 3, 2, 2, 2, 737, 738, 3, 2, 2, 2, 738, 739, 3, 2, 2, 2, 739, 741, 5, 198, 100, 2, 740, 742, 7, 127, 2, 2, 741, 740, 3, 2, 2, 2, 741, 742, 3, 2, 2, 2, 742, 744, 3, 2, 2, 2, 743, 745, 5, 84, 43, 2, 744, 743, 3, 2, 2, 2, 744, 745, 3, 2, 2, 2, 745, 747, 3, 2, 2, 2, 746, 748, 7, 127, 2, 2, 747, 746, 3, 2, 2, 2, 747, 748, 3, 2, 2, 2, 748, 749, 3, 2, 2, 2, 749, 750, 5, 198, 100, 2, 750, 780, 3, 2, 2, 2, 751, 753, 5, 198, 100, 2, 752, 754, 7, 127, 2, 2, 753, 752, 3, 2, 2, 2, 753, 754, 3, 2, 2, 2, 754, 756, 3, 2, 2, 2, 755, 757, 5, 84, 43, 2, 756, 755, 3, 2, 2, 2, 756, 757, 3, 2, 2, 2, 757, 759, 3, 2, 2, 2, 758, 760, 7, 127, 2, 2, 759, 758, 3, 2, 2, 2, 759, 760, 3, 2, 2, 2, 760, 761, 3, 2, 2, 2, 761, 763, 5, 198, 100, 2, 762, 764, 7, 127, 2, 2, 763, 762, 3, 2, 2, 2, 763, 764, 3, 2, 2, 2, 764, 765, 3, 2, 2, 2, 765, 766, 5, 196, 99, 2, 766, 780, 3, 2, 2, 2, 767, 769, 5, 198, 100, 2, 768, 770, 7, 127, 2, 2, 769, 768, 3, 2, 2, 2, 769, 770, 3, 2, 2, 2, 770, 772, 3, 2, 2, 2, 771, 773, 5, 84, 43, 2, 772, 771, 3, 2, 2, 2, 772, 773, 3, 2, 2, 2, 773, 775, 3, 2, 2, 2, 774, 776, 7, 127, 2, 2, 775, 774, 3, 2, 2, 2, 775, 776, 3, 2, 2, 2, 776, 777, 3, 2, 2, 2, 777, 778, 5, 198, 100, 2, 778, 780, 3, 2, 2, 2, 779, 715, 3, 2, 2, 2, 779, 735, 3, 2, 2, 2, 779, 751, 3, 2, 2, 2, 779, 767, 3, 2, 2, 2, 780, 83, 3, 2, 2, 2, 781, 783, 7, 10, 2, 2, 782, 784, 7, 127, 2, 2, 783, 782, 3, 2, 2, 2, 783, 784, 3, 2, 2, 2, 784, 789, 3, 2, 2, 2, 785, 787, 5, 172, 87, 2, 786, 788, 7, 127, 2, 2, 787, 786, 3, 2, 2, 2, 787, 788, 3, 2, 2, 2, 788, 790, 3, 2, 2, 2, 789, 785, 3, 2, 2, 2, 789, 790, 3, 2, 2, 2, 790, 795, 3, 2, 2, 2, 791, 793, 5, 88, 45, 2, 792, 794, 7, 127, 2, 2, 793, 792, 3, 2, 2, 2, 793, 794, 3, 2, 2, 2, 794, 796, 3, 2, 2, 2, 795, 791, 3, 2, 2, 2, 795, 796, 3, 2, 2, 2, 796, 798, 3, 2, 2, 2, 797, 799, 5, 94, 48, 2, 798, 797, 3, 2, 2, 2, 798, 799, 3, 2, 2, 2, 799, 804, 3, 2, 2, 2, 800, 802, 5, 86, 44, 2, 801, 803, 7, 127, 2, 2, 802, 801, 3, 2, 2, 2, 802, 803, 3, 2, 2, 2, 803, 805, 3, 2, 2, 2, 804, 800, 3, 2, 2, 2, 804, 805, 3, 2, 2, 2, 805, 806, 3, 2, 2, 2, 806, 807, 7, 11, 2, 2, 807, 85, 3, 2, 2, 2, 808, 811, 5, 176, 89, 2, 809, 811, 5, 178, 90, 2, 810, 808, 3, 2, 2, 2, 810, 809, 3, 2, 2, 2, 811, 87, 3, 2, 2, 2, 812, 814, 7, 12, 2, 2, 813, 815, 7, 127, 2, 2, 814, 813, 3, 2, 2, 2, 814, 815, 3, 2, 2, 2, 815, 816, 3, 2, 2, 2, 816, 830, 5, 98, 50, 2, 817, 819, 7, 127, 2, 2, 818, 817, 3, 2, 2, 2, 818, 819, 3, 2, 2, 2, 819, 820, 3, 2, 2, 2, 820, 822, 7, 13, 2, 2, 821, 823, 7, 12, 2, 2, 822, 821, 3, 2, 2, 2, 822, 823, 3, 2, 2, 2, 823, 825, 3, 2, 2, 2, 824, 826, 7, 127, 2, 2, 825, 824, 3, 2, 2, 2, 825, 826, 3, 2, 2, 2, 826, 827, 3, 2, 2, 2, 827, 829, 5, 98, 50, 2, 828, 818, 3, 2, 2, 2, 829, 832, 3, 2, 2, 2, 830, 828, 3, 2, 2, 2, 830, 831, 3, 2, 2, 2, 831, 89, 3, 2, 2, 2, 832, 830, 3, 2, 2, 2, 833, 840, 5, 92, 47, 2, 834, 836, 7, 127, 2, 2, 835, 834, 3, 2, 2, 2, 835, 836, 3, 2, 2, 2, 836, 837, 3, 2, 2, 2, 837, 839, 5, 92, 47, 2, 838, 835, 3, 2, 2, 2, 839, 842, 3, 2, 2, 2, 840, 838, 3, 2, 2, 2, 840, 841, 3, 2, 2, 2, 841, 91, 3, 2, 2, 2, 842, 840, 3, 2, 2, 2, 843, 845, 7, 12, 2, 2, 844, 846, 7, 127, 2, 2, 845, 844, 3, 2, 2, 2, 845, 846, 3, 2, 2, 2, 846, 847, 3, 2, 2, 2, 847, 848, 5, 96, 49, 2, 848, 93, 3, 2, 2, 2, 849, 851, 7, 7, 2, 2, 850, 852, 7, 127, 2, 2, 851, 850, 3, 2, 2, 2, 851, 852, 3, 2, 2, 2, 852, 857, 3, 2, 2, 2, 853, 855, 5, 184, 93, 2, 854, 856, 7, 127, 2, 2, 855, 854, 3, 2, 2, 2, 855, 856, 3, 2, 2, 2, 856, 858, 3, 2, 2, 2, 857, 853, 3, 2, 2, 2, 857, 858, 3, 2, 2, 2, 858, 869, 3, 2, 2, 2, 859, 861, 7, 14, 2, 2, 860, 862, 7, 127, 2, 2, 861, 860, 3, 2, 2, 2, 861, 862, 3, 2, 2, 2, 862, 867, 3, 2, 2, 2, 863, 865, 5, 184, 93, 2, 864, 866, 7, 127, 2, 2, 865, 864, 3, 2, 2, 2, 865, 866, 3, 2, 2, 2, 866, 868, 3, 2, 2, 2, 867, 863, 3, 2, 2, 2, 867, 868, 3, 2, 2, 2, 868, 870, 3, 2, 2, 2, 869, 859, 3, 2, 2, 2, 869, 870, 3, 2, 2, 2, 870, 95, 3, 2, 2, 2, 871, 872, 5, 188, 95, 2, 872, 97, 3, 2, 2, 2, 873, 874, 5, 188, 95, 2, 874, 99, 3, 2, 2, 2, 875, 876, 5, 102, 52, 2, 876, 101, 3, 2, 2, 2, 877, 884, 5, 104, 53, 2, 878, 879, 7, 127, 2, 2, 879, 880, 7, 75, 2, 2, 880, 881, 7, 127, 2, 2, 881, 883, 5, 104, 53, 2, 882, 878, 3, 2, 2, 2, 883, 886, 3, 2, 2, 2, 884, 882, 3, 2, 2, 2, 884, 885, 3, 2, 2, 2, 885, 103, 3, 2, 2, 2, 886, 884, 3, 2, 2, 2, 887, 894, 5, 106, 54, 2, 888, 889, 7, 127, 2, 2, 889, 890, 7, 76, 2, 2, 890, 891, 7, 127, 2, 2, 891, 893, 5, 106, 54, 2, 892, 888, 3, 2, 2, 2, 893, 896, 3, 2, 2, 2, 894, 892, 3, 2, 2, 2, 894, 895, 3, 2, 2, 2, 895, 105, 3, 2, 2, 2, 896, 894, 3, 2, 2, 2, 897, 904, 5, 108, 55, 2, 898, 899, 7, 127, 2, 2, 899, 900, 7, 77, 2, 2, 900, 901, 7, 127, 2, 2, 901, 903, 5, 108, 55, 2, 902, 898, 3, 2, 2, 2, 903, 906, 3, 2, 2, 2, 904, 902, 3, 2, 2, 2, 904, 905, 3, 2, 2, 2, 905, 107, 3, 2, 2, 2, 906, 904, 3, 2, 2, 2, 907, 909, 7, 78, 2, 2, 908, 910, 7, 127, 2, 2, 909, 908, 3, 2, 2, 2, 909, 910, 3, 2, 2, 2, 910, 912, 3, 2, 2, 2, 911, 907, 3, 2, 2, 2, 912, 915, 3, 2, 2, 2, 913, 911, 3, 2, 2, 2, 913, 914, 3, 2, 2, 2, 914, 916, 3, 2, 2, 2, 915, 913, 3, 2, 2, 2, 916, 917, 5, 110, 56, 2, 917, 109, 3, 2, 2, 2, 918, 925, 5, 112, 57, 2, 919, 921, 7, 127, 2, 2, 920, 919, 3, 2, 2, 2, 920, 921, 3, 2, 2, 2, 921, 922, 3, 2, 2, 2, 922, 924, 5, 138, 70, 2, 923, 920, 3, 2, 2, 2, 924, 927, 3, 2, 2, 2, 925, 923, 3, 2, 2, 2, 925, 926, 3, 2, 2, 2, 926, 111, 3, 2, 2, 2, 927, 925, 3, 2, 2, 2, 928, 947, 5, 114, 58, 2, 929, 931, 7, 127, 2, 2, 930, 929, 3, 2, 2, 2, 930, 931, 3, 2, 2, 2, 931, 932, 3, 2, 2, 2, 932, 934, 7, 15, 2, 2, 933, 935, 7, 127, 2, 2, 934, 933, 3, 2, 2, 2, 934, 935, 3, 2, 2, 2, 935, 936, 3, 2, 2, 2, 936, 946, 5, 114, 58, 2, 937, 939, 7, 127, 2, 2, 938, 937, 3, 2, 2, 2, 938, 939, 3, 2, 2, 2, 939, 940, 3, 2, 2, 2, 940, 942, 7, 16, 2, 2, 941, 943, 7, 127, 2, 2, 942, 941, 3, 2, 2, 2, 942, 943, 3, 2, 2, 2, 943, 944, 3, 2, 2, 2, 944, 946, 5, 114, 58, 2, 945, 930, 3, 2, 2, 2, 945, 938, 3, 2, 2, 2, 946, 949, 3, 2, 2, 2, 947, 945, 3, 2, 2, 2, 947, 948, 3, 2, 2, 2, 948, 113, 3, 2, 2, 2, 949, 947, 3, 2, 2, 2, 950, 977, 5, 116, 59, 2, 951, 953, 7, 127, 2, 2, 952, 951, 3, 2, 2, 2, 952, 953, 3, 2, 2, 2, 953, 954, 3, 2, 2, 2, 954, 956, 7, 7, 2, 2, 955, 957, 7, 127, 2, 2, 956, 955, 3, 2, 2, 2, 956, 957, 3, 2, 2, 2, 957, 958, 3, 2, 2, 2, 958, 976, 5, 116, 59, 2, 959, 961, 7, 127, 2, 2, 960, 959, 3, 2, 2, 2, 960, 961, 3, 2, 2, 2, 961, 962, 3, 2, 2, 2, 962, 964, 7, 17, 2, 2, 963, 965, 7, 127, 2, 2, 964, 963, 3, 2, 2, 2, 964, 965, 3, 2, 2, 2, 965, 966, 3, 2, 2, 2, 966, 976, 5, 116, 59, 2, 967, 969, 7, 127, 2, 2, 968, 967, 3, 2, 2, 2, 968, 969, 3, 2, 2, 2, 969, 970, 3, 2, 2, 2, 970, 972, 7, 18, 2, 2, 971, 973, 7, 127, 2, 2, 972, 971, 3, 2, 2, 2, 972, 973, 3, 2, 2, 2, 973, 974, 3, 2, 2, 2, 974, 976, 5, 116, 59, 2, 975, 952, 3, 2, 2, 2, 975, 960, 3, 2, 2, 2, 975, 968, 3, 2, 2, 2, 976, 979, 3, 2, 2, 2, 977, 975, 3, 2, 2, 2, 977, 978, 3, 2, 2, 2, 978, 115, 3, 2, 2, 2, 979, 977, 3, 2, 2, 2, 980, 991, 5, 118, 60, 2, 981, 983, 7, 127, 2, 2, 982, 981, 3, 2, 2, 2, 982, 983, 3, 2, 2, 2, 983, 984, 3, 2, 2, 2, 984, 986, 7, 19, 2, 2, 985, 987, 7, 127, 2, 2, 986, 985, 3, 2, 2, 2, 986, 987, 3, 2, 2, 2, 987, 988, 3, 2, 2, 2, 988, 990, 5, 118, 60, 2, 989, 982, 3, 2, 2, 2, 990, 993, 3, 2, 2, 2, 991, 989, 3, 2, 2, 2, 991, 992, 3, 2, 2, 2, 992, 117, 3, 2, 2, 2, 993, 991, 3, 2, 2, 2, 994, 996, 9, 3, 2, 2, 995, 997, 7, 127, 2, 2, 996, 995, 3, 2, 2, 2, 996, 997, 3, 2, 2, 2, 997, 999, 3, 2, 2, 2, 998, 994, 3, 2, 2, 2, 999, 1002, 3, 2, 2, 2, 1000, 998, 3, 2, 2, 2, 1000, 1001, 3, 2, 2, 2, 1001, 1003, 3, 2, 2, 2, 1002, 1000, 3, 2, 2, 2, 1003, 1004, 5, 120, 61, 2, 1004, 119, 3, 2, 2, 2, 1005, 1011, 5, 128, 65, 2, 1006, 1010, 5, 124, 63, 2, 1007, 1010, 5, 122, 62, 2, 1008, 1010, 5, 126, 64, 2, 1009, 1006, 3, 2, 2, 2, 1009, 1007, 3, 2, 2, 2, 1009, 1008, 3, 2, 2, 2, 1010, 1013, 3, 2, 2, 2, 1011, 1009, 3, 2, 2, 2, 1011, 1012, 3, 2, 2, 2, 1012, 121, 3, 2, 2, 2, 1013, 1011, 3, 2, 2, 2, 1014, 1015, 7, 127, 2, 2, 1015, 1017, 7, 79, 2, 2, 1016, 1018, 7, 127, 2, 2, 1017, 1016, 3, 2, 2, 2, 1017, 1018, 3, 2, 2, 2, 1018, 1019, 3, 2, 2, 2, 1019, 1040, 5, 128, 65, 2, 1020, 1022, 7, 127, 2, 2, 1021, 1020, 3, 2, 2, 2, 1021, 1022, 3, 2, 2, 2, 1022, 1023, 3, 2, 2, 2, 1023, 1024, 7, 10, 2, 2, 1024, 1025, 5, 100, 51, 2, 1025, 1026, 7, 11, 2, 2, 1026, 1040, 3, 2, 2, 2, 1027, 1029, 7, 127, 2, 2, 1028, 1027, 3, 2, 2, 2, 1028, 1029, 3, 2, 2, 2, 1029, 1030, 3, 2, 2, 2, 1030, 1032, 7, 10, 2, 2, 1031, 1033, 5, 100, 51, 2, 1032, 1031, 3, 2, 2, 2, 1032, 1033, 3, 2, 2, 2, 1033, 1034, 3, 2, 2, 2, 1034, 1036, 7, 14, 2, 2, 1035, 1037, 5, 100, 51, 2, 1036, 1035, 3, 2, 2, 2, 1036, 1037, 3, 2, 2, 2, 1037, 1038, 3, 2, 2, 2, 1038, 1040, 7, 11, 2, 2, 1039, 1014, 3, 2, 2, 2, 1039, 1021, 3, 2, 2, 2, 1039, 1028, 3, 2, 2, 2, 1040, 123, 3, 2, 2, 2, 1041, 1042, 7, 127, 2, 2, 1042, 1043, 7, 80, 2, 2, 1043, 1044, 7, 127, 2, 2, 1044, 1052, 7, 63, 2, 2, 1045, 1046, 7, 127, 2, 2, 1046, 1047, 7, 81, 2, 2, 1047, 1048, 7, 127, 2, 2, 1048, 1052, 7, 63, 2, 2, 1049, 1050, 7, 127, 2, 2, 1050, 1052, 7, 82, 2, 2, 1051, 1041, 3, 2, 2, 2, 1051, 1045, 3, 2, 2, 2, 1051, 1049, 3, 2, 2, 2, 1052, 1054, 3, 2, 2, 2, 1053, 1055, 7, 127, 2, 2, 1054, 1053, 3, 2, 2, 2, 1054, 1055, 3, 2, 2, 2, 1055, 1056, 3, 2, 2, 2, 1056, 1057, 5, 128, 65, 2, 1057, 125, 3, 2, 2, 2, 1058, 1059, 7, 127, 2, 2, 1059, 1060, 7, 83, 2, 2, 1060, 1061, 7, 127, 2, 2, 1061, 1069, 7, 84, 2, 2, 1062, 1063, 7, 127, 2, 2, 1063, 1064, 7, 83, 2, 2, 1064, 1065, 7, 127, 2, 2, 1065, 1066, 7, 78, 2, 2, 1066, 1067, 7, 127, 2, 2, 1067, 1069, 7, 84, 2, 2, 1068, 1058, 3, 2, 2, 2, 1068, 1062, 3, 2, 2, 2, 1069, 127, 3, 2, 2, 2, 1070, 1077, 5, 130, 66, 2, 1071, 1073, 7, 127, 2, 2, 1072, 1071, 3, 2, 2, 2, 1072, 1073, 3, 2, 2, 2, 1073, 1074, 3, 2, 2, 2, 1074, 1076, 5, 166, 84, 2, 1075, 1072, 3, 2, 2, 2, 1076, 1079, 3, 2, 2, 2, 1077, 1075, 3, 2, 2, 2, 1077, 1078, 3, 2, 2, 2, 1078, 1084, 3, 2, 2, 2, 1079, 1077, 3, 2, 2, 2, 1080, 1082, 7, 127, 2, 2, 1081, 1080, 3, 2, 2, 2, 1081, 1082, 3, 2, 2, 2, 1082, 1083, 3, 2, 2, 2, 1083, 1085, 5, 90, 46, 2, 1084, 1081, 3, 2, 2, 2, 1084, 1085, 3, 2, 2, 2, 1085, 129, 3, 2, 2, 2, 1086, 1165, 5, 132, 67, 2, 1087, 1165, 5, 178, 90, 2, 1088, 1165, 5, 168, 85, 2, 1089, 1091, 7, 85, 2, 2, 1090, 1092, 7, 127, 2, 2, 1091, 1090, 3, 2, 2, 2, 1091, 1092, 3, 2, 2, 2, 1092, 1093, 3, 2, 2, 2, 1093, 1095, 7, 8, 2, 2, 1094, 1096, 7, 127, 2, 2, 1095, 1094, 3, 2, 2, 2, 1095, 1096, 3, 2, 2, 2, 1096, 1097, 3, 2, 2, 2, 1097, 1099, 7, 7, 2, 2, 1098, 1100, 7, 127, 2, 2, 1099, 1098, 3, 2, 2, 2, 1099, 1100, 3, 2, 2, 2, 1100, 1101, 3, 2, 2, 2, 1101, 1165, 7, 9, 2, 2, 1102, 1165, 5, 162, 82, 2, 1103, 1165, 5, 164, 83, 2, 1104, 1106, 7, 49, 2, 2, 1105, 1107, 7, 127, 2, 2, 1106, 1105, 3, 2, 2, 2, 1106, 1107, 3, 2, 2, 2, 1107, 1108, 3, 2, 2, 2, 1108, 1110, 7, 8, 2, 2, 1109, 1111, 7, 127, 2, 2, 1110, 1109, 3, 2, 2, 2, 1110, 1111, 3, 2, 2, 2, 1111, 1112, 3, 2, 2, 2, 1112, 1114, 5, 144, 73, 2, 1113, 1115, 7, 127, 2, 2, 1114, 1113, 3, 2, 2, 2, 1114, 1115, 3, 2, 2, 2, 1115, 1116, 3, 2, 2, 2, 1116, 1117, 7, 9, 2, 2, 1117, 1165, 3, 2, 2, 2, 1118, 1120, 7, 86, 2, 2, 1119, 1121, 7, 127, 2, 2, 1120, 1119, 3, 2, 2, 2, 1120, 1121, 3, 2, 2, 2, 1121, 1122, 3, 2, 2, 2, 1122, 1124, 7, 8, 2, 2, 1123, 1125, 7, 127, 2, 2, 1124, 1123, 3, 2, 2, 2, 1124, 1125, 3, 2, 2, 2, 1125, 1126, 3, 2, 2, 2, 1126, 1128, 5, 144, 73, 2, 1127, 1129, 7, 127, 2, 2, 1128, 1127, 3, 2, 2, 2, 1128, 1129, 3, 2, 2, 2, 1129, 1130, 3, 2, 2, 2, 1130, 1131, 7, 9, 2, 2, 1131, 1165, 3, 2, 2, 2, 1132, 1134, 7, 87, 2, 2, 1133, 1135, 7, 127, 2, 2, 1134, 1133, 3, 2, 2, 2, 1134, 1135, 3, 2, 2, 2, 1135, 1136, 3, 2, 2, 2, 1136, 1138, 7, 8, 2, 2, 1137, 1139, 7, 127, 2, 2, 1138, 1137, 3, 2, 2, 2, 1138, 1139, 3, 2, 2, 2, 1139, 1140, 3, 2, 2, 2, 1140, 1142, 5, 144, 73, 2, 1141, 1143, 7, 127, 2, 2, 1142, 1141, 3, 2, 2, 2, 1142, 1143, 3, 2, 2, 2, 1143, 1144, 3, 2, 2, 2, 1144, 1145, 7, 9, 2, 2, 1145, 1165, 3, 2, 2, 2, 1146, 1148, 7, 88, 2, 2, 1147, 1149, 7, 127, 2, 2, 1148, 1147, 3, 2, 2, 2, 1148, 1149, 3, 2, 2, 2, 1149, 1150, 3, 2, 2, 2, 1150, 1152, 7, 8, 2, 2, 1151, 1153, 7, 127, 2, 2, 1152, 1151, 3, 2, 2, 2, 1152, 1153, 3, 2, 2, 2, 1153, 1154, 3, 2, 2, 2, 1154, 1156, 5, 144, 73, 2, 1155, 1157, 7, 127, 2, 2, 1156, 1155, 3, 2, 2, 2, 1156, 1157, 3, 2, 2, 2, 1157, 1158, 3, 2, 2, 2, 1158, 1159, 7, 9, 2, 2, 1159, 1165, 3, 2, 2, 2, 1160, 1165, 5, 142, 72, 2, 1161, 1165, 5, 140, 71, 2, 1162, 1165, 5, 148, 75, 2, 1163, 1165, 5, 172, 87, 2, 1164, 1086, 3, 2, 2, 2, 1164, 1087, 3, 2, 2, 2, 1164, 1088, 3, 2, 2, 2, 1164, 1089, 3, 2, 2, 2, 1164, 1102, 3, 2, 2, 2, 1164, 1103, 3, 2, 2, 2, 1164, 1104, 3, 2, 2, 2, 1164, 1118, 3, 2, 2, 2, 1164, 1132, 3, 2, 2, 2, 1164, 1146, 3, 2, 2, 2, 1164, 1160, 3, 2, 2, 2, 1164, 1161, 3, 2, 2, 2, 1164, 1162, 3, 2, 2, 2, 1164, 1163, 3, 2, 2, 2, 1165, 131, 3, 2, 2, 2, 1166, 1173, 5, 174, 88, 2, 1167, 1173, 7, 97, 2, 2, 1168, 1173, 5, 134, 68, 2, 1169, 1173, 7, 84, 2, 2, 1170, 1173, 5, 176, 89, 2, 1171, 1173, 5, 136, 69, 2, 1172, 1166, 3, 2, 2, 2, 1172, 1167, 3, 2, 2, 2, 1172, 1168, 3, 2, 2, 2, 1172, 1169, 3, 2, 2, 2, 1172, 1170, 3, 2, 2, 2, 1172, 1171, 3, 2, 2, 2, 1173, 133, 3, 2, 2, 2, 1174, 1175, 9, 4, 2, 2, 1175, 135, 3, 2, 2, 2, 1176, 1178, 7, 10, 2, 2, 1177, 1179, 7, 127, 2, 2, 1178, 1177, 3, 2, 2, 2, 1178, 1179, 3, 2, 2, 2, 1179, 1197, 3, 2, 2, 2, 1180, 1182, 5, 100, 51, 2, 1181, 1183, 7, 127, 2, 2, 1182, 1181, 3, 2, 2, 2, 1182, 1183, 3, 2, 2, 2, 1183, 1194, 3, 2, 2, 2, 1184, 1186, 7, 4, 2, 2, 1185, 1187, 7, 127, 2, 2, 1186, 1185, 3, 2, 2, 2, 1186, 1187, 3, 2, 2, 2, 1187, 1188, 3, 2, 2, 2, 1188, 1190, 5, 100, 51, 2, 1189, 1191, 7, 127, 2, 2, 1190, 1189, 3, 2, 2, 2, 1190, 1191, 3, 2, 2, 2, 1191, 1193, 3, 2, 2, 2, 1192, 1184, 3, 2, 2, 2, 1193, 1196, 3, 2, 2, 2, 1194, 1192, 3, 2, 2, 2, 1194, 1195, 3, 2, 2, 2, 1195, 1198, 3, 2, 2, 2, 1196, 1194, 3, 2, 2, 2, 1197, 1180, 3, 2, 2, 2, 1197, 1198, 3, 2, 2, 2, 1198, 1199, 3, 2, 2, 2, 1199, 1200, 7, 11, 2, 2, 1200, 137, 3, 2, 2, 2, 1201, 1203, 7, 5, 2, 2, 1202, 1204, 7, 127, 2, 2, 1203, 1202, 3, 2, 2, 2, 1203, 1204, 3, 2, 2, 2, 1204, 1205, 3, 2, 2, 2, 1205, 1232, 5, 112, 57, 2, 1206, 1208, 7, 20, 2, 2, 1207, 1209, 7, 127, 2, 2, 1208, 1207, 3, 2, 2, 2, 1208, 1209, 3, 2, 2, 2, 1209, 1210, 3, 2, 2, 2, 1210, 1232, 5, 112, 57, 2, 1211, 1213, 7, 21, 2, 2, 1212, 1214, 7, 127, 2, 2, 1213, 1212, 3, 2, 2, 2, 1213, 1214, 3, 2, 2, 2, 1214, 1215, 3, 2, 2, 2, 1215, 1232, 5, 112, 57, 2, 1216, 1218, 7, 22, 2, 2, 1217, 1219, 7, 127, 2, 2, 1218, 1217, 3, 2, 2, 2, 1218, 1219, 3, 2, 2, 2, 1219, 1220, 3, 2, 2, 2, 1220, 1232, 5, 112, 57, 2, 1221, 1223, 7, 23, 2, 2, 1222, 1224, 7, 127, 2, 2, 1223, 1222, 3, 2, 2, 2, 1223, 1224, 3, 2, 2, 2, 1224, 1225, 3, 2, 2, 2, 1225, 1232, 5, 112, 57, 2, 1226, 1228, 7, 24, 2, 2, 1227, 1229, 7, 127, 2, 2, 1228, 1227, 3, 2, 2, 2, 1228, 1229, 3, 2, 2, 2, 1229, 1230, 3, 2, 2, 2, 1230, 1232, 5, 112, 57, 2, 1231, 1201, 3, 2, 2, 2, 1231, 1206, 3, 2, 2, 2, 1231, 1211, 3, 2, 2, 2, 1231, 1216, 3, 2, 2, 2, 1231, 1221, 3, 2, 2, 2, 1231, 1226, 3, 2, 2, 2, 1232, 139, 3, 2, 2, 2, 1233, 1235, 7, 8, 2, 2, 1234, 1236, 7, 127, 2, 2, 1235, 1234, 3, 2, 2, 2, 1235, 1236, 3, 2, 2, 2, 1236, 1237, 3, 2, 2, 2, 1237, 1239, 5, 100, 51, 2, 1238, 1240, 7, 127, 2, 2, 1239, 1238, 3, 2, 2, 2, 1239, 1240, 3, 2, 2, 2, 1240, 1241, 3, 2, 2, 2, 1241, 1242, 7, 9, 2, 2, 1242, 141, 3, 2, 2, 2, 1243, 1248, 5, 78, 40, 2, 1244, 1246, 7, 127, 2, 2, 1245, 1244, 3, 2, 2, 2, 1245, 1246, 3, 2, 2, 2, 1246, 1247, 3, 2, 2, 2, 1247, 1249, 5, 80, 41, 2, 1248, 1245, 3, 2, 2, 2, 1249, 1250, 3, 2, 2, 2, 1250, 1248, 3, 2, 2, 2, 1250, 1251, 3, 2, 2, 2, 1251, 143, 3, 2, 2, 2, 1252, 1257, 5, 146, 74, 2, 1253, 1255, 7, 127, 2, 2, 1254, 1253, 3, 2, 2, 2, 1254, 1255, 3, 2, 2, 2, 1255, 1256, 3, 2, 2, 2, 1256, 1258, 5, 68, 35, 2, 1257, 1254, 3, 2, 2, 2, 1257, 1258, 3, 2, 2, 2, 1258, 145, 3, 2, 2, 2, 1259, 1260, 5, 172, 87, 2, 1260, 1261, 7, 127, 2, 2, 1261, 1262, 7, 79, 2, 2, 1262, 1263, 7, 127, 2, 2, 1263, 1264, 5, 100, 51, 2, 1264, 147, 3, 2, 2, 2, 1265, 1267, 5, 150, 76, 2, 1266, 1268, 7, 127, 2, 2, 1267, 1266, 3, 2, 2, 2, 1267, 1268, 3, 2, 2, 2, 1268, 1269, 3, 2, 2, 2, 1269, 1271, 7, 8, 2, 2, 1270, 1272, 7, 127, 2, 2, 1271, 1270, 3, 2, 2, 2, 1271, 1272, 3, 2, 2, 2, 1272, 1277, 3, 2, 2, 2, 1273, 1275, 7, 65, 2, 2, 1274, 1276, 7, 127, 2, 2, 1275, 1274, 3, 2, 2, 2, 1275, 1276, 3, 2, 2, 2, 1276, 1278, 3, 2, 2, 2, 1277, 1273, 3, 2, 2, 2, 1277, 1278, 3, 2, 2, 2, 1278, 1296, 3, 2, 2, 2, 1279, 1281, 5, 100, 51, 2, 1280, 1282, 7, 127, 2, 2, 1281, 1280, 3, 2, 2, 2, 1281, 1282, 3, 2, 2, 2, 1282, 1293, 3, 2, 2, 2, 1283, 1285, 7, 4, 2, 2, 1284, 1286, 7, 127, 2, 2, 1285, 1284, 3, 2, 2, 2, 1285, 1286, 3, 2, 2, 2, 1286, 1287, 3, 2, 2, 2, 1287, 1289, 5, 100, 51, 2, 1288, 1290, 7, 127, 2, 2, 1289, 1288, 3, 2, 2, 2, 1289, 1290, 3, 2, 2, 2, 1290, 1292, 3, 2, 2, 2, 1291, 1283, 3, 2, 2, 2, 1292, 1295, 3, 2, 2, 2, 1293, 1291, 3, 2, 2, 2, 1293, 1294, 3, 2, 2, 2, 1294, 1297, 3, 2, 2, 2, 1295, 1293, 3, 2, 2, 2, 1296, 1279, 3, 2, 2, 2, 1296, 1297, 3, 2, 2, 2, 1297, 1298, 3, 2, 2, 2, 1298, 1299, 7, 9, 2, 2, 1299, 149, 3, 2, 2, 2, 1300, 1301, 5, 160, 81, 2, 1301, 1302, 5, 192, 97, 2, 1302, 1305, 3, 2, 2, 2, 1303, 1305, 7, 91, 2, 2, 1304, 1300, 3, 2, 2, 2, 1304, 1303, 3, 2, 2, 2, 1305, 151, 3, 2, 2, 2, 1306, 1308, 5, 158, 80, 2, 1307, 1309, 7, 127, 2, 2, 1308, 1307, 3, 2, 2, 2, 1308, 1309, 3, 2, 2, 2, 1309, 1310, 3, 2, 2, 2, 1310, 1312, 7, 8, 2, 2, 1311, 1313, 7, 127, 2, 2, 1312, 1311, 3, 2, 2, 2, 1312, 1313, 3, 2, 2, 2, 1313, 1331, 3, 2, 2, 2, 1314, 1316, 5, 100, 51, 2, 1315, 1317, 7, 127, 2, 2, 1316, 1315, 3, 2, 2, 2, 1316, 1317, 3, 2, 2, 2, 1317, 1328, 3, 2, 2, 2, 1318, 1320, 7, 4, 2, 2, 1319, 1321, 7, 127, 2, 2, 1320, 1319, 3, 2, 2, 2, 1320, 1321, 3, 2, 2, 2, 1321, 1322, 3, 2, 2, 2, 1322, 1324, 5, 100, 51, 2, 1323, 1325, 7, 127, 2, 2, 1324, 1323, 3, 2, 2, 2, 1324, 1325, 3, 2, 2, 2, 1325, 1327, 3, 2, 2, 2, 1326, 1318, 3, 2, 2, 2, 1327, 1330, 3, 2, 2, 2, 1328, 1326, 3, 2, 2, 2, 1328, 1329, 3, 2, 2, 2, 1329, 1332, 3, 2, 2, 2, 1330, 1328, 3, 2, 2, 2, 1331, 1314, 3, 2, 2, 2, 1331, 1332, 3, 2, 2, 2, 1332, 1333, 3, 2, 2, 2, 1333, 1334, 7, 9, 2, 2, 1334, 153, 3, 2, 2, 2, 1335, 1336, 5, 158, 80, 2, 1336, 155, 3, 2, 2, 2, 1337, 1338, 5, 192, 97, 2, 1338, 157, 3, 2, 2, 2, 1339, 1340, 5, 160, 81, 2, 1340, 1341, 5, 192, 97, 2, 1341, 159, 3, 2, 2, 2, 1342, 1343, 5, 192, 97, 2, 1343, 1344, 7, 25, 2, 2, 1344, 1346, 3, 2, 2, 2, 1345, 1342, 3, 2, 2, 2, 1346, 1349, 3, 2, 2, 2, 1347, 1345, 3, 2, 2, 2, 1347, 1348, 3, 2, 2, 2, 1348, 161, 3, 2, 2, 2, 1349, 1347, 3, 2, 2, 2, 1350, 1352, 7, 10, 2, 2, 1351, 1353, 7, 127, 2, 2, 1352, 1351, 3, 2, 2, 2, 1352, 1353, 3, 2, 2, 2, 1353, 1354, 3, 2, 2, 2, 1354, 1363, 5, 144, 73, 2, 1355, 1357, 7, 127, 2, 2, 1356, 1355, 3, 2, 2, 2, 1356, 1357, 3, 2, 2, 2, 1357, 1358, 3, 2, 2, 2, 1358, 1360, 7, 13, 2, 2, 1359, 1361, 7, 127, 2, 2, 1360, 1359, 3, 2, 2, 2, 1360, 1361, 3, 2, 2, 2, 1361, 1362, 3, 2, 2, 2, 1362, 1364, 5, 100, 51, 2, 1363, 1356, 3, 2, 2, 2, 1363, 1364, 3, 2, 2, 2, 1364, 1366, 3, 2, 2, 2, 1365, 1367, 7, 127, 2, 2, 1366, 1365, 3, 2, 2, 2, 1366, 1367, 3, 2, 2, 2, 1367, 1368, 3, 2, 2, 2, 1368, 1369, 7, 11, 2, 2, 1369, 163, 3, 2, 2, 2, 1370, 1372, 7, 10, 2, 2, 1371, 1373, 7, 127, 2, 2, 1372, 1371, 3, 2, 2, 2, 1372, 1373, 3, 2, 2, 2, 1373, 1382, 3, 2, 2, 2, 1374, 1376, 5, 172, 87, 2, 1375, 1377, 7, 127, 2, 2, 1376, 1375, 3, 2, 2, 2, 1376, 1377, 3, 2, 2, 2, 1377, 1378, 3, 2, 2, 2, 1378, 1380, 7, 5, 2, 2, 1379, 1381, 7, 127, 2, 2, 1380, 1379, 3, 2, 2, 2, 1380, 1381, 3, 2, 2, 2, 1381, 1383, 3, 2, 2, 2, 1382, 1374, 3, 2, 2, 2, 1382, 1383, 3, 2, 2, 2, 1383, 1384, 3, 2, 2, 2, 1384, 1386, 5, 142, 72, 2, 1385, 1387, 7, 127, 2, 2, 1386, 1385, 3, 2, 2, 2, 1386, 1387, 3, 2, 2, 2, 1387, 1396, 3, 2, 2, 2, 1388, 1390, 7, 74, 2, 2, 1389, 1391, 7, 127, 2, 2, 1390, 1389, 3, 2, 2, 2, 1390, 1391, 3, 2, 2, 2, 1391, 1392, 3, 2, 2, 2, 1392, 1394, 5, 100, 51, 2, 1393, 1395, 7, 127, 2, 2, 1394, 1393, 3, 2, 2, 2, 1394, 1395, 3, 2, 2, 2, 1395, 1397, 3, 2, 2, 2, 1396, 1388, 3, 2, 2, 2, 1396, 1397, 3, 2, 2, 2, 1397, 1398, 3, 2, 2, 2, 1398, 1400, 7, 13, 2, 2, 1399, 1401, 7, 127, 2, 2, 1400, 1399, 3, 2, 2, 2, 1400, 1401, 3, 2, 2, 2, 1401, 1402, 3, 2, 2, 2, 1402, 1404, 5, 100, 51, 2, 1403, 1405, 7, 127, 2, 2, 1404, 1403, 3, 2, 2, 2, 1404, 1405, 3, 2, 2, 2, 1405, 1406, 3, 2, 2, 2, 1406, 1407, 7, 11, 2, 2, 1407, 165, 3, 2, 2, 2, 1408, 1410, 7, 25, 2, 2, 1409, 1411, 7, 127, 2, 2, 1410, 1409, 3, 2, 2, 2, 1410, 1411, 3, 2, 2, 2, 1411, 1412, 3, 2, 2, 2, 1412, 1413, 5, 182, 92, 2, 1413, 167, 3, 2, 2, 2, 1414, 1419, 7, 92, 2, 2, 1415, 1417, 7, 127, 2, 2, 1416, 1415, 3, 2, 2, 2, 1416, 1417, 3, 2, 2, 2, 1417, 1418, 3, 2, 2, 2, 1418, 1420, 5, 170, 86, 2, 1419, 1416, 3, 2, 2, 2, 1420, 1421, 3, 2, 2, 2, 1421, 1419, 3, 2, 2, 2, 1421, 1422, 3, 2, 2, 2, 1422, 1437, 3, 2, 2, 2, 1423, 1425, 7, 92, 2, 2, 1424, 1426, 7, 127, 2, 2, 1425, 1424, 3, 2, 2, 2, 1425, 1426, 3, 2, 2, 2, 1426, 1427, 3, 2, 2, 2, 1427, 1432, 5, 100, 51, 2, 1428, 1430, 7, 127, 2, 2, 1429, 1428, 3, 2, 2, 2, 1429, 1430, 3, 2, 2, 2, 1430, 1431, 3, 2, 2, 2, 1431, 1433, 5, 170, 86, 2, 1432, 1429, 3, 2, 2, 2, 1433, 1434, 3, 2, 2, 2, 1434, 1432, 3, 2, 2, 2, 1434, 1435, 3, 2, 2, 2, 1435, 1437, 3, 2, 2, 2, 1436, 1414, 3, 2, 2, 2, 1436, 1423, 3, 2, 2, 2, 1437, 1446, 3, 2, 2, 2, 1438, 1440, 7, 127, 2, 2, 1439, 1438, 3, 2, 2, 2, 1439, 1440, 3, 2, 2, 2, 1440, 1441, 3, 2, 2, 2, 1441, 1443, 7, 93, 2, 2, 1442, 1444, 7, 127, 2, 2, 1443, 1442, 3, 2, 2, 2, 1443, 1444, 3, 2, 2, 2, 1444, 1445, 3, 2, 2, 2, 1445, 1447, 5, 100, 51, 2, 1446, 1439, 3, 2, 2, 2, 1446, 1447, 3, 2, 2, 2, 1447, 1449, 3, 2, 2, 2, 1448, 1450, 7, 127, 2, 2, 1449, 1448, 3, 2, 2, 2, 1449, 1450, 3, 2, 2, 2, 1450, 1451, 3, 2, 2, 2, 1451, 1452, 7, 94, 2, 2, 1452, 169, 3, 2, 2, 2, 1453, 1455, 7, 95, 2, 2, 1454, 1456, 7, 127, 2, 2, 1455, 1454, 3, 2, 2, 2, 1455, 1456, 3, 2, 2, 2, 1456, 1457, 3, 2, 2, 2, 1457, 1459, 5, 100, 51, 2, 1458, 1460, 7, 127, 2, 2, 1459, 1458, 3, 2, 2, 2, 1459, 1460, 3, 2, 2, 2, 1460, 1461, 3, 2, 2, 2, 1461, 1463, 7, 96, 2, 2, 1462, 1464, 7, 127, 2, 2, 1463, 1462, 3, 2, 2, 2, 1463, 1464, 3, 2, 2, 2, 1464, 1465, 3, 2, 2, 2, 1465, 1466, 5, 100, 51, 2, 1466, 171, 3, 2, 2, 2, 1467, 1468, 5, 192, 97, 2, 1468, 173, 3, 2, 2, 2, 1469, 1472, 5, 186, 94, 2, 1470, 1472, 5, 184, 93, 2, 1471, 1469, 3, 2, 2, 2, 1471, 1470, 3, 2, 2, 2, 1472, 175, 3, 2, 2, 2, 1473, 1475, 7, 26, 2, 2, 1474, 1476, 7, 127, 2, 2, 1475, 1474, 3, 2, 2, 2, 1475, 1476, 3, 2, 2, 2, 1476, 1510, 3, 2, 2, 2, 1477, 1479, 5, 182, 92, 2, 1478, 1480, 7, 127, 2, 2, 1479, 1478, 3, 2, 2, 2, 1479, 1480, 3, 2, 2, 2, 1480, 1481, 3, 2, 2, 2, 1481, 1483, 7, 12, 2, 2, 1482, 1484, 7, 127, 2, 2, 1483, 1482, 3, 2, 2, 2, 1483, 1484, 3, 2, 2, 2, 1484, 1485, 3, 2, 2, 2, 1485, 1487, 5, 100, 51, 2, 1486, 1488, 7, 127, 2, 2, 1487, 1486, 3, 2, 2, 2, 1487, 1488, 3, 2, 2, 2, 1488, 1507, 3, 2, 2, 2, 1489, 1491, 7, 4, 2, 2, 1490, 1492, 7, 127, 2, 2, 1491, 1490, 3, 2, 2, 2, 1491, 1492, 3, 2, 2, 2, 1492, 1493, 3, 2, 2, 2, 1493, 1495, 5, 182, 92, 2, 1494, 1496, 7, 127, 2, 2, 1495, 1494, 3, 2, 2, 2, 1495, 1496, 3, 2, 2, 2, 1496, 1497, 3, 2, 2, 2, 1497, 1499, 7, 12, 2, 2, 1498, 1500, 7, 127, 2, 2, 1499, 1498, 3, 2, 2, 2, 1499, 1500, 3, 2, 2, 2, 1500, 1501, 3, 2, 2, 2, 1501, 1503, 5, 100, 51, 2, 1502, 1504, 7, 127, 2, 2, 1503, 1502, 3, 2, 2, 2, 1503, 1504, 3, 2, 2, 2, 1504, 1506, 3, 2, 2, 2, 1505, 1489, 3, 2, 2, 2, 1506, 1509, 3, 2, 2, 2, 1507, 1505, 3, 2, 2, 2, 1507, 1508, 3, 2, 2, 2, 1508, 1511, 3, 2, 2, 2, 1509, 1507, 3, 2, 2, 2, 1510, 1477, 3, 2, 2, 2, 1510, 1511, 3, 2, 2, 2, 1511, 1512, 3, 2, 2, 2, 1512, 1513, 7, 27, 2, 2, 1513, 177, 3, 2, 2, 2, 1514, 1517, 7, 28, 2, 2, 1515, 1518, 5, 192, 97, 2, 1516, 1518, 7, 100, 2, 2, 1517, 1515, 3, 2, 2, 2, 1517, 1516, 3, 2, 2, 2, 1518, 179, 3, 2, 2, 2, 1519, 1524, 5, 130, 66, 2, 1520, 1522, 7, 127, 2, 2, 1521, 1520, 3, 2, 2, 2, 1521, 1522, 3, 2, 2, 2, 1522, 1523, 3, 2, 2, 2, 1523, 1525, 5, 166, 84, 2, 1524, 1521, 3, 2, 2, 2, 1525, 1526, 3, 2, 2, 2, 1526, 1524, 3, 2, 2, 2, 1526, 1527, 3, 2, 2, 2, 1527, 181, 3, 2, 2, 2, 1528, 1529, 5, 188, 95, 2, 1529, 183, 3, 2, 2, 2, 1530, 1531, 9, 5, 2, 2, 1531, 185, 3, 2, 2, 2, 1532, 1533, 9, 6, 2, 2, 1533, 187, 3, 2, 2, 2, 1534, 1537, 5, 192, 97, 2, 1535, 1537, 5, 190, 96, 2, 1536, 1534, 3, 2, 2, 2, 1536, 1535, 3, 2, 2, 2, 1537, 189, 3, 2, 2, 2, 1538, 1539, 9, 7, 2, 2, 1539, 191, 3, 2, 2, 2, 1540, 1541, 9, 8, 2, 2, 1541, 193, 3, 2, 2, 2, 1542, 1543, 9, 9, 2, 2, 1543, 195, 3, 2, 2, 2, 1544, 1545, 9, 10, 2, 2, 1545, 197, 3, 2, 2, 2, 1546, 1547, 9, 11, 2, 2, 1547, 199, 3, 2, 2, 2, 287, 201, 205, 208, 211, 219, 223, 228, 235, 240, 243, 247, 251, 255, 261, 265, 270, 275, 279, 282, 284, 288, 292, 297, 301, 306, 310, 319, 324, 328, 332, 336, 339, 343, 353, 360, 373, 377, 383, 387, 391, 396, 401, 405, 411, 415, 421, 425, 431, 435, 439, 443, 447, 451, 456, 463, 467, 472, 479, 485, 490, 496, 502, 507, 511, 516, 519, 522, 525, 532, 539, 542, 548, 551, 557, 561, 565, 569, 573, 578, 583, 587, 592, 595, 604, 613, 618, 631, 634, 642, 646, 651, 656, 660, 665, 671, 676, 683, 687, 691, 693, 697, 699, 703, 705, 711, 717, 721, 724, 727, 731, 737, 741, 744, 747, 753, 756, 759, 763, 769, 772, 775, 779, 783, 787, 789, 793, 795, 798, 802, 804, 810, 814, 818, 822, 825, 830, 835, 840, 845, 851, 855, 857, 861, 865, 867, 869, 884, 894, 904, 909, 913, 920, 925, 930, 934, 938, 942, 945, 947, 952, 956, 960, 964, 968, 972, 975, 977, 982, 986, 991, 996, 1000, 1009, 1011, 1017, 1021, 1028, 1032, 1036, 1039, 1051, 1054, 1068, 1072, 1077, 1081, 1084, 1091, 1095, 1099, 1106, 1110, 1114, 1120, 1124, 1128, 1134, 1138, 1142, 1148, 1152, 1156, 1164, 1172, 1178, 1182, 1186, 1190, 1194, 1197, 1203, 1208, 1213, 1218, 1223, 1228, 1231, 1235, 1239, 1245, 1250, 1254, 1257, 1267, 1271, 1275, 1277, 1281, 1285, 1289, 1293, 1296, 1304, 1308, 1312, 1316, 1320, 1324, 1328, 1331, 1347, 1352, 1356, 1360, 1363, 1366, 1372, 1376, 1380, 1382, 1386, 1390, 1394, 1396, 1400, 1404, 1410, 1416, 1421, 1425, 1429, 1434, 1436, 1439, 1443, 1446, 1449, 1455, 1459, 1463, 1471, 1475, 1479, 1483, 1487, 1491, 1495, 1499, 1503, 1507, 1510, 1517, 1521, 1526, 1536] \ No newline at end of file diff --git a/parser/Cypher.tokens b/parser/Cypher.tokens new file mode 100644 index 0000000..9dacb2a --- /dev/null +++ b/parser/Cypher.tokens @@ -0,0 +1,173 @@ +T__0=1 +T__1=2 +T__2=3 +T__3=4 +T__4=5 +T__5=6 +T__6=7 +T__7=8 +T__8=9 +T__9=10 +T__10=11 +T__11=12 +T__12=13 +T__13=14 +T__14=15 +T__15=16 +T__16=17 +T__17=18 +T__18=19 +T__19=20 +T__20=21 +T__21=22 +T__22=23 +T__23=24 +T__24=25 +T__25=26 +T__26=27 +T__27=28 +T__28=29 +T__29=30 +T__30=31 +T__31=32 +T__32=33 +T__33=34 +T__34=35 +T__35=36 +T__36=37 +T__37=38 +T__38=39 +T__39=40 +T__40=41 +T__41=42 +T__42=43 +T__43=44 +T__44=45 +UNION=46 +ALL=47 +OPTIONAL=48 +MATCH=49 +UNWIND=50 +AS=51 +MERGE=52 +ON=53 +CREATE=54 +SET=55 +DETACH=56 +DELETE=57 +REMOVE=58 +CALL=59 +YIELD=60 +WITH=61 +RETURN=62 +DISTINCT=63 +ORDER=64 +BY=65 +L_SKIP=66 +LIMIT=67 +ASCENDING=68 +ASC=69 +DESCENDING=70 +DESC=71 +WHERE=72 +OR=73 +XOR=74 +AND=75 +NOT=76 +IN=77 +STARTS=78 +ENDS=79 +CONTAINS=80 +IS=81 +NULL=82 +COUNT=83 +ANY=84 +NONE=85 +SINGLE=86 +TRUE=87 +FALSE=88 +EXISTS=89 +CASE=90 +ELSE=91 +END=92 +WHEN=93 +THEN=94 +StringLiteral=95 +EscapedChar=96 +HexInteger=97 +DecimalInteger=98 +OctalInteger=99 +HexLetter=100 +HexDigit=101 +Digit=102 +NonZeroDigit=103 +NonZeroOctDigit=104 +OctDigit=105 +ZeroDigit=106 +ExponentDecimalReal=107 +RegularDecimalReal=108 +CONSTRAINT=109 +DO=110 +FOR=111 +REQUIRE=112 +UNIQUE=113 +MANDATORY=114 +SCALAR=115 +OF=116 +ADD=117 +DROP=118 +FILTER=119 +EXTRACT=120 +UnescapedSymbolicName=121 +IdentifierStart=122 +IdentifierPart=123 +EscapedSymbolicName=124 +SP=125 +WHITESPACE=126 +Comment=127 +';'=1 +','=2 +'='=3 +'+='=4 +'*'=5 +'('=6 +')'=7 +'['=8 +']'=9 +':'=10 +'|'=11 +'..'=12 +'+'=13 +'-'=14 +'/'=15 +'%'=16 +'^'=17 +'<>'=18 +'<'=19 +'>'=20 +'<='=21 +'>='=22 +'.'=23 +'{'=24 +'}'=25 +'$'=26 +'\u27e8'=27 +'\u3008'=28 +'\ufe64'=29 +'\uff1c'=30 +'\u27e9'=31 +'\u3009'=32 +'\ufe65'=33 +'\uff1e'=34 +'\u00ad'=35 +'\u2010'=36 +'\u2011'=37 +'\u2012'=38 +'\u2013'=39 +'\u2014'=40 +'\u2015'=41 +'\u2212'=42 +'\ufe58'=43 +'\ufe63'=44 +'\uff0d'=45 +'0'=106 diff --git a/parser/CypherLexer.interp b/parser/CypherLexer.interp new file mode 100644 index 0000000..eb62597 --- /dev/null +++ b/parser/CypherLexer.interp @@ -0,0 +1,418 @@ +token literal names: +null +';' +',' +'=' +'+=' +'*' +'(' +')' +'[' +']' +':' +'|' +'..' +'+' +'-' +'/' +'%' +'^' +'<>' +'<' +'>' +'<=' +'>=' +'.' +'{' +'}' +'$' +'\u27e8' +'\u3008' +'\ufe64' +'\uff1c' +'\u27e9' +'\u3009' +'\ufe65' +'\uff1e' +'\u00ad' +'\u2010' +'\u2011' +'\u2012' +'\u2013' +'\u2014' +'\u2015' +'\u2212' +'\ufe58' +'\ufe63' +'\uff0d' +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +'0' +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null + +token symbolic names: +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +UNION +ALL +OPTIONAL +MATCH +UNWIND +AS +MERGE +ON +CREATE +SET +DETACH +DELETE +REMOVE +CALL +YIELD +WITH +RETURN +DISTINCT +ORDER +BY +L_SKIP +LIMIT +ASCENDING +ASC +DESCENDING +DESC +WHERE +OR +XOR +AND +NOT +IN +STARTS +ENDS +CONTAINS +IS +NULL +COUNT +ANY +NONE +SINGLE +TRUE +FALSE +EXISTS +CASE +ELSE +END +WHEN +THEN +StringLiteral +EscapedChar +HexInteger +DecimalInteger +OctalInteger +HexLetter +HexDigit +Digit +NonZeroDigit +NonZeroOctDigit +OctDigit +ZeroDigit +ExponentDecimalReal +RegularDecimalReal +CONSTRAINT +DO +FOR +REQUIRE +UNIQUE +MANDATORY +SCALAR +OF +ADD +DROP +FILTER +EXTRACT +UnescapedSymbolicName +IdentifierStart +IdentifierPart +EscapedSymbolicName +SP +WHITESPACE +Comment + +rule names: +T__0 +T__1 +T__2 +T__3 +T__4 +T__5 +T__6 +T__7 +T__8 +T__9 +T__10 +T__11 +T__12 +T__13 +T__14 +T__15 +T__16 +T__17 +T__18 +T__19 +T__20 +T__21 +T__22 +T__23 +T__24 +T__25 +T__26 +T__27 +T__28 +T__29 +T__30 +T__31 +T__32 +T__33 +T__34 +T__35 +T__36 +T__37 +T__38 +T__39 +T__40 +T__41 +T__42 +T__43 +T__44 +UNION +ALL +OPTIONAL +MATCH +UNWIND +AS +MERGE +ON +CREATE +SET +DETACH +DELETE +REMOVE +CALL +YIELD +WITH +RETURN +DISTINCT +ORDER +BY +L_SKIP +LIMIT +ASCENDING +ASC +DESCENDING +DESC +WHERE +OR +XOR +AND +NOT +IN +STARTS +ENDS +CONTAINS +IS +NULL +COUNT +ANY +NONE +SINGLE +TRUE +FALSE +EXISTS +CASE +ELSE +END +WHEN +THEN +StringLiteral +EscapedChar +HexInteger +DecimalInteger +OctalInteger +HexLetter +HexDigit +Digit +NonZeroDigit +NonZeroOctDigit +OctDigit +ZeroDigit +ExponentDecimalReal +RegularDecimalReal +CONSTRAINT +DO +FOR +REQUIRE +UNIQUE +MANDATORY +SCALAR +OF +ADD +DROP +FILTER +EXTRACT +UnescapedSymbolicName +IdentifierStart +IdentifierPart +EscapedSymbolicName +SP +WHITESPACE +Comment +FF +EscapedSymbolicName_0 +RS +ID_Continue +Comment_1 +StringLiteral_1 +Comment_3 +Comment_2 +GS +FS +CR +Sc +SPACE +Pc +TAB +StringLiteral_0 +LF +VT +US +ID_Start + +channel names: +DEFAULT_TOKEN_CHANNEL +HIDDEN + +mode names: +DEFAULT_MODE + +atn: +[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 129, 993, 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, 28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9, 32, 4, 33, 9, 33, 4, 34, 9, 34, 4, 35, 9, 35, 4, 36, 9, 36, 4, 37, 9, 37, 4, 38, 9, 38, 4, 39, 9, 39, 4, 40, 9, 40, 4, 41, 9, 41, 4, 42, 9, 42, 4, 43, 9, 43, 4, 44, 9, 44, 4, 45, 9, 45, 4, 46, 9, 46, 4, 47, 9, 47, 4, 48, 9, 48, 4, 49, 9, 49, 4, 50, 9, 50, 4, 51, 9, 51, 4, 52, 9, 52, 4, 53, 9, 53, 4, 54, 9, 54, 4, 55, 9, 55, 4, 56, 9, 56, 4, 57, 9, 57, 4, 58, 9, 58, 4, 59, 9, 59, 4, 60, 9, 60, 4, 61, 9, 61, 4, 62, 9, 62, 4, 63, 9, 63, 4, 64, 9, 64, 4, 65, 9, 65, 4, 66, 9, 66, 4, 67, 9, 67, 4, 68, 9, 68, 4, 69, 9, 69, 4, 70, 9, 70, 4, 71, 9, 71, 4, 72, 9, 72, 4, 73, 9, 73, 4, 74, 9, 74, 4, 75, 9, 75, 4, 76, 9, 76, 4, 77, 9, 77, 4, 78, 9, 78, 4, 79, 9, 79, 4, 80, 9, 80, 4, 81, 9, 81, 4, 82, 9, 82, 4, 83, 9, 83, 4, 84, 9, 84, 4, 85, 9, 85, 4, 86, 9, 86, 4, 87, 9, 87, 4, 88, 9, 88, 4, 89, 9, 89, 4, 90, 9, 90, 4, 91, 9, 91, 4, 92, 9, 92, 4, 93, 9, 93, 4, 94, 9, 94, 4, 95, 9, 95, 4, 96, 9, 96, 4, 97, 9, 97, 4, 98, 9, 98, 4, 99, 9, 99, 4, 100, 9, 100, 4, 101, 9, 101, 4, 102, 9, 102, 4, 103, 9, 103, 4, 104, 9, 104, 4, 105, 9, 105, 4, 106, 9, 106, 4, 107, 9, 107, 4, 108, 9, 108, 4, 109, 9, 109, 4, 110, 9, 110, 4, 111, 9, 111, 4, 112, 9, 112, 4, 113, 9, 113, 4, 114, 9, 114, 4, 115, 9, 115, 4, 116, 9, 116, 4, 117, 9, 117, 4, 118, 9, 118, 4, 119, 9, 119, 4, 120, 9, 120, 4, 121, 9, 121, 4, 122, 9, 122, 4, 123, 9, 123, 4, 124, 9, 124, 4, 125, 9, 125, 4, 126, 9, 126, 4, 127, 9, 127, 4, 128, 9, 128, 4, 129, 9, 129, 4, 130, 9, 130, 4, 131, 9, 131, 4, 132, 9, 132, 4, 133, 9, 133, 4, 134, 9, 134, 4, 135, 9, 135, 4, 136, 9, 136, 4, 137, 9, 137, 4, 138, 9, 138, 4, 139, 9, 139, 4, 140, 9, 140, 4, 141, 9, 141, 4, 142, 9, 142, 4, 143, 9, 143, 4, 144, 9, 144, 4, 145, 9, 145, 4, 146, 9, 146, 4, 147, 9, 147, 4, 148, 9, 148, 3, 2, 3, 2, 3, 3, 3, 3, 3, 4, 3, 4, 3, 5, 3, 5, 3, 5, 3, 6, 3, 6, 3, 7, 3, 7, 3, 8, 3, 8, 3, 9, 3, 9, 3, 10, 3, 10, 3, 11, 3, 11, 3, 12, 3, 12, 3, 13, 3, 13, 3, 13, 3, 14, 3, 14, 3, 15, 3, 15, 3, 16, 3, 16, 3, 17, 3, 17, 3, 18, 3, 18, 3, 19, 3, 19, 3, 19, 3, 20, 3, 20, 3, 21, 3, 21, 3, 22, 3, 22, 3, 22, 3, 23, 3, 23, 3, 23, 3, 24, 3, 24, 3, 25, 3, 25, 3, 26, 3, 26, 3, 27, 3, 27, 3, 28, 3, 28, 3, 29, 3, 29, 3, 30, 3, 30, 3, 31, 3, 31, 3, 32, 3, 32, 3, 33, 3, 33, 3, 34, 3, 34, 3, 35, 3, 35, 3, 36, 3, 36, 3, 37, 3, 37, 3, 38, 3, 38, 3, 39, 3, 39, 3, 40, 3, 40, 3, 41, 3, 41, 3, 42, 3, 42, 3, 43, 3, 43, 3, 44, 3, 44, 3, 45, 3, 45, 3, 46, 3, 46, 3, 47, 3, 47, 3, 47, 3, 47, 3, 47, 3, 47, 3, 48, 3, 48, 3, 48, 3, 48, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 51, 3, 51, 3, 51, 3, 51, 3, 51, 3, 51, 3, 51, 3, 52, 3, 52, 3, 52, 3, 53, 3, 53, 3, 53, 3, 53, 3, 53, 3, 53, 3, 54, 3, 54, 3, 54, 3, 55, 3, 55, 3, 55, 3, 55, 3, 55, 3, 55, 3, 55, 3, 56, 3, 56, 3, 56, 3, 56, 3, 57, 3, 57, 3, 57, 3, 57, 3, 57, 3, 57, 3, 57, 3, 58, 3, 58, 3, 58, 3, 58, 3, 58, 3, 58, 3, 58, 3, 59, 3, 59, 3, 59, 3, 59, 3, 59, 3, 59, 3, 59, 3, 60, 3, 60, 3, 60, 3, 60, 3, 60, 3, 61, 3, 61, 3, 61, 3, 61, 3, 61, 3, 61, 3, 62, 3, 62, 3, 62, 3, 62, 3, 62, 3, 63, 3, 63, 3, 63, 3, 63, 3, 63, 3, 63, 3, 63, 3, 64, 3, 64, 3, 64, 3, 64, 3, 64, 3, 64, 3, 64, 3, 64, 3, 64, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 66, 3, 66, 3, 66, 3, 67, 3, 67, 3, 67, 3, 67, 3, 67, 3, 68, 3, 68, 3, 68, 3, 68, 3, 68, 3, 68, 3, 69, 3, 69, 3, 69, 3, 69, 3, 69, 3, 69, 3, 69, 3, 69, 3, 69, 3, 69, 3, 70, 3, 70, 3, 70, 3, 70, 3, 71, 3, 71, 3, 71, 3, 71, 3, 71, 3, 71, 3, 71, 3, 71, 3, 71, 3, 71, 3, 71, 3, 72, 3, 72, 3, 72, 3, 72, 3, 72, 3, 73, 3, 73, 3, 73, 3, 73, 3, 73, 3, 73, 3, 74, 3, 74, 3, 74, 3, 75, 3, 75, 3, 75, 3, 75, 3, 76, 3, 76, 3, 76, 3, 76, 3, 77, 3, 77, 3, 77, 3, 77, 3, 78, 3, 78, 3, 78, 3, 79, 3, 79, 3, 79, 3, 79, 3, 79, 3, 79, 3, 79, 3, 80, 3, 80, 3, 80, 3, 80, 3, 80, 3, 81, 3, 81, 3, 81, 3, 81, 3, 81, 3, 81, 3, 81, 3, 81, 3, 81, 3, 82, 3, 82, 3, 82, 3, 83, 3, 83, 3, 83, 3, 83, 3, 83, 3, 84, 3, 84, 3, 84, 3, 84, 3, 84, 3, 84, 3, 85, 3, 85, 3, 85, 3, 85, 3, 86, 3, 86, 3, 86, 3, 86, 3, 86, 3, 87, 3, 87, 3, 87, 3, 87, 3, 87, 3, 87, 3, 87, 3, 88, 3, 88, 3, 88, 3, 88, 3, 88, 3, 89, 3, 89, 3, 89, 3, 89, 3, 89, 3, 89, 3, 90, 3, 90, 3, 90, 3, 90, 3, 90, 3, 90, 3, 90, 3, 91, 3, 91, 3, 91, 3, 91, 3, 91, 3, 92, 3, 92, 3, 92, 3, 92, 3, 92, 3, 93, 3, 93, 3, 93, 3, 93, 3, 94, 3, 94, 3, 94, 3, 94, 3, 94, 3, 95, 3, 95, 3, 95, 3, 95, 3, 95, 3, 96, 3, 96, 3, 96, 7, 96, 671, 10, 96, 12, 96, 14, 96, 674, 11, 96, 3, 96, 3, 96, 3, 96, 3, 96, 7, 96, 680, 10, 96, 12, 96, 14, 96, 683, 11, 96, 3, 96, 5, 96, 686, 10, 96, 3, 97, 3, 97, 3, 97, 3, 97, 3, 97, 3, 97, 3, 97, 3, 97, 3, 97, 3, 97, 3, 97, 3, 97, 3, 97, 3, 97, 3, 97, 3, 97, 3, 97, 3, 97, 5, 97, 706, 10, 97, 3, 98, 3, 98, 3, 98, 3, 98, 6, 98, 712, 10, 98, 13, 98, 14, 98, 713, 3, 99, 3, 99, 3, 99, 7, 99, 719, 10, 99, 12, 99, 14, 99, 722, 11, 99, 5, 99, 724, 10, 99, 3, 100, 3, 100, 6, 100, 728, 10, 100, 13, 100, 14, 100, 729, 3, 101, 5, 101, 733, 10, 101, 3, 102, 3, 102, 5, 102, 737, 10, 102, 3, 103, 3, 103, 5, 103, 741, 10, 103, 3, 104, 3, 104, 5, 104, 745, 10, 104, 3, 105, 3, 105, 3, 106, 3, 106, 5, 106, 751, 10, 106, 3, 107, 3, 107, 3, 108, 6, 108, 756, 10, 108, 13, 108, 14, 108, 757, 3, 108, 6, 108, 761, 10, 108, 13, 108, 14, 108, 762, 3, 108, 3, 108, 6, 108, 767, 10, 108, 13, 108, 14, 108, 768, 3, 108, 3, 108, 6, 108, 773, 10, 108, 13, 108, 14, 108, 774, 5, 108, 777, 10, 108, 3, 108, 3, 108, 5, 108, 781, 10, 108, 3, 108, 6, 108, 784, 10, 108, 13, 108, 14, 108, 785, 3, 109, 7, 109, 789, 10, 109, 12, 109, 14, 109, 792, 11, 109, 3, 109, 3, 109, 6, 109, 796, 10, 109, 13, 109, 14, 109, 797, 3, 110, 3, 110, 3, 110, 3, 110, 3, 110, 3, 110, 3, 110, 3, 110, 3, 110, 3, 110, 3, 110, 3, 111, 3, 111, 3, 111, 3, 112, 3, 112, 3, 112, 3, 112, 3, 113, 3, 113, 3, 113, 3, 113, 3, 113, 3, 113, 3, 113, 3, 113, 3, 114, 3, 114, 3, 114, 3, 114, 3, 114, 3, 114, 3, 114, 3, 115, 3, 115, 3, 115, 3, 115, 3, 115, 3, 115, 3, 115, 3, 115, 3, 115, 3, 115, 3, 116, 3, 116, 3, 116, 3, 116, 3, 116, 3, 116, 3, 116, 3, 117, 3, 117, 3, 117, 3, 118, 3, 118, 3, 118, 3, 118, 3, 119, 3, 119, 3, 119, 3, 119, 3, 119, 3, 120, 3, 120, 3, 120, 3, 120, 3, 120, 3, 120, 3, 120, 3, 121, 3, 121, 3, 121, 3, 121, 3, 121, 3, 121, 3, 121, 3, 121, 3, 122, 3, 122, 7, 122, 879, 10, 122, 12, 122, 14, 122, 882, 11, 122, 3, 123, 3, 123, 5, 123, 886, 10, 123, 3, 124, 3, 124, 5, 124, 890, 10, 124, 3, 125, 3, 125, 7, 125, 894, 10, 125, 12, 125, 14, 125, 897, 11, 125, 3, 125, 6, 125, 900, 10, 125, 13, 125, 14, 125, 901, 3, 126, 6, 126, 905, 10, 126, 13, 126, 14, 126, 906, 3, 127, 3, 127, 3, 127, 3, 127, 3, 127, 3, 127, 3, 127, 3, 127, 3, 127, 3, 127, 3, 127, 3, 127, 5, 127, 921, 10, 127, 3, 128, 3, 128, 3, 128, 3, 128, 3, 128, 3, 128, 7, 128, 929, 10, 128, 12, 128, 14, 128, 932, 11, 128, 3, 128, 3, 128, 3, 128, 3, 128, 3, 128, 3, 128, 7, 128, 940, 10, 128, 12, 128, 14, 128, 943, 11, 128, 3, 128, 5, 128, 946, 10, 128, 3, 128, 3, 128, 5, 128, 950, 10, 128, 5, 128, 952, 10, 128, 3, 129, 3, 129, 3, 130, 3, 130, 3, 131, 3, 131, 3, 132, 3, 132, 3, 133, 3, 133, 3, 134, 3, 134, 3, 135, 3, 135, 3, 136, 3, 136, 3, 137, 3, 137, 3, 138, 3, 138, 3, 139, 3, 139, 3, 140, 3, 140, 3, 141, 3, 141, 3, 142, 3, 142, 3, 143, 3, 143, 3, 144, 3, 144, 3, 145, 3, 145, 3, 146, 3, 146, 3, 147, 3, 147, 3, 148, 3, 148, 2, 2, 149, 3, 3, 5, 4, 7, 5, 9, 6, 11, 7, 13, 8, 15, 9, 17, 10, 19, 11, 21, 12, 23, 13, 25, 14, 27, 15, 29, 16, 31, 17, 33, 18, 35, 19, 37, 20, 39, 21, 41, 22, 43, 23, 45, 24, 47, 25, 49, 26, 51, 27, 53, 28, 55, 29, 57, 30, 59, 31, 61, 32, 63, 33, 65, 34, 67, 35, 69, 36, 71, 37, 73, 38, 75, 39, 77, 40, 79, 41, 81, 42, 83, 43, 85, 44, 87, 45, 89, 46, 91, 47, 93, 48, 95, 49, 97, 50, 99, 51, 101, 52, 103, 53, 105, 54, 107, 55, 109, 56, 111, 57, 113, 58, 115, 59, 117, 60, 119, 61, 121, 62, 123, 63, 125, 64, 127, 65, 129, 66, 131, 67, 133, 68, 135, 69, 137, 70, 139, 71, 141, 72, 143, 73, 145, 74, 147, 75, 149, 76, 151, 77, 153, 78, 155, 79, 157, 80, 159, 81, 161, 82, 163, 83, 165, 84, 167, 85, 169, 86, 171, 87, 173, 88, 175, 89, 177, 90, 179, 91, 181, 92, 183, 93, 185, 94, 187, 95, 189, 96, 191, 97, 193, 98, 195, 99, 197, 100, 199, 101, 201, 102, 203, 103, 205, 104, 207, 105, 209, 106, 211, 107, 213, 108, 215, 109, 217, 110, 219, 111, 221, 112, 223, 113, 225, 114, 227, 115, 229, 116, 231, 117, 233, 118, 235, 119, 237, 120, 239, 121, 241, 122, 243, 123, 245, 124, 247, 125, 249, 126, 251, 127, 253, 128, 255, 129, 257, 2, 259, 2, 261, 2, 263, 2, 265, 2, 267, 2, 269, 2, 271, 2, 273, 2, 275, 2, 277, 2, 279, 2, 281, 2, 283, 2, 285, 2, 287, 2, 289, 2, 291, 2, 293, 2, 295, 2, 3, 2, 47, 4, 2, 87, 87, 119, 119, 4, 2, 80, 80, 112, 112, 4, 2, 75, 75, 107, 107, 4, 2, 81, 81, 113, 113, 4, 2, 67, 67, 99, 99, 4, 2, 78, 78, 110, 110, 4, 2, 82, 82, 114, 114, 4, 2, 86, 86, 118, 118, 4, 2, 79, 79, 111, 111, 4, 2, 69, 69, 101, 101, 4, 2, 74, 74, 106, 106, 4, 2, 89, 89, 121, 121, 4, 2, 70, 70, 102, 102, 4, 2, 85, 85, 117, 117, 4, 2, 71, 71, 103, 103, 4, 2, 84, 84, 116, 116, 4, 2, 73, 73, 105, 105, 4, 2, 88, 88, 120, 120, 4, 2, 91, 91, 123, 123, 4, 2, 68, 68, 100, 100, 4, 2, 77, 77, 109, 109, 4, 2, 90, 90, 122, 122, 4, 2, 72, 72, 104, 104, 15, 2, 36, 36, 41, 41, 68, 68, 72, 72, 80, 80, 84, 84, 86, 86, 94, 94, 100, 100, 104, 104, 112, 112, 116, 116, 118, 118, 4, 2, 67, 72, 99, 104, 4, 2, 83, 83, 115, 115, 10, 2, 162, 162, 5762, 5762, 6160, 6160, 8194, 8204, 8234, 8235, 8241, 8241, 8289, 8289, 12290, 12290, 3, 2, 14, 14, 3, 2, 98, 98, 3, 2, 32, 32, 3, 2, 44, 44, 4, 2, 41, 41, 94, 94, 4, 2, 12, 12, 15, 15, 3, 2, 49, 49, 3, 2, 31, 31, 3, 2, 30, 30, 3, 2, 15, 15, 19, 2, 38, 38, 164, 167, 1425, 1425, 1549, 1549, 2548, 2549, 2557, 2557, 2803, 2803, 3067, 3067, 3649, 3649, 6109, 6109, 8354, 8385, 43066, 43066, 65022, 65022, 65131, 65131, 65286, 65286, 65506, 65507, 65511, 65512, 3, 2, 34, 34, 8, 2, 97, 97, 8257, 8258, 8278, 8278, 65077, 65078, 65103, 65105, 65345, 65345, 3, 2, 11, 11, 4, 2, 36, 36, 94, 94, 3, 2, 12, 12, 3, 2, 13, 13, 3, 2, 33, 33, 4, 691, 2, 50, 2, 59, 2, 67, 2, 92, 2, 97, 2, 97, 2, 99, 2, 124, 2, 172, 2, 172, 2, 183, 2, 183, 2, 185, 2, 185, 2, 188, 2, 188, 2, 194, 2, 216, 2, 218, 2, 248, 2, 250, 2, 707, 2, 712, 2, 723, 2, 738, 2, 742, 2, 750, 2, 750, 2, 752, 2, 752, 2, 770, 2, 886, 2, 888, 2, 889, 2, 892, 2, 895, 2, 897, 2, 897, 2, 904, 2, 908, 2, 910, 2, 910, 2, 912, 2, 931, 2, 933, 2, 1015, 2, 1017, 2, 1155, 2, 1157, 2, 1161, 2, 1164, 2, 1329, 2, 1331, 2, 1368, 2, 1371, 2, 1371, 2, 1379, 2, 1417, 2, 1427, 2, 1471, 2, 1473, 2, 1473, 2, 1475, 2, 1476, 2, 1478, 2, 1479, 2, 1481, 2, 1481, 2, 1490, 2, 1516, 2, 1522, 2, 1524, 2, 1554, 2, 1564, 2, 1570, 2, 1643, 2, 1648, 2, 1749, 2, 1751, 2, 1758, 2, 1761, 2, 1770, 2, 1772, 2, 1790, 2, 1793, 2, 1793, 2, 1810, 2, 1868, 2, 1871, 2, 1971, 2, 1986, 2, 2039, 2, 2044, 2, 2044, 2, 2050, 2, 2095, 2, 2114, 2, 2141, 2, 2146, 2, 2156, 2, 2210, 2, 2230, 2, 2232, 2, 2239, 2, 2262, 2, 2275, 2, 2277, 2, 2405, 2, 2408, 2, 2417, 2, 2419, 2, 2437, 2, 2439, 2, 2446, 2, 2449, 2, 2450, 2, 2453, 2, 2474, 2, 2476, 2, 2482, 2, 2484, 2, 2484, 2, 2488, 2, 2491, 2, 2494, 2, 2502, 2, 2505, 2, 2506, 2, 2509, 2, 2512, 2, 2521, 2, 2521, 2, 2526, 2, 2527, 2, 2529, 2, 2533, 2, 2536, 2, 2547, 2, 2558, 2, 2558, 2, 2563, 2, 2565, 2, 2567, 2, 2572, 2, 2577, 2, 2578, 2, 2581, 2, 2602, 2, 2604, 2, 2610, 2, 2612, 2, 2613, 2, 2615, 2, 2616, 2, 2618, 2, 2619, 2, 2622, 2, 2622, 2, 2624, 2, 2628, 2, 2633, 2, 2634, 2, 2637, 2, 2639, 2, 2643, 2, 2643, 2, 2651, 2, 2654, 2, 2656, 2, 2656, 2, 2664, 2, 2679, 2, 2691, 2, 2693, 2, 2695, 2, 2703, 2, 2705, 2, 2707, 2, 2709, 2, 2730, 2, 2732, 2, 2738, 2, 2740, 2, 2741, 2, 2743, 2, 2747, 2, 2750, 2, 2759, 2, 2761, 2, 2763, 2, 2765, 2, 2767, 2, 2770, 2, 2770, 2, 2786, 2, 2789, 2, 2792, 2, 2801, 2, 2811, 2, 2817, 2, 2819, 2, 2821, 2, 2823, 2, 2830, 2, 2833, 2, 2834, 2, 2837, 2, 2858, 2, 2860, 2, 2866, 2, 2868, 2, 2869, 2, 2871, 2, 2875, 2, 2878, 2, 2886, 2, 2889, 2, 2890, 2, 2893, 2, 2895, 2, 2904, 2, 2905, 2, 2910, 2, 2911, 2, 2913, 2, 2917, 2, 2920, 2, 2929, 2, 2931, 2, 2931, 2, 2948, 2, 2949, 2, 2951, 2, 2956, 2, 2960, 2, 2962, 2, 2964, 2, 2967, 2, 2971, 2, 2972, 2, 2974, 2, 2974, 2, 2976, 2, 2977, 2, 2981, 2, 2982, 2, 2986, 2, 2988, 2, 2992, 2, 3003, 2, 3008, 2, 3012, 2, 3016, 2, 3018, 2, 3020, 2, 3023, 2, 3026, 2, 3026, 2, 3033, 2, 3033, 2, 3048, 2, 3057, 2, 3074, 2, 3077, 2, 3079, 2, 3086, 2, 3088, 2, 3090, 2, 3092, 2, 3114, 2, 3116, 2, 3131, 2, 3135, 2, 3142, 2, 3144, 2, 3146, 2, 3148, 2, 3151, 2, 3159, 2, 3160, 2, 3162, 2, 3164, 2, 3170, 2, 3173, 2, 3176, 2, 3185, 2, 3202, 2, 3205, 2, 3207, 2, 3214, 2, 3216, 2, 3218, 2, 3220, 2, 3242, 2, 3244, 2, 3253, 2, 3255, 2, 3259, 2, 3262, 2, 3270, 2, 3272, 2, 3274, 2, 3276, 2, 3279, 2, 3287, 2, 3288, 2, 3296, 2, 3296, 2, 3298, 2, 3301, 2, 3304, 2, 3313, 2, 3315, 2, 3316, 2, 3330, 2, 3333, 2, 3335, 2, 3342, 2, 3344, 2, 3346, 2, 3348, 2, 3398, 2, 3400, 2, 3402, 2, 3404, 2, 3408, 2, 3414, 2, 3417, 2, 3425, 2, 3429, 2, 3432, 2, 3441, 2, 3452, 2, 3457, 2, 3460, 2, 3461, 2, 3463, 2, 3480, 2, 3484, 2, 3507, 2, 3509, 2, 3517, 2, 3519, 2, 3519, 2, 3522, 2, 3528, 2, 3532, 2, 3532, 2, 3537, 2, 3542, 2, 3544, 2, 3544, 2, 3546, 2, 3553, 2, 3560, 2, 3569, 2, 3572, 2, 3573, 2, 3587, 2, 3644, 2, 3650, 2, 3664, 2, 3666, 2, 3675, 2, 3715, 2, 3716, 2, 3718, 2, 3718, 2, 3721, 2, 3722, 2, 3724, 2, 3724, 2, 3727, 2, 3727, 2, 3734, 2, 3737, 2, 3739, 2, 3745, 2, 3747, 2, 3749, 2, 3751, 2, 3751, 2, 3753, 2, 3753, 2, 3756, 2, 3757, 2, 3759, 2, 3771, 2, 3773, 2, 3775, 2, 3778, 2, 3782, 2, 3784, 2, 3784, 2, 3786, 2, 3791, 2, 3794, 2, 3803, 2, 3806, 2, 3809, 2, 3842, 2, 3842, 2, 3866, 2, 3867, 2, 3874, 2, 3883, 2, 3895, 2, 3895, 2, 3897, 2, 3897, 2, 3899, 2, 3899, 2, 3904, 2, 3913, 2, 3915, 2, 3950, 2, 3955, 2, 3974, 2, 3976, 2, 3993, 2, 3995, 2, 4030, 2, 4040, 2, 4040, 2, 4098, 2, 4171, 2, 4178, 2, 4255, 2, 4258, 2, 4295, 2, 4297, 2, 4297, 2, 4303, 2, 4303, 2, 4306, 2, 4348, 2, 4350, 2, 4682, 2, 4684, 2, 4687, 2, 4690, 2, 4696, 2, 4698, 2, 4698, 2, 4700, 2, 4703, 2, 4706, 2, 4746, 2, 4748, 2, 4751, 2, 4754, 2, 4786, 2, 4788, 2, 4791, 2, 4794, 2, 4800, 2, 4802, 2, 4802, 2, 4804, 2, 4807, 2, 4810, 2, 4824, 2, 4826, 2, 4882, 2, 4884, 2, 4887, 2, 4890, 2, 4956, 2, 4959, 2, 4961, 2, 4971, 2, 4979, 2, 4994, 2, 5009, 2, 5026, 2, 5111, 2, 5114, 2, 5119, 2, 5123, 2, 5742, 2, 5745, 2, 5761, 2, 5763, 2, 5788, 2, 5794, 2, 5868, 2, 5872, 2, 5882, 2, 5890, 2, 5902, 2, 5904, 2, 5910, 2, 5922, 2, 5942, 2, 5954, 2, 5973, 2, 5986, 2, 5998, 2, 6000, 2, 6002, 2, 6004, 2, 6005, 2, 6018, 2, 6101, 2, 6105, 2, 6105, 2, 6110, 2, 6111, 2, 6114, 2, 6123, 2, 6157, 2, 6159, 2, 6162, 2, 6171, 2, 6178, 2, 6265, 2, 6274, 2, 6316, 2, 6322, 2, 6391, 2, 6402, 2, 6432, 2, 6434, 2, 6445, 2, 6450, 2, 6461, 2, 6472, 2, 6511, 2, 6514, 2, 6518, 2, 6530, 2, 6573, 2, 6578, 2, 6603, 2, 6610, 2, 6620, 2, 6658, 2, 6685, 2, 6690, 2, 6752, 2, 6754, 2, 6782, 2, 6785, 2, 6795, 2, 6802, 2, 6811, 2, 6825, 2, 6825, 2, 6834, 2, 6847, 2, 6914, 2, 6989, 2, 6994, 2, 7003, 2, 7021, 2, 7029, 2, 7042, 2, 7157, 2, 7170, 2, 7225, 2, 7234, 2, 7243, 2, 7247, 2, 7295, 2, 7298, 2, 7306, 2, 7378, 2, 7380, 2, 7382, 2, 7419, 2, 7426, 2, 7675, 2, 7677, 2, 7959, 2, 7962, 2, 7967, 2, 7970, 2, 8007, 2, 8010, 2, 8015, 2, 8018, 2, 8025, 2, 8027, 2, 8027, 2, 8029, 2, 8029, 2, 8031, 2, 8031, 2, 8033, 2, 8063, 2, 8066, 2, 8118, 2, 8120, 2, 8126, 2, 8128, 2, 8128, 2, 8132, 2, 8134, 2, 8136, 2, 8142, 2, 8146, 2, 8149, 2, 8152, 2, 8157, 2, 8162, 2, 8174, 2, 8180, 2, 8182, 2, 8184, 2, 8190, 2, 8257, 2, 8258, 2, 8278, 2, 8278, 2, 8307, 2, 8307, 2, 8321, 2, 8321, 2, 8338, 2, 8350, 2, 8402, 2, 8414, 2, 8419, 2, 8419, 2, 8423, 2, 8434, 2, 8452, 2, 8452, 2, 8457, 2, 8457, 2, 8460, 2, 8469, 2, 8471, 2, 8471, 2, 8474, 2, 8479, 2, 8486, 2, 8486, 2, 8488, 2, 8488, 2, 8490, 2, 8490, 2, 8492, 2, 8507, 2, 8510, 2, 8513, 2, 8519, 2, 8523, 2, 8528, 2, 8528, 2, 8546, 2, 8586, 2, 11266, 2, 11312, 2, 11314, 2, 11360, 2, 11362, 2, 11494, 2, 11501, 2, 11509, 2, 11522, 2, 11559, 2, 11561, 2, 11561, 2, 11567, 2, 11567, 2, 11570, 2, 11625, 2, 11633, 2, 11633, 2, 11649, 2, 11672, 2, 11682, 2, 11688, 2, 11690, 2, 11696, 2, 11698, 2, 11704, 2, 11706, 2, 11712, 2, 11714, 2, 11720, 2, 11722, 2, 11728, 2, 11730, 2, 11736, 2, 11738, 2, 11744, 2, 11746, 2, 11777, 2, 12295, 2, 12297, 2, 12323, 2, 12337, 2, 12339, 2, 12343, 2, 12346, 2, 12350, 2, 12355, 2, 12440, 2, 12443, 2, 12449, 2, 12451, 2, 12540, 2, 12542, 2, 12545, 2, 12551, 2, 12592, 2, 12595, 2, 12688, 2, 12706, 2, 12732, 2, 12786, 2, 12801, 2, 13314, 2, 19895, 2, 19970, 2, 40940, 2, 40962, 2, 42126, 2, 42194, 2, 42239, 2, 42242, 2, 42510, 2, 42514, 2, 42541, 2, 42562, 2, 42609, 2, 42614, 2, 42623, 2, 42625, 2, 42739, 2, 42777, 2, 42785, 2, 42788, 2, 42890, 2, 42893, 2, 42928, 2, 42930, 2, 42937, 2, 43001, 2, 43049, 2, 43074, 2, 43125, 2, 43138, 2, 43207, 2, 43218, 2, 43227, 2, 43234, 2, 43257, 2, 43261, 2, 43261, 2, 43263, 2, 43263, 2, 43266, 2, 43311, 2, 43314, 2, 43349, 2, 43362, 2, 43390, 2, 43394, 2, 43458, 2, 43473, 2, 43483, 2, 43490, 2, 43520, 2, 43522, 2, 43576, 2, 43586, 2, 43599, 2, 43602, 2, 43611, 2, 43618, 2, 43640, 2, 43644, 2, 43716, 2, 43741, 2, 43743, 2, 43746, 2, 43761, 2, 43764, 2, 43768, 2, 43779, 2, 43784, 2, 43787, 2, 43792, 2, 43795, 2, 43800, 2, 43810, 2, 43816, 2, 43818, 2, 43824, 2, 43826, 2, 43868, 2, 43870, 2, 43879, 2, 43890, 2, 44012, 2, 44014, 2, 44015, 2, 44018, 2, 44027, 2, 44034, 2, 55205, 2, 55218, 2, 55240, 2, 55245, 2, 55293, 2, 63746, 2, 64111, 2, 64114, 2, 64219, 2, 64258, 2, 64264, 2, 64277, 2, 64281, 2, 64287, 2, 64298, 2, 64300, 2, 64312, 2, 64314, 2, 64318, 2, 64320, 2, 64320, 2, 64322, 2, 64323, 2, 64325, 2, 64326, 2, 64328, 2, 64435, 2, 64469, 2, 64831, 2, 64850, 2, 64913, 2, 64916, 2, 64969, 2, 65010, 2, 65021, 2, 65026, 2, 65041, 2, 65058, 2, 65073, 2, 65077, 2, 65078, 2, 65103, 2, 65105, 2, 65138, 2, 65142, 2, 65144, 2, 65278, 2, 65298, 2, 65307, 2, 65315, 2, 65340, 2, 65345, 2, 65345, 2, 65347, 2, 65372, 2, 65384, 2, 65472, 2, 65476, 2, 65481, 2, 65484, 2, 65489, 2, 65492, 2, 65497, 2, 65500, 2, 65502, 2, 2, 3, 13, 3, 15, 3, 40, 3, 42, 3, 60, 3, 62, 3, 63, 3, 65, 3, 79, 3, 82, 3, 95, 3, 130, 3, 252, 3, 322, 3, 374, 3, 511, 3, 511, 3, 642, 3, 670, 3, 674, 3, 722, 3, 738, 3, 738, 3, 770, 3, 801, 3, 815, 3, 844, 3, 850, 3, 892, 3, 898, 3, 927, 3, 930, 3, 965, 3, 970, 3, 977, 3, 979, 3, 983, 3, 1026, 3, 1183, 3, 1186, 3, 1195, 3, 1202, 3, 1237, 3, 1242, 3, 1277, 3, 1282, 3, 1321, 3, 1330, 3, 1381, 3, 1538, 3, 1848, 3, 1858, 3, 1879, 3, 1890, 3, 1897, 3, 2050, 3, 2055, 3, 2058, 3, 2058, 3, 2060, 3, 2103, 3, 2105, 3, 2106, 3, 2110, 3, 2110, 3, 2113, 3, 2135, 3, 2146, 3, 2168, 3, 2178, 3, 2208, 3, 2274, 3, 2292, 3, 2294, 3, 2295, 3, 2306, 3, 2327, 3, 2338, 3, 2363, 3, 2434, 3, 2489, 3, 2496, 3, 2497, 3, 2562, 3, 2565, 3, 2567, 3, 2568, 3, 2574, 3, 2581, 3, 2583, 3, 2585, 3, 2587, 3, 2613, 3, 2618, 3, 2620, 3, 2625, 3, 2625, 3, 2658, 3, 2686, 3, 2690, 3, 2718, 3, 2754, 3, 2761, 3, 2763, 3, 2792, 3, 2818, 3, 2871, 3, 2882, 3, 2903, 3, 2914, 3, 2932, 3, 2946, 3, 2963, 3, 3074, 3, 3146, 3, 3202, 3, 3252, 3, 3266, 3, 3316, 3, 4098, 3, 4168, 3, 4200, 3, 4209, 3, 4225, 3, 4284, 3, 4306, 3, 4330, 3, 4338, 3, 4347, 3, 4354, 3, 4406, 3, 4408, 3, 4417, 3, 4434, 3, 4469, 3, 4472, 3, 4472, 3, 4482, 3, 4550, 3, 4556, 3, 4558, 3, 4562, 3, 4572, 3, 4574, 3, 4574, 3, 4610, 3, 4627, 3, 4629, 3, 4665, 3, 4672, 3, 4672, 3, 4738, 3, 4744, 3, 4746, 3, 4746, 3, 4748, 3, 4751, 3, 4753, 3, 4767, 3, 4769, 3, 4778, 3, 4786, 3, 4844, 3, 4850, 3, 4859, 3, 4866, 3, 4869, 3, 4871, 3, 4878, 3, 4881, 3, 4882, 3, 4885, 3, 4906, 3, 4908, 3, 4914, 3, 4916, 3, 4917, 3, 4919, 3, 4923, 3, 4926, 3, 4934, 3, 4937, 3, 4938, 3, 4941, 3, 4943, 3, 4946, 3, 4946, 3, 4953, 3, 4953, 3, 4959, 3, 4965, 3, 4968, 3, 4974, 3, 4978, 3, 4982, 3, 5122, 3, 5196, 3, 5202, 3, 5211, 3, 5250, 3, 5319, 3, 5321, 3, 5321, 3, 5330, 3, 5339, 3, 5506, 3, 5559, 3, 5562, 3, 5570, 3, 5594, 3, 5599, 3, 5634, 3, 5698, 3, 5702, 3, 5702, 3, 5714, 3, 5723, 3, 5762, 3, 5817, 3, 5826, 3, 5835, 3, 5890, 3, 5915, 3, 5919, 3, 5933, 3, 5938, 3, 5947, 3, 6306, 3, 6379, 3, 6401, 3, 6401, 3, 6658, 3, 6720, 3, 6729, 3, 6729, 3, 6738, 3, 6789, 3, 6792, 3, 6811, 3, 6850, 3, 6906, 3, 7170, 3, 7178, 3, 7180, 3, 7224, 3, 7226, 3, 7234, 3, 7250, 3, 7259, 3, 7284, 3, 7313, 3, 7316, 3, 7337, 3, 7339, 3, 7352, 3, 7426, 3, 7432, 3, 7434, 3, 7435, 3, 7437, 3, 7480, 3, 7484, 3, 7484, 3, 7486, 3, 7487, 3, 7489, 3, 7497, 3, 7506, 3, 7515, 3, 8194, 3, 9115, 3, 9218, 3, 9328, 3, 9346, 3, 9541, 3, 12290, 3, 13360, 3, 17410, 3, 17992, 3, 26626, 3, 27194, 3, 27202, 3, 27232, 3, 27234, 3, 27243, 3, 27346, 3, 27375, 3, 27378, 3, 27382, 3, 27394, 3, 27448, 3, 27458, 3, 27461, 3, 27474, 3, 27483, 3, 27493, 3, 27513, 3, 27519, 3, 27537, 3, 28418, 3, 28486, 3, 28498, 3, 28544, 3, 28561, 3, 28577, 3, 28642, 3, 28643, 3, 28674, 3, 34798, 3, 34818, 3, 35572, 3, 45058, 3, 45344, 3, 45426, 3, 45821, 3, 48130, 3, 48236, 3, 48242, 3, 48254, 3, 48258, 3, 48266, 3, 48274, 3, 48283, 3, 48287, 3, 48288, 3, 53607, 3, 53611, 3, 53615, 3, 53620, 3, 53629, 3, 53636, 3, 53639, 3, 53645, 3, 53676, 3, 53679, 3, 53828, 3, 53830, 3, 54274, 3, 54358, 3, 54360, 3, 54430, 3, 54432, 3, 54433, 3, 54436, 3, 54436, 3, 54439, 3, 54440, 3, 54443, 3, 54446, 3, 54448, 3, 54459, 3, 54461, 3, 54461, 3, 54463, 3, 54469, 3, 54471, 3, 54535, 3, 54537, 3, 54540, 3, 54543, 3, 54550, 3, 54552, 3, 54558, 3, 54560, 3, 54587, 3, 54589, 3, 54592, 3, 54594, 3, 54598, 3, 54600, 3, 54600, 3, 54604, 3, 54610, 3, 54612, 3, 54951, 3, 54954, 3, 54978, 3, 54980, 3, 55004, 3, 55006, 3, 55036, 3, 55038, 3, 55062, 3, 55064, 3, 55094, 3, 55096, 3, 55120, 3, 55122, 3, 55152, 3, 55154, 3, 55178, 3, 55180, 3, 55210, 3, 55212, 3, 55236, 3, 55238, 3, 55245, 3, 55248, 3, 55297, 3, 55810, 3, 55864, 3, 55869, 3, 55918, 3, 55927, 3, 55927, 3, 55942, 3, 55942, 3, 55965, 3, 55969, 3, 55971, 3, 55985, 3, 57346, 3, 57352, 3, 57354, 3, 57370, 3, 57373, 3, 57379, 3, 57381, 3, 57382, 3, 57384, 3, 57388, 3, 59394, 3, 59590, 3, 59602, 3, 59608, 3, 59650, 3, 59724, 3, 59730, 3, 59739, 3, 60930, 3, 60933, 3, 60935, 3, 60961, 3, 60963, 3, 60964, 3, 60966, 3, 60966, 3, 60969, 3, 60969, 3, 60971, 3, 60980, 3, 60982, 3, 60985, 3, 60987, 3, 60987, 3, 60989, 3, 60989, 3, 60996, 3, 60996, 3, 61001, 3, 61001, 3, 61003, 3, 61003, 3, 61005, 3, 61005, 3, 61007, 3, 61009, 3, 61011, 3, 61012, 3, 61014, 3, 61014, 3, 61017, 3, 61017, 3, 61019, 3, 61019, 3, 61021, 3, 61021, 3, 61023, 3, 61023, 3, 61025, 3, 61025, 3, 61027, 3, 61028, 3, 61030, 3, 61030, 3, 61033, 3, 61036, 3, 61038, 3, 61044, 3, 61046, 3, 61049, 3, 61051, 3, 61054, 3, 61056, 3, 61056, 3, 61058, 3, 61067, 3, 61069, 3, 61085, 3, 61091, 3, 61093, 3, 61095, 3, 61099, 3, 61101, 3, 61117, 3, 2, 4, 42712, 4, 42754, 4, 46902, 4, 46914, 4, 47135, 4, 47138, 4, 52899, 4, 52914, 4, 60386, 4, 63490, 4, 64031, 4, 258, 16, 497, 16, 587, 2, 67, 2, 92, 2, 99, 2, 124, 2, 172, 2, 172, 2, 183, 2, 183, 2, 188, 2, 188, 2, 194, 2, 216, 2, 218, 2, 248, 2, 250, 2, 707, 2, 712, 2, 723, 2, 738, 2, 742, 2, 750, 2, 750, 2, 752, 2, 752, 2, 882, 2, 886, 2, 888, 2, 889, 2, 892, 2, 895, 2, 897, 2, 897, 2, 904, 2, 904, 2, 906, 2, 908, 2, 910, 2, 910, 2, 912, 2, 931, 2, 933, 2, 1015, 2, 1017, 2, 1155, 2, 1164, 2, 1329, 2, 1331, 2, 1368, 2, 1371, 2, 1371, 2, 1379, 2, 1417, 2, 1490, 2, 1516, 2, 1522, 2, 1524, 2, 1570, 2, 1612, 2, 1648, 2, 1649, 2, 1651, 2, 1749, 2, 1751, 2, 1751, 2, 1767, 2, 1768, 2, 1776, 2, 1777, 2, 1788, 2, 1790, 2, 1793, 2, 1793, 2, 1810, 2, 1810, 2, 1812, 2, 1841, 2, 1871, 2, 1959, 2, 1971, 2, 1971, 2, 1996, 2, 2028, 2, 2038, 2, 2039, 2, 2044, 2, 2044, 2, 2050, 2, 2071, 2, 2076, 2, 2076, 2, 2086, 2, 2086, 2, 2090, 2, 2090, 2, 2114, 2, 2138, 2, 2146, 2, 2156, 2, 2210, 2, 2230, 2, 2232, 2, 2239, 2, 2310, 2, 2363, 2, 2367, 2, 2367, 2, 2386, 2, 2386, 2, 2394, 2, 2403, 2, 2419, 2, 2434, 2, 2439, 2, 2446, 2, 2449, 2, 2450, 2, 2453, 2, 2474, 2, 2476, 2, 2482, 2, 2484, 2, 2484, 2, 2488, 2, 2491, 2, 2495, 2, 2495, 2, 2512, 2, 2512, 2, 2526, 2, 2527, 2, 2529, 2, 2531, 2, 2546, 2, 2547, 2, 2558, 2, 2558, 2, 2567, 2, 2572, 2, 2577, 2, 2578, 2, 2581, 2, 2602, 2, 2604, 2, 2610, 2, 2612, 2, 2613, 2, 2615, 2, 2616, 2, 2618, 2, 2619, 2, 2651, 2, 2654, 2, 2656, 2, 2656, 2, 2676, 2, 2678, 2, 2695, 2, 2703, 2, 2705, 2, 2707, 2, 2709, 2, 2730, 2, 2732, 2, 2738, 2, 2740, 2, 2741, 2, 2743, 2, 2747, 2, 2751, 2, 2751, 2, 2770, 2, 2770, 2, 2786, 2, 2787, 2, 2811, 2, 2811, 2, 2823, 2, 2830, 2, 2833, 2, 2834, 2, 2837, 2, 2858, 2, 2860, 2, 2866, 2, 2868, 2, 2869, 2, 2871, 2, 2875, 2, 2879, 2, 2879, 2, 2910, 2, 2911, 2, 2913, 2, 2915, 2, 2931, 2, 2931, 2, 2949, 2, 2949, 2, 2951, 2, 2956, 2, 2960, 2, 2962, 2, 2964, 2, 2967, 2, 2971, 2, 2972, 2, 2974, 2, 2974, 2, 2976, 2, 2977, 2, 2981, 2, 2982, 2, 2986, 2, 2988, 2, 2992, 2, 3003, 2, 3026, 2, 3026, 2, 3079, 2, 3086, 2, 3088, 2, 3090, 2, 3092, 2, 3114, 2, 3116, 2, 3131, 2, 3135, 2, 3135, 2, 3162, 2, 3164, 2, 3170, 2, 3171, 2, 3202, 2, 3202, 2, 3207, 2, 3214, 2, 3216, 2, 3218, 2, 3220, 2, 3242, 2, 3244, 2, 3253, 2, 3255, 2, 3259, 2, 3263, 2, 3263, 2, 3296, 2, 3296, 2, 3298, 2, 3299, 2, 3315, 2, 3316, 2, 3335, 2, 3342, 2, 3344, 2, 3346, 2, 3348, 2, 3388, 2, 3391, 2, 3391, 2, 3408, 2, 3408, 2, 3414, 2, 3416, 2, 3425, 2, 3427, 2, 3452, 2, 3457, 2, 3463, 2, 3480, 2, 3484, 2, 3507, 2, 3509, 2, 3517, 2, 3519, 2, 3519, 2, 3522, 2, 3528, 2, 3587, 2, 3634, 2, 3636, 2, 3637, 2, 3650, 2, 3656, 2, 3715, 2, 3716, 2, 3718, 2, 3718, 2, 3721, 2, 3722, 2, 3724, 2, 3724, 2, 3727, 2, 3727, 2, 3734, 2, 3737, 2, 3739, 2, 3745, 2, 3747, 2, 3749, 2, 3751, 2, 3751, 2, 3753, 2, 3753, 2, 3756, 2, 3757, 2, 3759, 2, 3762, 2, 3764, 2, 3765, 2, 3775, 2, 3775, 2, 3778, 2, 3782, 2, 3784, 2, 3784, 2, 3806, 2, 3809, 2, 3842, 2, 3842, 2, 3906, 2, 3913, 2, 3915, 2, 3950, 2, 3978, 2, 3982, 2, 4098, 2, 4140, 2, 4161, 2, 4161, 2, 4178, 2, 4183, 2, 4188, 2, 4191, 2, 4195, 2, 4195, 2, 4199, 2, 4200, 2, 4208, 2, 4210, 2, 4215, 2, 4227, 2, 4240, 2, 4240, 2, 4258, 2, 4295, 2, 4297, 2, 4297, 2, 4303, 2, 4303, 2, 4306, 2, 4348, 2, 4350, 2, 4682, 2, 4684, 2, 4687, 2, 4690, 2, 4696, 2, 4698, 2, 4698, 2, 4700, 2, 4703, 2, 4706, 2, 4746, 2, 4748, 2, 4751, 2, 4754, 2, 4786, 2, 4788, 2, 4791, 2, 4794, 2, 4800, 2, 4802, 2, 4802, 2, 4804, 2, 4807, 2, 4810, 2, 4824, 2, 4826, 2, 4882, 2, 4884, 2, 4887, 2, 4890, 2, 4956, 2, 4994, 2, 5009, 2, 5026, 2, 5111, 2, 5114, 2, 5119, 2, 5123, 2, 5742, 2, 5745, 2, 5761, 2, 5763, 2, 5788, 2, 5794, 2, 5868, 2, 5872, 2, 5882, 2, 5890, 2, 5902, 2, 5904, 2, 5907, 2, 5922, 2, 5939, 2, 5954, 2, 5971, 2, 5986, 2, 5998, 2, 6000, 2, 6002, 2, 6018, 2, 6069, 2, 6105, 2, 6105, 2, 6110, 2, 6110, 2, 6178, 2, 6265, 2, 6274, 2, 6314, 2, 6316, 2, 6316, 2, 6322, 2, 6391, 2, 6402, 2, 6432, 2, 6482, 2, 6511, 2, 6514, 2, 6518, 2, 6530, 2, 6573, 2, 6578, 2, 6603, 2, 6658, 2, 6680, 2, 6690, 2, 6742, 2, 6825, 2, 6825, 2, 6919, 2, 6965, 2, 6983, 2, 6989, 2, 7045, 2, 7074, 2, 7088, 2, 7089, 2, 7100, 2, 7143, 2, 7170, 2, 7205, 2, 7247, 2, 7249, 2, 7260, 2, 7295, 2, 7298, 2, 7306, 2, 7403, 2, 7406, 2, 7408, 2, 7411, 2, 7415, 2, 7416, 2, 7426, 2, 7617, 2, 7682, 2, 7959, 2, 7962, 2, 7967, 2, 7970, 2, 8007, 2, 8010, 2, 8015, 2, 8018, 2, 8025, 2, 8027, 2, 8027, 2, 8029, 2, 8029, 2, 8031, 2, 8031, 2, 8033, 2, 8063, 2, 8066, 2, 8118, 2, 8120, 2, 8126, 2, 8128, 2, 8128, 2, 8132, 2, 8134, 2, 8136, 2, 8142, 2, 8146, 2, 8149, 2, 8152, 2, 8157, 2, 8162, 2, 8174, 2, 8180, 2, 8182, 2, 8184, 2, 8190, 2, 8307, 2, 8307, 2, 8321, 2, 8321, 2, 8338, 2, 8350, 2, 8452, 2, 8452, 2, 8457, 2, 8457, 2, 8460, 2, 8469, 2, 8471, 2, 8471, 2, 8474, 2, 8479, 2, 8486, 2, 8486, 2, 8488, 2, 8488, 2, 8490, 2, 8490, 2, 8492, 2, 8507, 2, 8510, 2, 8513, 2, 8519, 2, 8523, 2, 8528, 2, 8528, 2, 8546, 2, 8586, 2, 11266, 2, 11312, 2, 11314, 2, 11360, 2, 11362, 2, 11494, 2, 11501, 2, 11504, 2, 11508, 2, 11509, 2, 11522, 2, 11559, 2, 11561, 2, 11561, 2, 11567, 2, 11567, 2, 11570, 2, 11625, 2, 11633, 2, 11633, 2, 11650, 2, 11672, 2, 11682, 2, 11688, 2, 11690, 2, 11696, 2, 11698, 2, 11704, 2, 11706, 2, 11712, 2, 11714, 2, 11720, 2, 11722, 2, 11728, 2, 11730, 2, 11736, 2, 11738, 2, 11744, 2, 12295, 2, 12297, 2, 12323, 2, 12331, 2, 12339, 2, 12343, 2, 12346, 2, 12350, 2, 12355, 2, 12440, 2, 12445, 2, 12449, 2, 12451, 2, 12540, 2, 12542, 2, 12545, 2, 12551, 2, 12592, 2, 12595, 2, 12688, 2, 12706, 2, 12732, 2, 12786, 2, 12801, 2, 13314, 2, 19895, 2, 19970, 2, 40940, 2, 40962, 2, 42126, 2, 42194, 2, 42239, 2, 42242, 2, 42510, 2, 42514, 2, 42529, 2, 42540, 2, 42541, 2, 42562, 2, 42608, 2, 42625, 2, 42655, 2, 42658, 2, 42737, 2, 42777, 2, 42785, 2, 42788, 2, 42890, 2, 42893, 2, 42928, 2, 42930, 2, 42937, 2, 43001, 2, 43011, 2, 43013, 2, 43015, 2, 43017, 2, 43020, 2, 43022, 2, 43044, 2, 43074, 2, 43125, 2, 43140, 2, 43189, 2, 43252, 2, 43257, 2, 43261, 2, 43261, 2, 43263, 2, 43263, 2, 43276, 2, 43303, 2, 43314, 2, 43336, 2, 43362, 2, 43390, 2, 43398, 2, 43444, 2, 43473, 2, 43473, 2, 43490, 2, 43494, 2, 43496, 2, 43505, 2, 43516, 2, 43520, 2, 43522, 2, 43562, 2, 43586, 2, 43588, 2, 43590, 2, 43597, 2, 43618, 2, 43640, 2, 43644, 2, 43644, 2, 43648, 2, 43697, 2, 43699, 2, 43699, 2, 43703, 2, 43704, 2, 43707, 2, 43711, 2, 43714, 2, 43714, 2, 43716, 2, 43716, 2, 43741, 2, 43743, 2, 43746, 2, 43756, 2, 43764, 2, 43766, 2, 43779, 2, 43784, 2, 43787, 2, 43792, 2, 43795, 2, 43800, 2, 43810, 2, 43816, 2, 43818, 2, 43824, 2, 43826, 2, 43868, 2, 43870, 2, 43879, 2, 43890, 2, 44004, 2, 44034, 2, 55205, 2, 55218, 2, 55240, 2, 55245, 2, 55293, 2, 63746, 2, 64111, 2, 64114, 2, 64219, 2, 64258, 2, 64264, 2, 64277, 2, 64281, 2, 64287, 2, 64287, 2, 64289, 2, 64298, 2, 64300, 2, 64312, 2, 64314, 2, 64318, 2, 64320, 2, 64320, 2, 64322, 2, 64323, 2, 64325, 2, 64326, 2, 64328, 2, 64435, 2, 64469, 2, 64831, 2, 64850, 2, 64913, 2, 64916, 2, 64969, 2, 65010, 2, 65021, 2, 65138, 2, 65142, 2, 65144, 2, 65278, 2, 65315, 2, 65340, 2, 65347, 2, 65372, 2, 65384, 2, 65472, 2, 65476, 2, 65481, 2, 65484, 2, 65489, 2, 65492, 2, 65497, 2, 65500, 2, 65502, 2, 2, 3, 13, 3, 15, 3, 40, 3, 42, 3, 60, 3, 62, 3, 63, 3, 65, 3, 79, 3, 82, 3, 95, 3, 130, 3, 252, 3, 322, 3, 374, 3, 642, 3, 670, 3, 674, 3, 722, 3, 770, 3, 801, 3, 815, 3, 844, 3, 850, 3, 887, 3, 898, 3, 927, 3, 930, 3, 965, 3, 970, 3, 977, 3, 979, 3, 983, 3, 1026, 3, 1183, 3, 1202, 3, 1237, 3, 1242, 3, 1277, 3, 1282, 3, 1321, 3, 1330, 3, 1381, 3, 1538, 3, 1848, 3, 1858, 3, 1879, 3, 1890, 3, 1897, 3, 2050, 3, 2055, 3, 2058, 3, 2058, 3, 2060, 3, 2103, 3, 2105, 3, 2106, 3, 2110, 3, 2110, 3, 2113, 3, 2135, 3, 2146, 3, 2168, 3, 2178, 3, 2208, 3, 2274, 3, 2292, 3, 2294, 3, 2295, 3, 2306, 3, 2327, 3, 2338, 3, 2363, 3, 2434, 3, 2489, 3, 2496, 3, 2497, 3, 2562, 3, 2562, 3, 2578, 3, 2581, 3, 2583, 3, 2585, 3, 2587, 3, 2613, 3, 2658, 3, 2686, 3, 2690, 3, 2718, 3, 2754, 3, 2761, 3, 2763, 3, 2790, 3, 2818, 3, 2871, 3, 2882, 3, 2903, 3, 2914, 3, 2932, 3, 2946, 3, 2963, 3, 3074, 3, 3146, 3, 3202, 3, 3252, 3, 3266, 3, 3316, 3, 4101, 3, 4153, 3, 4229, 3, 4273, 3, 4306, 3, 4330, 3, 4357, 3, 4392, 3, 4434, 3, 4468, 3, 4472, 3, 4472, 3, 4485, 3, 4532, 3, 4547, 3, 4550, 3, 4572, 3, 4572, 3, 4574, 3, 4574, 3, 4610, 3, 4627, 3, 4629, 3, 4653, 3, 4738, 3, 4744, 3, 4746, 3, 4746, 3, 4748, 3, 4751, 3, 4753, 3, 4767, 3, 4769, 3, 4778, 3, 4786, 3, 4832, 3, 4871, 3, 4878, 3, 4881, 3, 4882, 3, 4885, 3, 4906, 3, 4908, 3, 4914, 3, 4916, 3, 4917, 3, 4919, 3, 4923, 3, 4927, 3, 4927, 3, 4946, 3, 4946, 3, 4959, 3, 4963, 3, 5122, 3, 5174, 3, 5193, 3, 5196, 3, 5250, 3, 5297, 3, 5318, 3, 5319, 3, 5321, 3, 5321, 3, 5506, 3, 5552, 3, 5594, 3, 5597, 3, 5634, 3, 5681, 3, 5702, 3, 5702, 3, 5762, 3, 5804, 3, 5890, 3, 5915, 3, 6306, 3, 6369, 3, 6401, 3, 6401, 3, 6658, 3, 6658, 3, 6669, 3, 6708, 3, 6716, 3, 6716, 3, 6738, 3, 6738, 3, 6750, 3, 6789, 3, 6792, 3, 6795, 3, 6850, 3, 6906, 3, 7170, 3, 7178, 3, 7180, 3, 7216, 3, 7234, 3, 7234, 3, 7284, 3, 7313, 3, 7426, 3, 7432, 3, 7434, 3, 7435, 3, 7437, 3, 7474, 3, 7496, 3, 7496, 3, 8194, 3, 9115, 3, 9218, 3, 9328, 3, 9346, 3, 9541, 3, 12290, 3, 13360, 3, 17410, 3, 17992, 3, 26626, 3, 27194, 3, 27202, 3, 27232, 3, 27346, 3, 27375, 3, 27394, 3, 27441, 3, 27458, 3, 27461, 3, 27493, 3, 27513, 3, 27519, 3, 27537, 3, 28418, 3, 28486, 3, 28498, 3, 28498, 3, 28565, 3, 28577, 3, 28642, 3, 28643, 3, 28674, 3, 34798, 3, 34818, 3, 35572, 3, 45058, 3, 45344, 3, 45426, 3, 45821, 3, 48130, 3, 48236, 3, 48242, 3, 48254, 3, 48258, 3, 48266, 3, 48274, 3, 48283, 3, 54274, 3, 54358, 3, 54360, 3, 54430, 3, 54432, 3, 54433, 3, 54436, 3, 54436, 3, 54439, 3, 54440, 3, 54443, 3, 54446, 3, 54448, 3, 54459, 3, 54461, 3, 54461, 3, 54463, 3, 54469, 3, 54471, 3, 54535, 3, 54537, 3, 54540, 3, 54543, 3, 54550, 3, 54552, 3, 54558, 3, 54560, 3, 54587, 3, 54589, 3, 54592, 3, 54594, 3, 54598, 3, 54600, 3, 54600, 3, 54604, 3, 54610, 3, 54612, 3, 54951, 3, 54954, 3, 54978, 3, 54980, 3, 55004, 3, 55006, 3, 55036, 3, 55038, 3, 55062, 3, 55064, 3, 55094, 3, 55096, 3, 55120, 3, 55122, 3, 55152, 3, 55154, 3, 55178, 3, 55180, 3, 55210, 3, 55212, 3, 55236, 3, 55238, 3, 55245, 3, 59394, 3, 59590, 3, 59650, 3, 59717, 3, 60930, 3, 60933, 3, 60935, 3, 60961, 3, 60963, 3, 60964, 3, 60966, 3, 60966, 3, 60969, 3, 60969, 3, 60971, 3, 60980, 3, 60982, 3, 60985, 3, 60987, 3, 60987, 3, 60989, 3, 60989, 3, 60996, 3, 60996, 3, 61001, 3, 61001, 3, 61003, 3, 61003, 3, 61005, 3, 61005, 3, 61007, 3, 61009, 3, 61011, 3, 61012, 3, 61014, 3, 61014, 3, 61017, 3, 61017, 3, 61019, 3, 61019, 3, 61021, 3, 61021, 3, 61023, 3, 61023, 3, 61025, 3, 61025, 3, 61027, 3, 61028, 3, 61030, 3, 61030, 3, 61033, 3, 61036, 3, 61038, 3, 61044, 3, 61046, 3, 61049, 3, 61051, 3, 61054, 3, 61056, 3, 61056, 3, 61058, 3, 61067, 3, 61069, 3, 61085, 3, 61091, 3, 61093, 3, 61095, 3, 61099, 3, 61101, 3, 61117, 3, 2, 4, 42712, 4, 42754, 4, 46902, 4, 46914, 4, 47135, 4, 47138, 4, 52899, 4, 52914, 4, 60386, 4, 63490, 4, 64031, 4, 1020, 2, 3, 3, 2, 2, 2, 2, 5, 3, 2, 2, 2, 2, 7, 3, 2, 2, 2, 2, 9, 3, 2, 2, 2, 2, 11, 3, 2, 2, 2, 2, 13, 3, 2, 2, 2, 2, 15, 3, 2, 2, 2, 2, 17, 3, 2, 2, 2, 2, 19, 3, 2, 2, 2, 2, 21, 3, 2, 2, 2, 2, 23, 3, 2, 2, 2, 2, 25, 3, 2, 2, 2, 2, 27, 3, 2, 2, 2, 2, 29, 3, 2, 2, 2, 2, 31, 3, 2, 2, 2, 2, 33, 3, 2, 2, 2, 2, 35, 3, 2, 2, 2, 2, 37, 3, 2, 2, 2, 2, 39, 3, 2, 2, 2, 2, 41, 3, 2, 2, 2, 2, 43, 3, 2, 2, 2, 2, 45, 3, 2, 2, 2, 2, 47, 3, 2, 2, 2, 2, 49, 3, 2, 2, 2, 2, 51, 3, 2, 2, 2, 2, 53, 3, 2, 2, 2, 2, 55, 3, 2, 2, 2, 2, 57, 3, 2, 2, 2, 2, 59, 3, 2, 2, 2, 2, 61, 3, 2, 2, 2, 2, 63, 3, 2, 2, 2, 2, 65, 3, 2, 2, 2, 2, 67, 3, 2, 2, 2, 2, 69, 3, 2, 2, 2, 2, 71, 3, 2, 2, 2, 2, 73, 3, 2, 2, 2, 2, 75, 3, 2, 2, 2, 2, 77, 3, 2, 2, 2, 2, 79, 3, 2, 2, 2, 2, 81, 3, 2, 2, 2, 2, 83, 3, 2, 2, 2, 2, 85, 3, 2, 2, 2, 2, 87, 3, 2, 2, 2, 2, 89, 3, 2, 2, 2, 2, 91, 3, 2, 2, 2, 2, 93, 3, 2, 2, 2, 2, 95, 3, 2, 2, 2, 2, 97, 3, 2, 2, 2, 2, 99, 3, 2, 2, 2, 2, 101, 3, 2, 2, 2, 2, 103, 3, 2, 2, 2, 2, 105, 3, 2, 2, 2, 2, 107, 3, 2, 2, 2, 2, 109, 3, 2, 2, 2, 2, 111, 3, 2, 2, 2, 2, 113, 3, 2, 2, 2, 2, 115, 3, 2, 2, 2, 2, 117, 3, 2, 2, 2, 2, 119, 3, 2, 2, 2, 2, 121, 3, 2, 2, 2, 2, 123, 3, 2, 2, 2, 2, 125, 3, 2, 2, 2, 2, 127, 3, 2, 2, 2, 2, 129, 3, 2, 2, 2, 2, 131, 3, 2, 2, 2, 2, 133, 3, 2, 2, 2, 2, 135, 3, 2, 2, 2, 2, 137, 3, 2, 2, 2, 2, 139, 3, 2, 2, 2, 2, 141, 3, 2, 2, 2, 2, 143, 3, 2, 2, 2, 2, 145, 3, 2, 2, 2, 2, 147, 3, 2, 2, 2, 2, 149, 3, 2, 2, 2, 2, 151, 3, 2, 2, 2, 2, 153, 3, 2, 2, 2, 2, 155, 3, 2, 2, 2, 2, 157, 3, 2, 2, 2, 2, 159, 3, 2, 2, 2, 2, 161, 3, 2, 2, 2, 2, 163, 3, 2, 2, 2, 2, 165, 3, 2, 2, 2, 2, 167, 3, 2, 2, 2, 2, 169, 3, 2, 2, 2, 2, 171, 3, 2, 2, 2, 2, 173, 3, 2, 2, 2, 2, 175, 3, 2, 2, 2, 2, 177, 3, 2, 2, 2, 2, 179, 3, 2, 2, 2, 2, 181, 3, 2, 2, 2, 2, 183, 3, 2, 2, 2, 2, 185, 3, 2, 2, 2, 2, 187, 3, 2, 2, 2, 2, 189, 3, 2, 2, 2, 2, 191, 3, 2, 2, 2, 2, 193, 3, 2, 2, 2, 2, 195, 3, 2, 2, 2, 2, 197, 3, 2, 2, 2, 2, 199, 3, 2, 2, 2, 2, 201, 3, 2, 2, 2, 2, 203, 3, 2, 2, 2, 2, 205, 3, 2, 2, 2, 2, 207, 3, 2, 2, 2, 2, 209, 3, 2, 2, 2, 2, 211, 3, 2, 2, 2, 2, 213, 3, 2, 2, 2, 2, 215, 3, 2, 2, 2, 2, 217, 3, 2, 2, 2, 2, 219, 3, 2, 2, 2, 2, 221, 3, 2, 2, 2, 2, 223, 3, 2, 2, 2, 2, 225, 3, 2, 2, 2, 2, 227, 3, 2, 2, 2, 2, 229, 3, 2, 2, 2, 2, 231, 3, 2, 2, 2, 2, 233, 3, 2, 2, 2, 2, 235, 3, 2, 2, 2, 2, 237, 3, 2, 2, 2, 2, 239, 3, 2, 2, 2, 2, 241, 3, 2, 2, 2, 2, 243, 3, 2, 2, 2, 2, 245, 3, 2, 2, 2, 2, 247, 3, 2, 2, 2, 2, 249, 3, 2, 2, 2, 2, 251, 3, 2, 2, 2, 2, 253, 3, 2, 2, 2, 2, 255, 3, 2, 2, 2, 3, 297, 3, 2, 2, 2, 5, 299, 3, 2, 2, 2, 7, 301, 3, 2, 2, 2, 9, 303, 3, 2, 2, 2, 11, 306, 3, 2, 2, 2, 13, 308, 3, 2, 2, 2, 15, 310, 3, 2, 2, 2, 17, 312, 3, 2, 2, 2, 19, 314, 3, 2, 2, 2, 21, 316, 3, 2, 2, 2, 23, 318, 3, 2, 2, 2, 25, 320, 3, 2, 2, 2, 27, 323, 3, 2, 2, 2, 29, 325, 3, 2, 2, 2, 31, 327, 3, 2, 2, 2, 33, 329, 3, 2, 2, 2, 35, 331, 3, 2, 2, 2, 37, 333, 3, 2, 2, 2, 39, 336, 3, 2, 2, 2, 41, 338, 3, 2, 2, 2, 43, 340, 3, 2, 2, 2, 45, 343, 3, 2, 2, 2, 47, 346, 3, 2, 2, 2, 49, 348, 3, 2, 2, 2, 51, 350, 3, 2, 2, 2, 53, 352, 3, 2, 2, 2, 55, 354, 3, 2, 2, 2, 57, 356, 3, 2, 2, 2, 59, 358, 3, 2, 2, 2, 61, 360, 3, 2, 2, 2, 63, 362, 3, 2, 2, 2, 65, 364, 3, 2, 2, 2, 67, 366, 3, 2, 2, 2, 69, 368, 3, 2, 2, 2, 71, 370, 3, 2, 2, 2, 73, 372, 3, 2, 2, 2, 75, 374, 3, 2, 2, 2, 77, 376, 3, 2, 2, 2, 79, 378, 3, 2, 2, 2, 81, 380, 3, 2, 2, 2, 83, 382, 3, 2, 2, 2, 85, 384, 3, 2, 2, 2, 87, 386, 3, 2, 2, 2, 89, 388, 3, 2, 2, 2, 91, 390, 3, 2, 2, 2, 93, 392, 3, 2, 2, 2, 95, 398, 3, 2, 2, 2, 97, 402, 3, 2, 2, 2, 99, 411, 3, 2, 2, 2, 101, 417, 3, 2, 2, 2, 103, 424, 3, 2, 2, 2, 105, 427, 3, 2, 2, 2, 107, 433, 3, 2, 2, 2, 109, 436, 3, 2, 2, 2, 111, 443, 3, 2, 2, 2, 113, 447, 3, 2, 2, 2, 115, 454, 3, 2, 2, 2, 117, 461, 3, 2, 2, 2, 119, 468, 3, 2, 2, 2, 121, 473, 3, 2, 2, 2, 123, 479, 3, 2, 2, 2, 125, 484, 3, 2, 2, 2, 127, 491, 3, 2, 2, 2, 129, 500, 3, 2, 2, 2, 131, 506, 3, 2, 2, 2, 133, 509, 3, 2, 2, 2, 135, 514, 3, 2, 2, 2, 137, 520, 3, 2, 2, 2, 139, 530, 3, 2, 2, 2, 141, 534, 3, 2, 2, 2, 143, 545, 3, 2, 2, 2, 145, 550, 3, 2, 2, 2, 147, 556, 3, 2, 2, 2, 149, 559, 3, 2, 2, 2, 151, 563, 3, 2, 2, 2, 153, 567, 3, 2, 2, 2, 155, 571, 3, 2, 2, 2, 157, 574, 3, 2, 2, 2, 159, 581, 3, 2, 2, 2, 161, 586, 3, 2, 2, 2, 163, 595, 3, 2, 2, 2, 165, 598, 3, 2, 2, 2, 167, 603, 3, 2, 2, 2, 169, 609, 3, 2, 2, 2, 171, 613, 3, 2, 2, 2, 173, 618, 3, 2, 2, 2, 175, 625, 3, 2, 2, 2, 177, 630, 3, 2, 2, 2, 179, 636, 3, 2, 2, 2, 181, 643, 3, 2, 2, 2, 183, 648, 3, 2, 2, 2, 185, 653, 3, 2, 2, 2, 187, 657, 3, 2, 2, 2, 189, 662, 3, 2, 2, 2, 191, 685, 3, 2, 2, 2, 193, 687, 3, 2, 2, 2, 195, 707, 3, 2, 2, 2, 197, 723, 3, 2, 2, 2, 199, 725, 3, 2, 2, 2, 201, 732, 3, 2, 2, 2, 203, 736, 3, 2, 2, 2, 205, 740, 3, 2, 2, 2, 207, 744, 3, 2, 2, 2, 209, 746, 3, 2, 2, 2, 211, 750, 3, 2, 2, 2, 213, 752, 3, 2, 2, 2, 215, 776, 3, 2, 2, 2, 217, 790, 3, 2, 2, 2, 219, 799, 3, 2, 2, 2, 221, 810, 3, 2, 2, 2, 223, 813, 3, 2, 2, 2, 225, 817, 3, 2, 2, 2, 227, 825, 3, 2, 2, 2, 229, 832, 3, 2, 2, 2, 231, 842, 3, 2, 2, 2, 233, 849, 3, 2, 2, 2, 235, 852, 3, 2, 2, 2, 237, 856, 3, 2, 2, 2, 239, 861, 3, 2, 2, 2, 241, 868, 3, 2, 2, 2, 243, 876, 3, 2, 2, 2, 245, 885, 3, 2, 2, 2, 247, 889, 3, 2, 2, 2, 249, 899, 3, 2, 2, 2, 251, 904, 3, 2, 2, 2, 253, 920, 3, 2, 2, 2, 255, 951, 3, 2, 2, 2, 257, 953, 3, 2, 2, 2, 259, 955, 3, 2, 2, 2, 261, 957, 3, 2, 2, 2, 263, 959, 3, 2, 2, 2, 265, 961, 3, 2, 2, 2, 267, 963, 3, 2, 2, 2, 269, 965, 3, 2, 2, 2, 271, 967, 3, 2, 2, 2, 273, 969, 3, 2, 2, 2, 275, 971, 3, 2, 2, 2, 277, 973, 3, 2, 2, 2, 279, 975, 3, 2, 2, 2, 281, 977, 3, 2, 2, 2, 283, 979, 3, 2, 2, 2, 285, 981, 3, 2, 2, 2, 287, 983, 3, 2, 2, 2, 289, 985, 3, 2, 2, 2, 291, 987, 3, 2, 2, 2, 293, 989, 3, 2, 2, 2, 295, 991, 3, 2, 2, 2, 297, 298, 7, 61, 2, 2, 298, 4, 3, 2, 2, 2, 299, 300, 7, 46, 2, 2, 300, 6, 3, 2, 2, 2, 301, 302, 7, 63, 2, 2, 302, 8, 3, 2, 2, 2, 303, 304, 7, 45, 2, 2, 304, 305, 7, 63, 2, 2, 305, 10, 3, 2, 2, 2, 306, 307, 7, 44, 2, 2, 307, 12, 3, 2, 2, 2, 308, 309, 7, 42, 2, 2, 309, 14, 3, 2, 2, 2, 310, 311, 7, 43, 2, 2, 311, 16, 3, 2, 2, 2, 312, 313, 7, 93, 2, 2, 313, 18, 3, 2, 2, 2, 314, 315, 7, 95, 2, 2, 315, 20, 3, 2, 2, 2, 316, 317, 7, 60, 2, 2, 317, 22, 3, 2, 2, 2, 318, 319, 7, 126, 2, 2, 319, 24, 3, 2, 2, 2, 320, 321, 7, 48, 2, 2, 321, 322, 7, 48, 2, 2, 322, 26, 3, 2, 2, 2, 323, 324, 7, 45, 2, 2, 324, 28, 3, 2, 2, 2, 325, 326, 7, 47, 2, 2, 326, 30, 3, 2, 2, 2, 327, 328, 7, 49, 2, 2, 328, 32, 3, 2, 2, 2, 329, 330, 7, 39, 2, 2, 330, 34, 3, 2, 2, 2, 331, 332, 7, 96, 2, 2, 332, 36, 3, 2, 2, 2, 333, 334, 7, 62, 2, 2, 334, 335, 7, 64, 2, 2, 335, 38, 3, 2, 2, 2, 336, 337, 7, 62, 2, 2, 337, 40, 3, 2, 2, 2, 338, 339, 7, 64, 2, 2, 339, 42, 3, 2, 2, 2, 340, 341, 7, 62, 2, 2, 341, 342, 7, 63, 2, 2, 342, 44, 3, 2, 2, 2, 343, 344, 7, 64, 2, 2, 344, 345, 7, 63, 2, 2, 345, 46, 3, 2, 2, 2, 346, 347, 7, 48, 2, 2, 347, 48, 3, 2, 2, 2, 348, 349, 7, 125, 2, 2, 349, 50, 3, 2, 2, 2, 350, 351, 7, 127, 2, 2, 351, 52, 3, 2, 2, 2, 352, 353, 7, 38, 2, 2, 353, 54, 3, 2, 2, 2, 354, 355, 7, 10218, 2, 2, 355, 56, 3, 2, 2, 2, 356, 357, 7, 12298, 2, 2, 357, 58, 3, 2, 2, 2, 358, 359, 7, 65126, 2, 2, 359, 60, 3, 2, 2, 2, 360, 361, 7, 65310, 2, 2, 361, 62, 3, 2, 2, 2, 362, 363, 7, 10219, 2, 2, 363, 64, 3, 2, 2, 2, 364, 365, 7, 12299, 2, 2, 365, 66, 3, 2, 2, 2, 366, 367, 7, 65127, 2, 2, 367, 68, 3, 2, 2, 2, 368, 369, 7, 65312, 2, 2, 369, 70, 3, 2, 2, 2, 370, 371, 7, 175, 2, 2, 371, 72, 3, 2, 2, 2, 372, 373, 7, 8210, 2, 2, 373, 74, 3, 2, 2, 2, 374, 375, 7, 8211, 2, 2, 375, 76, 3, 2, 2, 2, 376, 377, 7, 8212, 2, 2, 377, 78, 3, 2, 2, 2, 378, 379, 7, 8213, 2, 2, 379, 80, 3, 2, 2, 2, 380, 381, 7, 8214, 2, 2, 381, 82, 3, 2, 2, 2, 382, 383, 7, 8215, 2, 2, 383, 84, 3, 2, 2, 2, 384, 385, 7, 8724, 2, 2, 385, 86, 3, 2, 2, 2, 386, 387, 7, 65114, 2, 2, 387, 88, 3, 2, 2, 2, 388, 389, 7, 65125, 2, 2, 389, 90, 3, 2, 2, 2, 390, 391, 7, 65295, 2, 2, 391, 92, 3, 2, 2, 2, 392, 393, 9, 2, 2, 2, 393, 394, 9, 3, 2, 2, 394, 395, 9, 4, 2, 2, 395, 396, 9, 5, 2, 2, 396, 397, 9, 3, 2, 2, 397, 94, 3, 2, 2, 2, 398, 399, 9, 6, 2, 2, 399, 400, 9, 7, 2, 2, 400, 401, 9, 7, 2, 2, 401, 96, 3, 2, 2, 2, 402, 403, 9, 5, 2, 2, 403, 404, 9, 8, 2, 2, 404, 405, 9, 9, 2, 2, 405, 406, 9, 4, 2, 2, 406, 407, 9, 5, 2, 2, 407, 408, 9, 3, 2, 2, 408, 409, 9, 6, 2, 2, 409, 410, 9, 7, 2, 2, 410, 98, 3, 2, 2, 2, 411, 412, 9, 10, 2, 2, 412, 413, 9, 6, 2, 2, 413, 414, 9, 9, 2, 2, 414, 415, 9, 11, 2, 2, 415, 416, 9, 12, 2, 2, 416, 100, 3, 2, 2, 2, 417, 418, 9, 2, 2, 2, 418, 419, 9, 3, 2, 2, 419, 420, 9, 13, 2, 2, 420, 421, 9, 4, 2, 2, 421, 422, 9, 3, 2, 2, 422, 423, 9, 14, 2, 2, 423, 102, 3, 2, 2, 2, 424, 425, 9, 6, 2, 2, 425, 426, 9, 15, 2, 2, 426, 104, 3, 2, 2, 2, 427, 428, 9, 10, 2, 2, 428, 429, 9, 16, 2, 2, 429, 430, 9, 17, 2, 2, 430, 431, 9, 18, 2, 2, 431, 432, 9, 16, 2, 2, 432, 106, 3, 2, 2, 2, 433, 434, 9, 5, 2, 2, 434, 435, 9, 3, 2, 2, 435, 108, 3, 2, 2, 2, 436, 437, 9, 11, 2, 2, 437, 438, 9, 17, 2, 2, 438, 439, 9, 16, 2, 2, 439, 440, 9, 6, 2, 2, 440, 441, 9, 9, 2, 2, 441, 442, 9, 16, 2, 2, 442, 110, 3, 2, 2, 2, 443, 444, 9, 15, 2, 2, 444, 445, 9, 16, 2, 2, 445, 446, 9, 9, 2, 2, 446, 112, 3, 2, 2, 2, 447, 448, 9, 14, 2, 2, 448, 449, 9, 16, 2, 2, 449, 450, 9, 9, 2, 2, 450, 451, 9, 6, 2, 2, 451, 452, 9, 11, 2, 2, 452, 453, 9, 12, 2, 2, 453, 114, 3, 2, 2, 2, 454, 455, 9, 14, 2, 2, 455, 456, 9, 16, 2, 2, 456, 457, 9, 7, 2, 2, 457, 458, 9, 16, 2, 2, 458, 459, 9, 9, 2, 2, 459, 460, 9, 16, 2, 2, 460, 116, 3, 2, 2, 2, 461, 462, 9, 17, 2, 2, 462, 463, 9, 16, 2, 2, 463, 464, 9, 10, 2, 2, 464, 465, 9, 5, 2, 2, 465, 466, 9, 19, 2, 2, 466, 467, 9, 16, 2, 2, 467, 118, 3, 2, 2, 2, 468, 469, 9, 11, 2, 2, 469, 470, 9, 6, 2, 2, 470, 471, 9, 7, 2, 2, 471, 472, 9, 7, 2, 2, 472, 120, 3, 2, 2, 2, 473, 474, 9, 20, 2, 2, 474, 475, 9, 4, 2, 2, 475, 476, 9, 16, 2, 2, 476, 477, 9, 7, 2, 2, 477, 478, 9, 14, 2, 2, 478, 122, 3, 2, 2, 2, 479, 480, 9, 13, 2, 2, 480, 481, 9, 4, 2, 2, 481, 482, 9, 9, 2, 2, 482, 483, 9, 12, 2, 2, 483, 124, 3, 2, 2, 2, 484, 485, 9, 17, 2, 2, 485, 486, 9, 16, 2, 2, 486, 487, 9, 9, 2, 2, 487, 488, 9, 2, 2, 2, 488, 489, 9, 17, 2, 2, 489, 490, 9, 3, 2, 2, 490, 126, 3, 2, 2, 2, 491, 492, 9, 14, 2, 2, 492, 493, 9, 4, 2, 2, 493, 494, 9, 15, 2, 2, 494, 495, 9, 9, 2, 2, 495, 496, 9, 4, 2, 2, 496, 497, 9, 3, 2, 2, 497, 498, 9, 11, 2, 2, 498, 499, 9, 9, 2, 2, 499, 128, 3, 2, 2, 2, 500, 501, 9, 5, 2, 2, 501, 502, 9, 17, 2, 2, 502, 503, 9, 14, 2, 2, 503, 504, 9, 16, 2, 2, 504, 505, 9, 17, 2, 2, 505, 130, 3, 2, 2, 2, 506, 507, 9, 21, 2, 2, 507, 508, 9, 20, 2, 2, 508, 132, 3, 2, 2, 2, 509, 510, 9, 15, 2, 2, 510, 511, 9, 22, 2, 2, 511, 512, 9, 4, 2, 2, 512, 513, 9, 8, 2, 2, 513, 134, 3, 2, 2, 2, 514, 515, 9, 7, 2, 2, 515, 516, 9, 4, 2, 2, 516, 517, 9, 10, 2, 2, 517, 518, 9, 4, 2, 2, 518, 519, 9, 9, 2, 2, 519, 136, 3, 2, 2, 2, 520, 521, 9, 6, 2, 2, 521, 522, 9, 15, 2, 2, 522, 523, 9, 11, 2, 2, 523, 524, 9, 16, 2, 2, 524, 525, 9, 3, 2, 2, 525, 526, 9, 14, 2, 2, 526, 527, 9, 4, 2, 2, 527, 528, 9, 3, 2, 2, 528, 529, 9, 18, 2, 2, 529, 138, 3, 2, 2, 2, 530, 531, 9, 6, 2, 2, 531, 532, 9, 15, 2, 2, 532, 533, 9, 11, 2, 2, 533, 140, 3, 2, 2, 2, 534, 535, 9, 14, 2, 2, 535, 536, 9, 16, 2, 2, 536, 537, 9, 15, 2, 2, 537, 538, 9, 11, 2, 2, 538, 539, 9, 16, 2, 2, 539, 540, 9, 3, 2, 2, 540, 541, 9, 14, 2, 2, 541, 542, 9, 4, 2, 2, 542, 543, 9, 3, 2, 2, 543, 544, 9, 18, 2, 2, 544, 142, 3, 2, 2, 2, 545, 546, 9, 14, 2, 2, 546, 547, 9, 16, 2, 2, 547, 548, 9, 15, 2, 2, 548, 549, 9, 11, 2, 2, 549, 144, 3, 2, 2, 2, 550, 551, 9, 13, 2, 2, 551, 552, 9, 12, 2, 2, 552, 553, 9, 16, 2, 2, 553, 554, 9, 17, 2, 2, 554, 555, 9, 16, 2, 2, 555, 146, 3, 2, 2, 2, 556, 557, 9, 5, 2, 2, 557, 558, 9, 17, 2, 2, 558, 148, 3, 2, 2, 2, 559, 560, 9, 23, 2, 2, 560, 561, 9, 5, 2, 2, 561, 562, 9, 17, 2, 2, 562, 150, 3, 2, 2, 2, 563, 564, 9, 6, 2, 2, 564, 565, 9, 3, 2, 2, 565, 566, 9, 14, 2, 2, 566, 152, 3, 2, 2, 2, 567, 568, 9, 3, 2, 2, 568, 569, 9, 5, 2, 2, 569, 570, 9, 9, 2, 2, 570, 154, 3, 2, 2, 2, 571, 572, 9, 4, 2, 2, 572, 573, 9, 3, 2, 2, 573, 156, 3, 2, 2, 2, 574, 575, 9, 15, 2, 2, 575, 576, 9, 9, 2, 2, 576, 577, 9, 6, 2, 2, 577, 578, 9, 17, 2, 2, 578, 579, 9, 9, 2, 2, 579, 580, 9, 15, 2, 2, 580, 158, 3, 2, 2, 2, 581, 582, 9, 16, 2, 2, 582, 583, 9, 3, 2, 2, 583, 584, 9, 14, 2, 2, 584, 585, 9, 15, 2, 2, 585, 160, 3, 2, 2, 2, 586, 587, 9, 11, 2, 2, 587, 588, 9, 5, 2, 2, 588, 589, 9, 3, 2, 2, 589, 590, 9, 9, 2, 2, 590, 591, 9, 6, 2, 2, 591, 592, 9, 4, 2, 2, 592, 593, 9, 3, 2, 2, 593, 594, 9, 15, 2, 2, 594, 162, 3, 2, 2, 2, 595, 596, 9, 4, 2, 2, 596, 597, 9, 15, 2, 2, 597, 164, 3, 2, 2, 2, 598, 599, 9, 3, 2, 2, 599, 600, 9, 2, 2, 2, 600, 601, 9, 7, 2, 2, 601, 602, 9, 7, 2, 2, 602, 166, 3, 2, 2, 2, 603, 604, 9, 11, 2, 2, 604, 605, 9, 5, 2, 2, 605, 606, 9, 2, 2, 2, 606, 607, 9, 3, 2, 2, 607, 608, 9, 9, 2, 2, 608, 168, 3, 2, 2, 2, 609, 610, 9, 6, 2, 2, 610, 611, 9, 3, 2, 2, 611, 612, 9, 20, 2, 2, 612, 170, 3, 2, 2, 2, 613, 614, 9, 3, 2, 2, 614, 615, 9, 5, 2, 2, 615, 616, 9, 3, 2, 2, 616, 617, 9, 16, 2, 2, 617, 172, 3, 2, 2, 2, 618, 619, 9, 15, 2, 2, 619, 620, 9, 4, 2, 2, 620, 621, 9, 3, 2, 2, 621, 622, 9, 18, 2, 2, 622, 623, 9, 7, 2, 2, 623, 624, 9, 16, 2, 2, 624, 174, 3, 2, 2, 2, 625, 626, 9, 9, 2, 2, 626, 627, 9, 17, 2, 2, 627, 628, 9, 2, 2, 2, 628, 629, 9, 16, 2, 2, 629, 176, 3, 2, 2, 2, 630, 631, 9, 24, 2, 2, 631, 632, 9, 6, 2, 2, 632, 633, 9, 7, 2, 2, 633, 634, 9, 15, 2, 2, 634, 635, 9, 16, 2, 2, 635, 178, 3, 2, 2, 2, 636, 637, 9, 16, 2, 2, 637, 638, 9, 23, 2, 2, 638, 639, 9, 4, 2, 2, 639, 640, 9, 15, 2, 2, 640, 641, 9, 9, 2, 2, 641, 642, 9, 15, 2, 2, 642, 180, 3, 2, 2, 2, 643, 644, 9, 11, 2, 2, 644, 645, 9, 6, 2, 2, 645, 646, 9, 15, 2, 2, 646, 647, 9, 16, 2, 2, 647, 182, 3, 2, 2, 2, 648, 649, 9, 16, 2, 2, 649, 650, 9, 7, 2, 2, 650, 651, 9, 15, 2, 2, 651, 652, 9, 16, 2, 2, 652, 184, 3, 2, 2, 2, 653, 654, 9, 16, 2, 2, 654, 655, 9, 3, 2, 2, 655, 656, 9, 14, 2, 2, 656, 186, 3, 2, 2, 2, 657, 658, 9, 13, 2, 2, 658, 659, 9, 12, 2, 2, 659, 660, 9, 16, 2, 2, 660, 661, 9, 3, 2, 2, 661, 188, 3, 2, 2, 2, 662, 663, 9, 9, 2, 2, 663, 664, 9, 12, 2, 2, 664, 665, 9, 16, 2, 2, 665, 666, 9, 3, 2, 2, 666, 190, 3, 2, 2, 2, 667, 672, 7, 36, 2, 2, 668, 671, 5, 287, 144, 2, 669, 671, 5, 193, 97, 2, 670, 668, 3, 2, 2, 2, 670, 669, 3, 2, 2, 2, 671, 674, 3, 2, 2, 2, 672, 670, 3, 2, 2, 2, 672, 673, 3, 2, 2, 2, 673, 675, 3, 2, 2, 2, 674, 672, 3, 2, 2, 2, 675, 686, 7, 36, 2, 2, 676, 681, 7, 41, 2, 2, 677, 680, 5, 267, 134, 2, 678, 680, 5, 193, 97, 2, 679, 677, 3, 2, 2, 2, 679, 678, 3, 2, 2, 2, 680, 683, 3, 2, 2, 2, 681, 679, 3, 2, 2, 2, 681, 682, 3, 2, 2, 2, 682, 684, 3, 2, 2, 2, 683, 681, 3, 2, 2, 2, 684, 686, 7, 41, 2, 2, 685, 667, 3, 2, 2, 2, 685, 676, 3, 2, 2, 2, 686, 192, 3, 2, 2, 2, 687, 705, 7, 94, 2, 2, 688, 706, 9, 25, 2, 2, 689, 690, 9, 2, 2, 2, 690, 691, 5, 203, 102, 2, 691, 692, 5, 203, 102, 2, 692, 693, 5, 203, 102, 2, 693, 694, 5, 203, 102, 2, 694, 706, 3, 2, 2, 2, 695, 696, 9, 2, 2, 2, 696, 697, 5, 203, 102, 2, 697, 698, 5, 203, 102, 2, 698, 699, 5, 203, 102, 2, 699, 700, 5, 203, 102, 2, 700, 701, 5, 203, 102, 2, 701, 702, 5, 203, 102, 2, 702, 703, 5, 203, 102, 2, 703, 704, 5, 203, 102, 2, 704, 706, 3, 2, 2, 2, 705, 688, 3, 2, 2, 2, 705, 689, 3, 2, 2, 2, 705, 695, 3, 2, 2, 2, 706, 194, 3, 2, 2, 2, 707, 708, 7, 50, 2, 2, 708, 709, 7, 122, 2, 2, 709, 711, 3, 2, 2, 2, 710, 712, 5, 203, 102, 2, 711, 710, 3, 2, 2, 2, 712, 713, 3, 2, 2, 2, 713, 711, 3, 2, 2, 2, 713, 714, 3, 2, 2, 2, 714, 196, 3, 2, 2, 2, 715, 724, 5, 213, 107, 2, 716, 720, 5, 207, 104, 2, 717, 719, 5, 205, 103, 2, 718, 717, 3, 2, 2, 2, 719, 722, 3, 2, 2, 2, 720, 718, 3, 2, 2, 2, 720, 721, 3, 2, 2, 2, 721, 724, 3, 2, 2, 2, 722, 720, 3, 2, 2, 2, 723, 715, 3, 2, 2, 2, 723, 716, 3, 2, 2, 2, 724, 198, 3, 2, 2, 2, 725, 727, 5, 213, 107, 2, 726, 728, 5, 211, 106, 2, 727, 726, 3, 2, 2, 2, 728, 729, 3, 2, 2, 2, 729, 727, 3, 2, 2, 2, 729, 730, 3, 2, 2, 2, 730, 200, 3, 2, 2, 2, 731, 733, 9, 26, 2, 2, 732, 731, 3, 2, 2, 2, 733, 202, 3, 2, 2, 2, 734, 737, 5, 205, 103, 2, 735, 737, 5, 201, 101, 2, 736, 734, 3, 2, 2, 2, 736, 735, 3, 2, 2, 2, 737, 204, 3, 2, 2, 2, 738, 741, 5, 213, 107, 2, 739, 741, 5, 207, 104, 2, 740, 738, 3, 2, 2, 2, 740, 739, 3, 2, 2, 2, 741, 206, 3, 2, 2, 2, 742, 745, 5, 209, 105, 2, 743, 745, 4, 58, 59, 2, 744, 742, 3, 2, 2, 2, 744, 743, 3, 2, 2, 2, 745, 208, 3, 2, 2, 2, 746, 747, 4, 51, 57, 2, 747, 210, 3, 2, 2, 2, 748, 751, 5, 213, 107, 2, 749, 751, 5, 209, 105, 2, 750, 748, 3, 2, 2, 2, 750, 749, 3, 2, 2, 2, 751, 212, 3, 2, 2, 2, 752, 753, 7, 50, 2, 2, 753, 214, 3, 2, 2, 2, 754, 756, 5, 205, 103, 2, 755, 754, 3, 2, 2, 2, 756, 757, 3, 2, 2, 2, 757, 755, 3, 2, 2, 2, 757, 758, 3, 2, 2, 2, 758, 777, 3, 2, 2, 2, 759, 761, 5, 205, 103, 2, 760, 759, 3, 2, 2, 2, 761, 762, 3, 2, 2, 2, 762, 760, 3, 2, 2, 2, 762, 763, 3, 2, 2, 2, 763, 764, 3, 2, 2, 2, 764, 766, 7, 48, 2, 2, 765, 767, 5, 205, 103, 2, 766, 765, 3, 2, 2, 2, 767, 768, 3, 2, 2, 2, 768, 766, 3, 2, 2, 2, 768, 769, 3, 2, 2, 2, 769, 777, 3, 2, 2, 2, 770, 772, 7, 48, 2, 2, 771, 773, 5, 205, 103, 2, 772, 771, 3, 2, 2, 2, 773, 774, 3, 2, 2, 2, 774, 772, 3, 2, 2, 2, 774, 775, 3, 2, 2, 2, 775, 777, 3, 2, 2, 2, 776, 755, 3, 2, 2, 2, 776, 760, 3, 2, 2, 2, 776, 770, 3, 2, 2, 2, 777, 778, 3, 2, 2, 2, 778, 780, 9, 16, 2, 2, 779, 781, 7, 47, 2, 2, 780, 779, 3, 2, 2, 2, 780, 781, 3, 2, 2, 2, 781, 783, 3, 2, 2, 2, 782, 784, 5, 205, 103, 2, 783, 782, 3, 2, 2, 2, 784, 785, 3, 2, 2, 2, 785, 783, 3, 2, 2, 2, 785, 786, 3, 2, 2, 2, 786, 216, 3, 2, 2, 2, 787, 789, 5, 205, 103, 2, 788, 787, 3, 2, 2, 2, 789, 792, 3, 2, 2, 2, 790, 788, 3, 2, 2, 2, 790, 791, 3, 2, 2, 2, 791, 793, 3, 2, 2, 2, 792, 790, 3, 2, 2, 2, 793, 795, 7, 48, 2, 2, 794, 796, 5, 205, 103, 2, 795, 794, 3, 2, 2, 2, 796, 797, 3, 2, 2, 2, 797, 795, 3, 2, 2, 2, 797, 798, 3, 2, 2, 2, 798, 218, 3, 2, 2, 2, 799, 800, 9, 11, 2, 2, 800, 801, 9, 5, 2, 2, 801, 802, 9, 3, 2, 2, 802, 803, 9, 15, 2, 2, 803, 804, 9, 9, 2, 2, 804, 805, 9, 17, 2, 2, 805, 806, 9, 6, 2, 2, 806, 807, 9, 4, 2, 2, 807, 808, 9, 3, 2, 2, 808, 809, 9, 9, 2, 2, 809, 220, 3, 2, 2, 2, 810, 811, 9, 14, 2, 2, 811, 812, 9, 5, 2, 2, 812, 222, 3, 2, 2, 2, 813, 814, 9, 24, 2, 2, 814, 815, 9, 5, 2, 2, 815, 816, 9, 17, 2, 2, 816, 224, 3, 2, 2, 2, 817, 818, 9, 17, 2, 2, 818, 819, 9, 16, 2, 2, 819, 820, 9, 27, 2, 2, 820, 821, 9, 2, 2, 2, 821, 822, 9, 4, 2, 2, 822, 823, 9, 17, 2, 2, 823, 824, 9, 16, 2, 2, 824, 226, 3, 2, 2, 2, 825, 826, 9, 2, 2, 2, 826, 827, 9, 3, 2, 2, 827, 828, 9, 4, 2, 2, 828, 829, 9, 27, 2, 2, 829, 830, 9, 2, 2, 2, 830, 831, 9, 16, 2, 2, 831, 228, 3, 2, 2, 2, 832, 833, 9, 10, 2, 2, 833, 834, 9, 6, 2, 2, 834, 835, 9, 3, 2, 2, 835, 836, 9, 14, 2, 2, 836, 837, 9, 6, 2, 2, 837, 838, 9, 9, 2, 2, 838, 839, 9, 5, 2, 2, 839, 840, 9, 17, 2, 2, 840, 841, 9, 20, 2, 2, 841, 230, 3, 2, 2, 2, 842, 843, 9, 15, 2, 2, 843, 844, 9, 11, 2, 2, 844, 845, 9, 6, 2, 2, 845, 846, 9, 7, 2, 2, 846, 847, 9, 6, 2, 2, 847, 848, 9, 17, 2, 2, 848, 232, 3, 2, 2, 2, 849, 850, 9, 5, 2, 2, 850, 851, 9, 24, 2, 2, 851, 234, 3, 2, 2, 2, 852, 853, 9, 6, 2, 2, 853, 854, 9, 14, 2, 2, 854, 855, 9, 14, 2, 2, 855, 236, 3, 2, 2, 2, 856, 857, 9, 14, 2, 2, 857, 858, 9, 17, 2, 2, 858, 859, 9, 5, 2, 2, 859, 860, 9, 8, 2, 2, 860, 238, 3, 2, 2, 2, 861, 862, 9, 24, 2, 2, 862, 863, 9, 4, 2, 2, 863, 864, 9, 7, 2, 2, 864, 865, 9, 9, 2, 2, 865, 866, 9, 16, 2, 2, 866, 867, 9, 17, 2, 2, 867, 240, 3, 2, 2, 2, 868, 869, 9, 16, 2, 2, 869, 870, 9, 23, 2, 2, 870, 871, 9, 9, 2, 2, 871, 872, 9, 17, 2, 2, 872, 873, 9, 6, 2, 2, 873, 874, 9, 11, 2, 2, 874, 875, 9, 9, 2, 2, 875, 242, 3, 2, 2, 2, 876, 880, 5, 245, 123, 2, 877, 879, 5, 247, 124, 2, 878, 877, 3, 2, 2, 2, 879, 882, 3, 2, 2, 2, 880, 878, 3, 2, 2, 2, 880, 881, 3, 2, 2, 2, 881, 244, 3, 2, 2, 2, 882, 880, 3, 2, 2, 2, 883, 886, 5, 295, 148, 2, 884, 886, 5, 283, 142, 2, 885, 883, 3, 2, 2, 2, 885, 884, 3, 2, 2, 2, 886, 246, 3, 2, 2, 2, 887, 890, 5, 263, 132, 2, 888, 890, 5, 279, 140, 2, 889, 887, 3, 2, 2, 2, 889, 888, 3, 2, 2, 2, 890, 248, 3, 2, 2, 2, 891, 895, 7, 98, 2, 2, 892, 894, 5, 259, 130, 2, 893, 892, 3, 2, 2, 2, 894, 897, 3, 2, 2, 2, 895, 893, 3, 2, 2, 2, 895, 896, 3, 2, 2, 2, 896, 898, 3, 2, 2, 2, 897, 895, 3, 2, 2, 2, 898, 900, 7, 98, 2, 2, 899, 891, 3, 2, 2, 2, 900, 901, 3, 2, 2, 2, 901, 899, 3, 2, 2, 2, 901, 902, 3, 2, 2, 2, 902, 250, 3, 2, 2, 2, 903, 905, 5, 253, 127, 2, 904, 903, 3, 2, 2, 2, 905, 906, 3, 2, 2, 2, 906, 904, 3, 2, 2, 2, 906, 907, 3, 2, 2, 2, 907, 252, 3, 2, 2, 2, 908, 921, 5, 281, 141, 2, 909, 921, 5, 285, 143, 2, 910, 921, 5, 289, 145, 2, 911, 921, 5, 291, 146, 2, 912, 921, 5, 257, 129, 2, 913, 921, 5, 277, 139, 2, 914, 921, 5, 275, 138, 2, 915, 921, 5, 273, 137, 2, 916, 921, 5, 261, 131, 2, 917, 921, 5, 293, 147, 2, 918, 921, 9, 28, 2, 2, 919, 921, 5, 255, 128, 2, 920, 908, 3, 2, 2, 2, 920, 909, 3, 2, 2, 2, 920, 910, 3, 2, 2, 2, 920, 911, 3, 2, 2, 2, 920, 912, 3, 2, 2, 2, 920, 913, 3, 2, 2, 2, 920, 914, 3, 2, 2, 2, 920, 915, 3, 2, 2, 2, 920, 916, 3, 2, 2, 2, 920, 917, 3, 2, 2, 2, 920, 918, 3, 2, 2, 2, 920, 919, 3, 2, 2, 2, 921, 254, 3, 2, 2, 2, 922, 923, 7, 49, 2, 2, 923, 924, 7, 44, 2, 2, 924, 930, 3, 2, 2, 2, 925, 929, 5, 265, 133, 2, 926, 927, 7, 44, 2, 2, 927, 929, 5, 271, 136, 2, 928, 925, 3, 2, 2, 2, 928, 926, 3, 2, 2, 2, 929, 932, 3, 2, 2, 2, 930, 928, 3, 2, 2, 2, 930, 931, 3, 2, 2, 2, 931, 933, 3, 2, 2, 2, 932, 930, 3, 2, 2, 2, 933, 934, 7, 44, 2, 2, 934, 952, 7, 49, 2, 2, 935, 936, 7, 49, 2, 2, 936, 937, 7, 49, 2, 2, 937, 941, 3, 2, 2, 2, 938, 940, 5, 269, 135, 2, 939, 938, 3, 2, 2, 2, 940, 943, 3, 2, 2, 2, 941, 939, 3, 2, 2, 2, 941, 942, 3, 2, 2, 2, 942, 945, 3, 2, 2, 2, 943, 941, 3, 2, 2, 2, 944, 946, 5, 277, 139, 2, 945, 944, 3, 2, 2, 2, 945, 946, 3, 2, 2, 2, 946, 949, 3, 2, 2, 2, 947, 950, 5, 289, 145, 2, 948, 950, 7, 2, 2, 3, 949, 947, 3, 2, 2, 2, 949, 948, 3, 2, 2, 2, 950, 952, 3, 2, 2, 2, 951, 922, 3, 2, 2, 2, 951, 935, 3, 2, 2, 2, 952, 256, 3, 2, 2, 2, 953, 954, 9, 29, 2, 2, 954, 258, 3, 2, 2, 2, 955, 956, 10, 30, 2, 2, 956, 260, 3, 2, 2, 2, 957, 958, 9, 31, 2, 2, 958, 262, 3, 2, 2, 2, 959, 960, 9, 47, 2, 2, 960, 264, 3, 2, 2, 2, 961, 962, 10, 32, 2, 2, 962, 266, 3, 2, 2, 2, 963, 964, 10, 33, 2, 2, 964, 268, 3, 2, 2, 2, 965, 966, 10, 34, 2, 2, 966, 270, 3, 2, 2, 2, 967, 968, 10, 35, 2, 2, 968, 272, 3, 2, 2, 2, 969, 970, 9, 36, 2, 2, 970, 274, 3, 2, 2, 2, 971, 972, 9, 37, 2, 2, 972, 276, 3, 2, 2, 2, 973, 974, 9, 38, 2, 2, 974, 278, 3, 2, 2, 2, 975, 976, 9, 39, 2, 2, 976, 280, 3, 2, 2, 2, 977, 978, 9, 40, 2, 2, 978, 282, 3, 2, 2, 2, 979, 980, 9, 41, 2, 2, 980, 284, 3, 2, 2, 2, 981, 982, 9, 42, 2, 2, 982, 286, 3, 2, 2, 2, 983, 984, 10, 43, 2, 2, 984, 288, 3, 2, 2, 2, 985, 986, 9, 44, 2, 2, 986, 290, 3, 2, 2, 2, 987, 988, 9, 45, 2, 2, 988, 292, 3, 2, 2, 2, 989, 990, 9, 46, 2, 2, 990, 294, 3, 2, 2, 2, 991, 992, 9, 48, 2, 2, 992, 296, 3, 2, 2, 2, 40, 2, 670, 672, 679, 681, 685, 705, 713, 720, 723, 729, 732, 736, 740, 744, 750, 757, 762, 768, 774, 776, 780, 785, 790, 797, 880, 885, 889, 895, 901, 906, 920, 928, 930, 941, 945, 949, 951, 2] \ No newline at end of file diff --git a/parser/CypherLexer.tokens b/parser/CypherLexer.tokens new file mode 100644 index 0000000..9dacb2a --- /dev/null +++ b/parser/CypherLexer.tokens @@ -0,0 +1,173 @@ +T__0=1 +T__1=2 +T__2=3 +T__3=4 +T__4=5 +T__5=6 +T__6=7 +T__7=8 +T__8=9 +T__9=10 +T__10=11 +T__11=12 +T__12=13 +T__13=14 +T__14=15 +T__15=16 +T__16=17 +T__17=18 +T__18=19 +T__19=20 +T__20=21 +T__21=22 +T__22=23 +T__23=24 +T__24=25 +T__25=26 +T__26=27 +T__27=28 +T__28=29 +T__29=30 +T__30=31 +T__31=32 +T__32=33 +T__33=34 +T__34=35 +T__35=36 +T__36=37 +T__37=38 +T__38=39 +T__39=40 +T__40=41 +T__41=42 +T__42=43 +T__43=44 +T__44=45 +UNION=46 +ALL=47 +OPTIONAL=48 +MATCH=49 +UNWIND=50 +AS=51 +MERGE=52 +ON=53 +CREATE=54 +SET=55 +DETACH=56 +DELETE=57 +REMOVE=58 +CALL=59 +YIELD=60 +WITH=61 +RETURN=62 +DISTINCT=63 +ORDER=64 +BY=65 +L_SKIP=66 +LIMIT=67 +ASCENDING=68 +ASC=69 +DESCENDING=70 +DESC=71 +WHERE=72 +OR=73 +XOR=74 +AND=75 +NOT=76 +IN=77 +STARTS=78 +ENDS=79 +CONTAINS=80 +IS=81 +NULL=82 +COUNT=83 +ANY=84 +NONE=85 +SINGLE=86 +TRUE=87 +FALSE=88 +EXISTS=89 +CASE=90 +ELSE=91 +END=92 +WHEN=93 +THEN=94 +StringLiteral=95 +EscapedChar=96 +HexInteger=97 +DecimalInteger=98 +OctalInteger=99 +HexLetter=100 +HexDigit=101 +Digit=102 +NonZeroDigit=103 +NonZeroOctDigit=104 +OctDigit=105 +ZeroDigit=106 +ExponentDecimalReal=107 +RegularDecimalReal=108 +CONSTRAINT=109 +DO=110 +FOR=111 +REQUIRE=112 +UNIQUE=113 +MANDATORY=114 +SCALAR=115 +OF=116 +ADD=117 +DROP=118 +FILTER=119 +EXTRACT=120 +UnescapedSymbolicName=121 +IdentifierStart=122 +IdentifierPart=123 +EscapedSymbolicName=124 +SP=125 +WHITESPACE=126 +Comment=127 +';'=1 +','=2 +'='=3 +'+='=4 +'*'=5 +'('=6 +')'=7 +'['=8 +']'=9 +':'=10 +'|'=11 +'..'=12 +'+'=13 +'-'=14 +'/'=15 +'%'=16 +'^'=17 +'<>'=18 +'<'=19 +'>'=20 +'<='=21 +'>='=22 +'.'=23 +'{'=24 +'}'=25 +'$'=26 +'\u27e8'=27 +'\u3008'=28 +'\ufe64'=29 +'\uff1c'=30 +'\u27e9'=31 +'\u3009'=32 +'\ufe65'=33 +'\uff1e'=34 +'\u00ad'=35 +'\u2010'=36 +'\u2011'=37 +'\u2012'=38 +'\u2013'=39 +'\u2014'=40 +'\u2015'=41 +'\u2212'=42 +'\ufe58'=43 +'\ufe63'=44 +'\uff0d'=45 +'0'=106 diff --git a/parser/cypher_base_listener.go b/parser/cypher_base_listener.go new file mode 100644 index 0000000..9e22645 --- /dev/null +++ b/parser/cypher_base_listener.go @@ -0,0 +1,634 @@ +// Code generated from Cypher.g4 by ANTLR 4.9. DO NOT EDIT. + +package parser // Cypher + +import "github.com/antlr/antlr4/runtime/Go/antlr" + +// BaseCypherListener is a complete listener for a parse tree produced by CypherParser. +type BaseCypherListener struct{} + +var _ CypherListener = &BaseCypherListener{} + +// VisitTerminal is called when a terminal node is visited. +func (s *BaseCypherListener) VisitTerminal(node antlr.TerminalNode) {} + +// VisitErrorNode is called when an error node is visited. +func (s *BaseCypherListener) VisitErrorNode(node antlr.ErrorNode) {} + +// EnterEveryRule is called when any rule is entered. +func (s *BaseCypherListener) EnterEveryRule(ctx antlr.ParserRuleContext) {} + +// ExitEveryRule is called when any rule is exited. +func (s *BaseCypherListener) ExitEveryRule(ctx antlr.ParserRuleContext) {} + +// EnterOC_Cypher is called when production oC_Cypher is entered. +func (s *BaseCypherListener) EnterOC_Cypher(ctx *OC_CypherContext) {} + +// ExitOC_Cypher is called when production oC_Cypher is exited. +func (s *BaseCypherListener) ExitOC_Cypher(ctx *OC_CypherContext) {} + +// EnterOC_Statement is called when production oC_Statement is entered. +func (s *BaseCypherListener) EnterOC_Statement(ctx *OC_StatementContext) {} + +// ExitOC_Statement is called when production oC_Statement is exited. +func (s *BaseCypherListener) ExitOC_Statement(ctx *OC_StatementContext) {} + +// EnterOC_Query is called when production oC_Query is entered. +func (s *BaseCypherListener) EnterOC_Query(ctx *OC_QueryContext) {} + +// ExitOC_Query is called when production oC_Query is exited. +func (s *BaseCypherListener) ExitOC_Query(ctx *OC_QueryContext) {} + +// EnterOC_RegularQuery is called when production oC_RegularQuery is entered. +func (s *BaseCypherListener) EnterOC_RegularQuery(ctx *OC_RegularQueryContext) {} + +// ExitOC_RegularQuery is called when production oC_RegularQuery is exited. +func (s *BaseCypherListener) ExitOC_RegularQuery(ctx *OC_RegularQueryContext) {} + +// EnterOC_Union is called when production oC_Union is entered. +func (s *BaseCypherListener) EnterOC_Union(ctx *OC_UnionContext) {} + +// ExitOC_Union is called when production oC_Union is exited. +func (s *BaseCypherListener) ExitOC_Union(ctx *OC_UnionContext) {} + +// EnterOC_SingleQuery is called when production oC_SingleQuery is entered. +func (s *BaseCypherListener) EnterOC_SingleQuery(ctx *OC_SingleQueryContext) {} + +// ExitOC_SingleQuery is called when production oC_SingleQuery is exited. +func (s *BaseCypherListener) ExitOC_SingleQuery(ctx *OC_SingleQueryContext) {} + +// EnterOC_SinglePartQuery is called when production oC_SinglePartQuery is entered. +func (s *BaseCypherListener) EnterOC_SinglePartQuery(ctx *OC_SinglePartQueryContext) {} + +// ExitOC_SinglePartQuery is called when production oC_SinglePartQuery is exited. +func (s *BaseCypherListener) ExitOC_SinglePartQuery(ctx *OC_SinglePartQueryContext) {} + +// EnterOC_MultiPartQuery is called when production oC_MultiPartQuery is entered. +func (s *BaseCypherListener) EnterOC_MultiPartQuery(ctx *OC_MultiPartQueryContext) {} + +// ExitOC_MultiPartQuery is called when production oC_MultiPartQuery is exited. +func (s *BaseCypherListener) ExitOC_MultiPartQuery(ctx *OC_MultiPartQueryContext) {} + +// EnterOC_UpdatingClause is called when production oC_UpdatingClause is entered. +func (s *BaseCypherListener) EnterOC_UpdatingClause(ctx *OC_UpdatingClauseContext) {} + +// ExitOC_UpdatingClause is called when production oC_UpdatingClause is exited. +func (s *BaseCypherListener) ExitOC_UpdatingClause(ctx *OC_UpdatingClauseContext) {} + +// EnterOC_ReadingClause is called when production oC_ReadingClause is entered. +func (s *BaseCypherListener) EnterOC_ReadingClause(ctx *OC_ReadingClauseContext) {} + +// ExitOC_ReadingClause is called when production oC_ReadingClause is exited. +func (s *BaseCypherListener) ExitOC_ReadingClause(ctx *OC_ReadingClauseContext) {} + +// EnterOC_Match is called when production oC_Match is entered. +func (s *BaseCypherListener) EnterOC_Match(ctx *OC_MatchContext) {} + +// ExitOC_Match is called when production oC_Match is exited. +func (s *BaseCypherListener) ExitOC_Match(ctx *OC_MatchContext) {} + +// EnterOC_Unwind is called when production oC_Unwind is entered. +func (s *BaseCypherListener) EnterOC_Unwind(ctx *OC_UnwindContext) {} + +// ExitOC_Unwind is called when production oC_Unwind is exited. +func (s *BaseCypherListener) ExitOC_Unwind(ctx *OC_UnwindContext) {} + +// EnterOC_Merge is called when production oC_Merge is entered. +func (s *BaseCypherListener) EnterOC_Merge(ctx *OC_MergeContext) {} + +// ExitOC_Merge is called when production oC_Merge is exited. +func (s *BaseCypherListener) ExitOC_Merge(ctx *OC_MergeContext) {} + +// EnterOC_MergeAction is called when production oC_MergeAction is entered. +func (s *BaseCypherListener) EnterOC_MergeAction(ctx *OC_MergeActionContext) {} + +// ExitOC_MergeAction is called when production oC_MergeAction is exited. +func (s *BaseCypherListener) ExitOC_MergeAction(ctx *OC_MergeActionContext) {} + +// EnterOC_Create is called when production oC_Create is entered. +func (s *BaseCypherListener) EnterOC_Create(ctx *OC_CreateContext) {} + +// ExitOC_Create is called when production oC_Create is exited. +func (s *BaseCypherListener) ExitOC_Create(ctx *OC_CreateContext) {} + +// EnterOC_Set is called when production oC_Set is entered. +func (s *BaseCypherListener) EnterOC_Set(ctx *OC_SetContext) {} + +// ExitOC_Set is called when production oC_Set is exited. +func (s *BaseCypherListener) ExitOC_Set(ctx *OC_SetContext) {} + +// EnterOC_SetItem is called when production oC_SetItem is entered. +func (s *BaseCypherListener) EnterOC_SetItem(ctx *OC_SetItemContext) {} + +// ExitOC_SetItem is called when production oC_SetItem is exited. +func (s *BaseCypherListener) ExitOC_SetItem(ctx *OC_SetItemContext) {} + +// EnterOC_Delete is called when production oC_Delete is entered. +func (s *BaseCypherListener) EnterOC_Delete(ctx *OC_DeleteContext) {} + +// ExitOC_Delete is called when production oC_Delete is exited. +func (s *BaseCypherListener) ExitOC_Delete(ctx *OC_DeleteContext) {} + +// EnterOC_Remove is called when production oC_Remove is entered. +func (s *BaseCypherListener) EnterOC_Remove(ctx *OC_RemoveContext) {} + +// ExitOC_Remove is called when production oC_Remove is exited. +func (s *BaseCypherListener) ExitOC_Remove(ctx *OC_RemoveContext) {} + +// EnterOC_RemoveItem is called when production oC_RemoveItem is entered. +func (s *BaseCypherListener) EnterOC_RemoveItem(ctx *OC_RemoveItemContext) {} + +// ExitOC_RemoveItem is called when production oC_RemoveItem is exited. +func (s *BaseCypherListener) ExitOC_RemoveItem(ctx *OC_RemoveItemContext) {} + +// EnterOC_InQueryCall is called when production oC_InQueryCall is entered. +func (s *BaseCypherListener) EnterOC_InQueryCall(ctx *OC_InQueryCallContext) {} + +// ExitOC_InQueryCall is called when production oC_InQueryCall is exited. +func (s *BaseCypherListener) ExitOC_InQueryCall(ctx *OC_InQueryCallContext) {} + +// EnterOC_StandaloneCall is called when production oC_StandaloneCall is entered. +func (s *BaseCypherListener) EnterOC_StandaloneCall(ctx *OC_StandaloneCallContext) {} + +// ExitOC_StandaloneCall is called when production oC_StandaloneCall is exited. +func (s *BaseCypherListener) ExitOC_StandaloneCall(ctx *OC_StandaloneCallContext) {} + +// EnterOC_YieldItems is called when production oC_YieldItems is entered. +func (s *BaseCypherListener) EnterOC_YieldItems(ctx *OC_YieldItemsContext) {} + +// ExitOC_YieldItems is called when production oC_YieldItems is exited. +func (s *BaseCypherListener) ExitOC_YieldItems(ctx *OC_YieldItemsContext) {} + +// EnterOC_YieldItem is called when production oC_YieldItem is entered. +func (s *BaseCypherListener) EnterOC_YieldItem(ctx *OC_YieldItemContext) {} + +// ExitOC_YieldItem is called when production oC_YieldItem is exited. +func (s *BaseCypherListener) ExitOC_YieldItem(ctx *OC_YieldItemContext) {} + +// EnterOC_With is called when production oC_With is entered. +func (s *BaseCypherListener) EnterOC_With(ctx *OC_WithContext) {} + +// ExitOC_With is called when production oC_With is exited. +func (s *BaseCypherListener) ExitOC_With(ctx *OC_WithContext) {} + +// EnterOC_Return is called when production oC_Return is entered. +func (s *BaseCypherListener) EnterOC_Return(ctx *OC_ReturnContext) {} + +// ExitOC_Return is called when production oC_Return is exited. +func (s *BaseCypherListener) ExitOC_Return(ctx *OC_ReturnContext) {} + +// EnterOC_ProjectionBody is called when production oC_ProjectionBody is entered. +func (s *BaseCypherListener) EnterOC_ProjectionBody(ctx *OC_ProjectionBodyContext) {} + +// ExitOC_ProjectionBody is called when production oC_ProjectionBody is exited. +func (s *BaseCypherListener) ExitOC_ProjectionBody(ctx *OC_ProjectionBodyContext) {} + +// EnterOC_ProjectionItems is called when production oC_ProjectionItems is entered. +func (s *BaseCypherListener) EnterOC_ProjectionItems(ctx *OC_ProjectionItemsContext) {} + +// ExitOC_ProjectionItems is called when production oC_ProjectionItems is exited. +func (s *BaseCypherListener) ExitOC_ProjectionItems(ctx *OC_ProjectionItemsContext) {} + +// EnterOC_ProjectionItem is called when production oC_ProjectionItem is entered. +func (s *BaseCypherListener) EnterOC_ProjectionItem(ctx *OC_ProjectionItemContext) {} + +// ExitOC_ProjectionItem is called when production oC_ProjectionItem is exited. +func (s *BaseCypherListener) ExitOC_ProjectionItem(ctx *OC_ProjectionItemContext) {} + +// EnterOC_Order is called when production oC_Order is entered. +func (s *BaseCypherListener) EnterOC_Order(ctx *OC_OrderContext) {} + +// ExitOC_Order is called when production oC_Order is exited. +func (s *BaseCypherListener) ExitOC_Order(ctx *OC_OrderContext) {} + +// EnterOC_Skip is called when production oC_Skip is entered. +func (s *BaseCypherListener) EnterOC_Skip(ctx *OC_SkipContext) {} + +// ExitOC_Skip is called when production oC_Skip is exited. +func (s *BaseCypherListener) ExitOC_Skip(ctx *OC_SkipContext) {} + +// EnterOC_Limit is called when production oC_Limit is entered. +func (s *BaseCypherListener) EnterOC_Limit(ctx *OC_LimitContext) {} + +// ExitOC_Limit is called when production oC_Limit is exited. +func (s *BaseCypherListener) ExitOC_Limit(ctx *OC_LimitContext) {} + +// EnterOC_SortItem is called when production oC_SortItem is entered. +func (s *BaseCypherListener) EnterOC_SortItem(ctx *OC_SortItemContext) {} + +// ExitOC_SortItem is called when production oC_SortItem is exited. +func (s *BaseCypherListener) ExitOC_SortItem(ctx *OC_SortItemContext) {} + +// EnterOC_Where is called when production oC_Where is entered. +func (s *BaseCypherListener) EnterOC_Where(ctx *OC_WhereContext) {} + +// ExitOC_Where is called when production oC_Where is exited. +func (s *BaseCypherListener) ExitOC_Where(ctx *OC_WhereContext) {} + +// EnterOC_Pattern is called when production oC_Pattern is entered. +func (s *BaseCypherListener) EnterOC_Pattern(ctx *OC_PatternContext) {} + +// ExitOC_Pattern is called when production oC_Pattern is exited. +func (s *BaseCypherListener) ExitOC_Pattern(ctx *OC_PatternContext) {} + +// EnterOC_PatternPart is called when production oC_PatternPart is entered. +func (s *BaseCypherListener) EnterOC_PatternPart(ctx *OC_PatternPartContext) {} + +// ExitOC_PatternPart is called when production oC_PatternPart is exited. +func (s *BaseCypherListener) ExitOC_PatternPart(ctx *OC_PatternPartContext) {} + +// EnterOC_AnonymousPatternPart is called when production oC_AnonymousPatternPart is entered. +func (s *BaseCypherListener) EnterOC_AnonymousPatternPart(ctx *OC_AnonymousPatternPartContext) {} + +// ExitOC_AnonymousPatternPart is called when production oC_AnonymousPatternPart is exited. +func (s *BaseCypherListener) ExitOC_AnonymousPatternPart(ctx *OC_AnonymousPatternPartContext) {} + +// EnterOC_PatternElement is called when production oC_PatternElement is entered. +func (s *BaseCypherListener) EnterOC_PatternElement(ctx *OC_PatternElementContext) {} + +// ExitOC_PatternElement is called when production oC_PatternElement is exited. +func (s *BaseCypherListener) ExitOC_PatternElement(ctx *OC_PatternElementContext) {} + +// EnterOC_NodePattern is called when production oC_NodePattern is entered. +func (s *BaseCypherListener) EnterOC_NodePattern(ctx *OC_NodePatternContext) {} + +// ExitOC_NodePattern is called when production oC_NodePattern is exited. +func (s *BaseCypherListener) ExitOC_NodePattern(ctx *OC_NodePatternContext) {} + +// EnterOC_PatternElementChain is called when production oC_PatternElementChain is entered. +func (s *BaseCypherListener) EnterOC_PatternElementChain(ctx *OC_PatternElementChainContext) {} + +// ExitOC_PatternElementChain is called when production oC_PatternElementChain is exited. +func (s *BaseCypherListener) ExitOC_PatternElementChain(ctx *OC_PatternElementChainContext) {} + +// EnterOC_RelationshipPattern is called when production oC_RelationshipPattern is entered. +func (s *BaseCypherListener) EnterOC_RelationshipPattern(ctx *OC_RelationshipPatternContext) {} + +// ExitOC_RelationshipPattern is called when production oC_RelationshipPattern is exited. +func (s *BaseCypherListener) ExitOC_RelationshipPattern(ctx *OC_RelationshipPatternContext) {} + +// EnterOC_RelationshipDetail is called when production oC_RelationshipDetail is entered. +func (s *BaseCypherListener) EnterOC_RelationshipDetail(ctx *OC_RelationshipDetailContext) {} + +// ExitOC_RelationshipDetail is called when production oC_RelationshipDetail is exited. +func (s *BaseCypherListener) ExitOC_RelationshipDetail(ctx *OC_RelationshipDetailContext) {} + +// EnterOC_Properties is called when production oC_Properties is entered. +func (s *BaseCypherListener) EnterOC_Properties(ctx *OC_PropertiesContext) {} + +// ExitOC_Properties is called when production oC_Properties is exited. +func (s *BaseCypherListener) ExitOC_Properties(ctx *OC_PropertiesContext) {} + +// EnterOC_RelationshipTypes is called when production oC_RelationshipTypes is entered. +func (s *BaseCypherListener) EnterOC_RelationshipTypes(ctx *OC_RelationshipTypesContext) {} + +// ExitOC_RelationshipTypes is called when production oC_RelationshipTypes is exited. +func (s *BaseCypherListener) ExitOC_RelationshipTypes(ctx *OC_RelationshipTypesContext) {} + +// EnterOC_NodeLabels is called when production oC_NodeLabels is entered. +func (s *BaseCypherListener) EnterOC_NodeLabels(ctx *OC_NodeLabelsContext) {} + +// ExitOC_NodeLabels is called when production oC_NodeLabels is exited. +func (s *BaseCypherListener) ExitOC_NodeLabels(ctx *OC_NodeLabelsContext) {} + +// EnterOC_NodeLabel is called when production oC_NodeLabel is entered. +func (s *BaseCypherListener) EnterOC_NodeLabel(ctx *OC_NodeLabelContext) {} + +// ExitOC_NodeLabel is called when production oC_NodeLabel is exited. +func (s *BaseCypherListener) ExitOC_NodeLabel(ctx *OC_NodeLabelContext) {} + +// EnterOC_RangeLiteral is called when production oC_RangeLiteral is entered. +func (s *BaseCypherListener) EnterOC_RangeLiteral(ctx *OC_RangeLiteralContext) {} + +// ExitOC_RangeLiteral is called when production oC_RangeLiteral is exited. +func (s *BaseCypherListener) ExitOC_RangeLiteral(ctx *OC_RangeLiteralContext) {} + +// EnterOC_LabelName is called when production oC_LabelName is entered. +func (s *BaseCypherListener) EnterOC_LabelName(ctx *OC_LabelNameContext) {} + +// ExitOC_LabelName is called when production oC_LabelName is exited. +func (s *BaseCypherListener) ExitOC_LabelName(ctx *OC_LabelNameContext) {} + +// EnterOC_RelTypeName is called when production oC_RelTypeName is entered. +func (s *BaseCypherListener) EnterOC_RelTypeName(ctx *OC_RelTypeNameContext) {} + +// ExitOC_RelTypeName is called when production oC_RelTypeName is exited. +func (s *BaseCypherListener) ExitOC_RelTypeName(ctx *OC_RelTypeNameContext) {} + +// EnterOC_Expression is called when production oC_Expression is entered. +func (s *BaseCypherListener) EnterOC_Expression(ctx *OC_ExpressionContext) {} + +// ExitOC_Expression is called when production oC_Expression is exited. +func (s *BaseCypherListener) ExitOC_Expression(ctx *OC_ExpressionContext) {} + +// EnterOC_OrExpression is called when production oC_OrExpression is entered. +func (s *BaseCypherListener) EnterOC_OrExpression(ctx *OC_OrExpressionContext) {} + +// ExitOC_OrExpression is called when production oC_OrExpression is exited. +func (s *BaseCypherListener) ExitOC_OrExpression(ctx *OC_OrExpressionContext) {} + +// EnterOC_XorExpression is called when production oC_XorExpression is entered. +func (s *BaseCypherListener) EnterOC_XorExpression(ctx *OC_XorExpressionContext) {} + +// ExitOC_XorExpression is called when production oC_XorExpression is exited. +func (s *BaseCypherListener) ExitOC_XorExpression(ctx *OC_XorExpressionContext) {} + +// EnterOC_AndExpression is called when production oC_AndExpression is entered. +func (s *BaseCypherListener) EnterOC_AndExpression(ctx *OC_AndExpressionContext) {} + +// ExitOC_AndExpression is called when production oC_AndExpression is exited. +func (s *BaseCypherListener) ExitOC_AndExpression(ctx *OC_AndExpressionContext) {} + +// EnterOC_NotExpression is called when production oC_NotExpression is entered. +func (s *BaseCypherListener) EnterOC_NotExpression(ctx *OC_NotExpressionContext) {} + +// ExitOC_NotExpression is called when production oC_NotExpression is exited. +func (s *BaseCypherListener) ExitOC_NotExpression(ctx *OC_NotExpressionContext) {} + +// EnterOC_ComparisonExpression is called when production oC_ComparisonExpression is entered. +func (s *BaseCypherListener) EnterOC_ComparisonExpression(ctx *OC_ComparisonExpressionContext) {} + +// ExitOC_ComparisonExpression is called when production oC_ComparisonExpression is exited. +func (s *BaseCypherListener) ExitOC_ComparisonExpression(ctx *OC_ComparisonExpressionContext) {} + +// EnterOC_AddOrSubtractExpression is called when production oC_AddOrSubtractExpression is entered. +func (s *BaseCypherListener) EnterOC_AddOrSubtractExpression(ctx *OC_AddOrSubtractExpressionContext) { +} + +// ExitOC_AddOrSubtractExpression is called when production oC_AddOrSubtractExpression is exited. +func (s *BaseCypherListener) ExitOC_AddOrSubtractExpression(ctx *OC_AddOrSubtractExpressionContext) {} + +// EnterOC_MultiplyDivideModuloExpression is called when production oC_MultiplyDivideModuloExpression is entered. +func (s *BaseCypherListener) EnterOC_MultiplyDivideModuloExpression(ctx *OC_MultiplyDivideModuloExpressionContext) { +} + +// ExitOC_MultiplyDivideModuloExpression is called when production oC_MultiplyDivideModuloExpression is exited. +func (s *BaseCypherListener) ExitOC_MultiplyDivideModuloExpression(ctx *OC_MultiplyDivideModuloExpressionContext) { +} + +// EnterOC_PowerOfExpression is called when production oC_PowerOfExpression is entered. +func (s *BaseCypherListener) EnterOC_PowerOfExpression(ctx *OC_PowerOfExpressionContext) {} + +// ExitOC_PowerOfExpression is called when production oC_PowerOfExpression is exited. +func (s *BaseCypherListener) ExitOC_PowerOfExpression(ctx *OC_PowerOfExpressionContext) {} + +// EnterOC_UnaryAddOrSubtractExpression is called when production oC_UnaryAddOrSubtractExpression is entered. +func (s *BaseCypherListener) EnterOC_UnaryAddOrSubtractExpression(ctx *OC_UnaryAddOrSubtractExpressionContext) { +} + +// ExitOC_UnaryAddOrSubtractExpression is called when production oC_UnaryAddOrSubtractExpression is exited. +func (s *BaseCypherListener) ExitOC_UnaryAddOrSubtractExpression(ctx *OC_UnaryAddOrSubtractExpressionContext) { +} + +// EnterOC_StringListNullOperatorExpression is called when production oC_StringListNullOperatorExpression is entered. +func (s *BaseCypherListener) EnterOC_StringListNullOperatorExpression(ctx *OC_StringListNullOperatorExpressionContext) { +} + +// ExitOC_StringListNullOperatorExpression is called when production oC_StringListNullOperatorExpression is exited. +func (s *BaseCypherListener) ExitOC_StringListNullOperatorExpression(ctx *OC_StringListNullOperatorExpressionContext) { +} + +// EnterOC_ListOperatorExpression is called when production oC_ListOperatorExpression is entered. +func (s *BaseCypherListener) EnterOC_ListOperatorExpression(ctx *OC_ListOperatorExpressionContext) {} + +// ExitOC_ListOperatorExpression is called when production oC_ListOperatorExpression is exited. +func (s *BaseCypherListener) ExitOC_ListOperatorExpression(ctx *OC_ListOperatorExpressionContext) {} + +// EnterOC_StringOperatorExpression is called when production oC_StringOperatorExpression is entered. +func (s *BaseCypherListener) EnterOC_StringOperatorExpression(ctx *OC_StringOperatorExpressionContext) { +} + +// ExitOC_StringOperatorExpression is called when production oC_StringOperatorExpression is exited. +func (s *BaseCypherListener) ExitOC_StringOperatorExpression(ctx *OC_StringOperatorExpressionContext) { +} + +// EnterOC_NullOperatorExpression is called when production oC_NullOperatorExpression is entered. +func (s *BaseCypherListener) EnterOC_NullOperatorExpression(ctx *OC_NullOperatorExpressionContext) {} + +// ExitOC_NullOperatorExpression is called when production oC_NullOperatorExpression is exited. +func (s *BaseCypherListener) ExitOC_NullOperatorExpression(ctx *OC_NullOperatorExpressionContext) {} + +// EnterOC_PropertyOrLabelsExpression is called when production oC_PropertyOrLabelsExpression is entered. +func (s *BaseCypherListener) EnterOC_PropertyOrLabelsExpression(ctx *OC_PropertyOrLabelsExpressionContext) { +} + +// ExitOC_PropertyOrLabelsExpression is called when production oC_PropertyOrLabelsExpression is exited. +func (s *BaseCypherListener) ExitOC_PropertyOrLabelsExpression(ctx *OC_PropertyOrLabelsExpressionContext) { +} + +// EnterOC_Atom is called when production oC_Atom is entered. +func (s *BaseCypherListener) EnterOC_Atom(ctx *OC_AtomContext) {} + +// ExitOC_Atom is called when production oC_Atom is exited. +func (s *BaseCypherListener) ExitOC_Atom(ctx *OC_AtomContext) {} + +// EnterOC_Literal is called when production oC_Literal is entered. +func (s *BaseCypherListener) EnterOC_Literal(ctx *OC_LiteralContext) {} + +// ExitOC_Literal is called when production oC_Literal is exited. +func (s *BaseCypherListener) ExitOC_Literal(ctx *OC_LiteralContext) {} + +// EnterOC_BooleanLiteral is called when production oC_BooleanLiteral is entered. +func (s *BaseCypherListener) EnterOC_BooleanLiteral(ctx *OC_BooleanLiteralContext) {} + +// ExitOC_BooleanLiteral is called when production oC_BooleanLiteral is exited. +func (s *BaseCypherListener) ExitOC_BooleanLiteral(ctx *OC_BooleanLiteralContext) {} + +// EnterOC_ListLiteral is called when production oC_ListLiteral is entered. +func (s *BaseCypherListener) EnterOC_ListLiteral(ctx *OC_ListLiteralContext) {} + +// ExitOC_ListLiteral is called when production oC_ListLiteral is exited. +func (s *BaseCypherListener) ExitOC_ListLiteral(ctx *OC_ListLiteralContext) {} + +// EnterOC_PartialComparisonExpression is called when production oC_PartialComparisonExpression is entered. +func (s *BaseCypherListener) EnterOC_PartialComparisonExpression(ctx *OC_PartialComparisonExpressionContext) { +} + +// ExitOC_PartialComparisonExpression is called when production oC_PartialComparisonExpression is exited. +func (s *BaseCypherListener) ExitOC_PartialComparisonExpression(ctx *OC_PartialComparisonExpressionContext) { +} + +// EnterOC_ParenthesizedExpression is called when production oC_ParenthesizedExpression is entered. +func (s *BaseCypherListener) EnterOC_ParenthesizedExpression(ctx *OC_ParenthesizedExpressionContext) { +} + +// ExitOC_ParenthesizedExpression is called when production oC_ParenthesizedExpression is exited. +func (s *BaseCypherListener) ExitOC_ParenthesizedExpression(ctx *OC_ParenthesizedExpressionContext) {} + +// EnterOC_RelationshipsPattern is called when production oC_RelationshipsPattern is entered. +func (s *BaseCypherListener) EnterOC_RelationshipsPattern(ctx *OC_RelationshipsPatternContext) {} + +// ExitOC_RelationshipsPattern is called when production oC_RelationshipsPattern is exited. +func (s *BaseCypherListener) ExitOC_RelationshipsPattern(ctx *OC_RelationshipsPatternContext) {} + +// EnterOC_FilterExpression is called when production oC_FilterExpression is entered. +func (s *BaseCypherListener) EnterOC_FilterExpression(ctx *OC_FilterExpressionContext) {} + +// ExitOC_FilterExpression is called when production oC_FilterExpression is exited. +func (s *BaseCypherListener) ExitOC_FilterExpression(ctx *OC_FilterExpressionContext) {} + +// EnterOC_IdInColl is called when production oC_IdInColl is entered. +func (s *BaseCypherListener) EnterOC_IdInColl(ctx *OC_IdInCollContext) {} + +// ExitOC_IdInColl is called when production oC_IdInColl is exited. +func (s *BaseCypherListener) ExitOC_IdInColl(ctx *OC_IdInCollContext) {} + +// EnterOC_FunctionInvocation is called when production oC_FunctionInvocation is entered. +func (s *BaseCypherListener) EnterOC_FunctionInvocation(ctx *OC_FunctionInvocationContext) {} + +// ExitOC_FunctionInvocation is called when production oC_FunctionInvocation is exited. +func (s *BaseCypherListener) ExitOC_FunctionInvocation(ctx *OC_FunctionInvocationContext) {} + +// EnterOC_FunctionName is called when production oC_FunctionName is entered. +func (s *BaseCypherListener) EnterOC_FunctionName(ctx *OC_FunctionNameContext) {} + +// ExitOC_FunctionName is called when production oC_FunctionName is exited. +func (s *BaseCypherListener) ExitOC_FunctionName(ctx *OC_FunctionNameContext) {} + +// EnterOC_ExplicitProcedureInvocation is called when production oC_ExplicitProcedureInvocation is entered. +func (s *BaseCypherListener) EnterOC_ExplicitProcedureInvocation(ctx *OC_ExplicitProcedureInvocationContext) { +} + +// ExitOC_ExplicitProcedureInvocation is called when production oC_ExplicitProcedureInvocation is exited. +func (s *BaseCypherListener) ExitOC_ExplicitProcedureInvocation(ctx *OC_ExplicitProcedureInvocationContext) { +} + +// EnterOC_ImplicitProcedureInvocation is called when production oC_ImplicitProcedureInvocation is entered. +func (s *BaseCypherListener) EnterOC_ImplicitProcedureInvocation(ctx *OC_ImplicitProcedureInvocationContext) { +} + +// ExitOC_ImplicitProcedureInvocation is called when production oC_ImplicitProcedureInvocation is exited. +func (s *BaseCypherListener) ExitOC_ImplicitProcedureInvocation(ctx *OC_ImplicitProcedureInvocationContext) { +} + +// EnterOC_ProcedureResultField is called when production oC_ProcedureResultField is entered. +func (s *BaseCypherListener) EnterOC_ProcedureResultField(ctx *OC_ProcedureResultFieldContext) {} + +// ExitOC_ProcedureResultField is called when production oC_ProcedureResultField is exited. +func (s *BaseCypherListener) ExitOC_ProcedureResultField(ctx *OC_ProcedureResultFieldContext) {} + +// EnterOC_ProcedureName is called when production oC_ProcedureName is entered. +func (s *BaseCypherListener) EnterOC_ProcedureName(ctx *OC_ProcedureNameContext) {} + +// ExitOC_ProcedureName is called when production oC_ProcedureName is exited. +func (s *BaseCypherListener) ExitOC_ProcedureName(ctx *OC_ProcedureNameContext) {} + +// EnterOC_Namespace is called when production oC_Namespace is entered. +func (s *BaseCypherListener) EnterOC_Namespace(ctx *OC_NamespaceContext) {} + +// ExitOC_Namespace is called when production oC_Namespace is exited. +func (s *BaseCypherListener) ExitOC_Namespace(ctx *OC_NamespaceContext) {} + +// EnterOC_ListComprehension is called when production oC_ListComprehension is entered. +func (s *BaseCypherListener) EnterOC_ListComprehension(ctx *OC_ListComprehensionContext) {} + +// ExitOC_ListComprehension is called when production oC_ListComprehension is exited. +func (s *BaseCypherListener) ExitOC_ListComprehension(ctx *OC_ListComprehensionContext) {} + +// EnterOC_PatternComprehension is called when production oC_PatternComprehension is entered. +func (s *BaseCypherListener) EnterOC_PatternComprehension(ctx *OC_PatternComprehensionContext) {} + +// ExitOC_PatternComprehension is called when production oC_PatternComprehension is exited. +func (s *BaseCypherListener) ExitOC_PatternComprehension(ctx *OC_PatternComprehensionContext) {} + +// EnterOC_PropertyLookup is called when production oC_PropertyLookup is entered. +func (s *BaseCypherListener) EnterOC_PropertyLookup(ctx *OC_PropertyLookupContext) {} + +// ExitOC_PropertyLookup is called when production oC_PropertyLookup is exited. +func (s *BaseCypherListener) ExitOC_PropertyLookup(ctx *OC_PropertyLookupContext) {} + +// EnterOC_CaseExpression is called when production oC_CaseExpression is entered. +func (s *BaseCypherListener) EnterOC_CaseExpression(ctx *OC_CaseExpressionContext) {} + +// ExitOC_CaseExpression is called when production oC_CaseExpression is exited. +func (s *BaseCypherListener) ExitOC_CaseExpression(ctx *OC_CaseExpressionContext) {} + +// EnterOC_CaseAlternatives is called when production oC_CaseAlternatives is entered. +func (s *BaseCypherListener) EnterOC_CaseAlternatives(ctx *OC_CaseAlternativesContext) {} + +// ExitOC_CaseAlternatives is called when production oC_CaseAlternatives is exited. +func (s *BaseCypherListener) ExitOC_CaseAlternatives(ctx *OC_CaseAlternativesContext) {} + +// EnterOC_Variable is called when production oC_Variable is entered. +func (s *BaseCypherListener) EnterOC_Variable(ctx *OC_VariableContext) {} + +// ExitOC_Variable is called when production oC_Variable is exited. +func (s *BaseCypherListener) ExitOC_Variable(ctx *OC_VariableContext) {} + +// EnterOC_NumberLiteral is called when production oC_NumberLiteral is entered. +func (s *BaseCypherListener) EnterOC_NumberLiteral(ctx *OC_NumberLiteralContext) {} + +// ExitOC_NumberLiteral is called when production oC_NumberLiteral is exited. +func (s *BaseCypherListener) ExitOC_NumberLiteral(ctx *OC_NumberLiteralContext) {} + +// EnterOC_MapLiteral is called when production oC_MapLiteral is entered. +func (s *BaseCypherListener) EnterOC_MapLiteral(ctx *OC_MapLiteralContext) {} + +// ExitOC_MapLiteral is called when production oC_MapLiteral is exited. +func (s *BaseCypherListener) ExitOC_MapLiteral(ctx *OC_MapLiteralContext) {} + +// EnterOC_Parameter is called when production oC_Parameter is entered. +func (s *BaseCypherListener) EnterOC_Parameter(ctx *OC_ParameterContext) {} + +// ExitOC_Parameter is called when production oC_Parameter is exited. +func (s *BaseCypherListener) ExitOC_Parameter(ctx *OC_ParameterContext) {} + +// EnterOC_PropertyExpression is called when production oC_PropertyExpression is entered. +func (s *BaseCypherListener) EnterOC_PropertyExpression(ctx *OC_PropertyExpressionContext) {} + +// ExitOC_PropertyExpression is called when production oC_PropertyExpression is exited. +func (s *BaseCypherListener) ExitOC_PropertyExpression(ctx *OC_PropertyExpressionContext) {} + +// EnterOC_PropertyKeyName is called when production oC_PropertyKeyName is entered. +func (s *BaseCypherListener) EnterOC_PropertyKeyName(ctx *OC_PropertyKeyNameContext) {} + +// ExitOC_PropertyKeyName is called when production oC_PropertyKeyName is exited. +func (s *BaseCypherListener) ExitOC_PropertyKeyName(ctx *OC_PropertyKeyNameContext) {} + +// EnterOC_IntegerLiteral is called when production oC_IntegerLiteral is entered. +func (s *BaseCypherListener) EnterOC_IntegerLiteral(ctx *OC_IntegerLiteralContext) {} + +// ExitOC_IntegerLiteral is called when production oC_IntegerLiteral is exited. +func (s *BaseCypherListener) ExitOC_IntegerLiteral(ctx *OC_IntegerLiteralContext) {} + +// EnterOC_DoubleLiteral is called when production oC_DoubleLiteral is entered. +func (s *BaseCypherListener) EnterOC_DoubleLiteral(ctx *OC_DoubleLiteralContext) {} + +// ExitOC_DoubleLiteral is called when production oC_DoubleLiteral is exited. +func (s *BaseCypherListener) ExitOC_DoubleLiteral(ctx *OC_DoubleLiteralContext) {} + +// EnterOC_SchemaName is called when production oC_SchemaName is entered. +func (s *BaseCypherListener) EnterOC_SchemaName(ctx *OC_SchemaNameContext) {} + +// ExitOC_SchemaName is called when production oC_SchemaName is exited. +func (s *BaseCypherListener) ExitOC_SchemaName(ctx *OC_SchemaNameContext) {} + +// EnterOC_ReservedWord is called when production oC_ReservedWord is entered. +func (s *BaseCypherListener) EnterOC_ReservedWord(ctx *OC_ReservedWordContext) {} + +// ExitOC_ReservedWord is called when production oC_ReservedWord is exited. +func (s *BaseCypherListener) ExitOC_ReservedWord(ctx *OC_ReservedWordContext) {} + +// EnterOC_SymbolicName is called when production oC_SymbolicName is entered. +func (s *BaseCypherListener) EnterOC_SymbolicName(ctx *OC_SymbolicNameContext) {} + +// ExitOC_SymbolicName is called when production oC_SymbolicName is exited. +func (s *BaseCypherListener) ExitOC_SymbolicName(ctx *OC_SymbolicNameContext) {} + +// EnterOC_LeftArrowHead is called when production oC_LeftArrowHead is entered. +func (s *BaseCypherListener) EnterOC_LeftArrowHead(ctx *OC_LeftArrowHeadContext) {} + +// ExitOC_LeftArrowHead is called when production oC_LeftArrowHead is exited. +func (s *BaseCypherListener) ExitOC_LeftArrowHead(ctx *OC_LeftArrowHeadContext) {} + +// EnterOC_RightArrowHead is called when production oC_RightArrowHead is entered. +func (s *BaseCypherListener) EnterOC_RightArrowHead(ctx *OC_RightArrowHeadContext) {} + +// ExitOC_RightArrowHead is called when production oC_RightArrowHead is exited. +func (s *BaseCypherListener) ExitOC_RightArrowHead(ctx *OC_RightArrowHeadContext) {} + +// EnterOC_Dash is called when production oC_Dash is entered. +func (s *BaseCypherListener) EnterOC_Dash(ctx *OC_DashContext) {} + +// ExitOC_Dash is called when production oC_Dash is exited. +func (s *BaseCypherListener) ExitOC_Dash(ctx *OC_DashContext) {} diff --git a/parser/cypher_lexer.go b/parser/cypher_lexer.go new file mode 100644 index 0000000..2e99816 --- /dev/null +++ b/parser/cypher_lexer.go @@ -0,0 +1,1024 @@ +// Code generated from Cypher.g4 by ANTLR 4.9. DO NOT EDIT. + +package parser + +import ( + "fmt" + "unicode" + + "github.com/antlr/antlr4/runtime/Go/antlr" +) + +// Suppress unused import error +var _ = fmt.Printf +var _ = unicode.IsLetter + +var serializedLexerAtn = []uint16{ + 3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 129, 993, + 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, + 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, + 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, + 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, + 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, + 28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9, 32, 4, 33, 9, 33, + 4, 34, 9, 34, 4, 35, 9, 35, 4, 36, 9, 36, 4, 37, 9, 37, 4, 38, 9, 38, 4, + 39, 9, 39, 4, 40, 9, 40, 4, 41, 9, 41, 4, 42, 9, 42, 4, 43, 9, 43, 4, 44, + 9, 44, 4, 45, 9, 45, 4, 46, 9, 46, 4, 47, 9, 47, 4, 48, 9, 48, 4, 49, 9, + 49, 4, 50, 9, 50, 4, 51, 9, 51, 4, 52, 9, 52, 4, 53, 9, 53, 4, 54, 9, 54, + 4, 55, 9, 55, 4, 56, 9, 56, 4, 57, 9, 57, 4, 58, 9, 58, 4, 59, 9, 59, 4, + 60, 9, 60, 4, 61, 9, 61, 4, 62, 9, 62, 4, 63, 9, 63, 4, 64, 9, 64, 4, 65, + 9, 65, 4, 66, 9, 66, 4, 67, 9, 67, 4, 68, 9, 68, 4, 69, 9, 69, 4, 70, 9, + 70, 4, 71, 9, 71, 4, 72, 9, 72, 4, 73, 9, 73, 4, 74, 9, 74, 4, 75, 9, 75, + 4, 76, 9, 76, 4, 77, 9, 77, 4, 78, 9, 78, 4, 79, 9, 79, 4, 80, 9, 80, 4, + 81, 9, 81, 4, 82, 9, 82, 4, 83, 9, 83, 4, 84, 9, 84, 4, 85, 9, 85, 4, 86, + 9, 86, 4, 87, 9, 87, 4, 88, 9, 88, 4, 89, 9, 89, 4, 90, 9, 90, 4, 91, 9, + 91, 4, 92, 9, 92, 4, 93, 9, 93, 4, 94, 9, 94, 4, 95, 9, 95, 4, 96, 9, 96, + 4, 97, 9, 97, 4, 98, 9, 98, 4, 99, 9, 99, 4, 100, 9, 100, 4, 101, 9, 101, + 4, 102, 9, 102, 4, 103, 9, 103, 4, 104, 9, 104, 4, 105, 9, 105, 4, 106, + 9, 106, 4, 107, 9, 107, 4, 108, 9, 108, 4, 109, 9, 109, 4, 110, 9, 110, + 4, 111, 9, 111, 4, 112, 9, 112, 4, 113, 9, 113, 4, 114, 9, 114, 4, 115, + 9, 115, 4, 116, 9, 116, 4, 117, 9, 117, 4, 118, 9, 118, 4, 119, 9, 119, + 4, 120, 9, 120, 4, 121, 9, 121, 4, 122, 9, 122, 4, 123, 9, 123, 4, 124, + 9, 124, 4, 125, 9, 125, 4, 126, 9, 126, 4, 127, 9, 127, 4, 128, 9, 128, + 4, 129, 9, 129, 4, 130, 9, 130, 4, 131, 9, 131, 4, 132, 9, 132, 4, 133, + 9, 133, 4, 134, 9, 134, 4, 135, 9, 135, 4, 136, 9, 136, 4, 137, 9, 137, + 4, 138, 9, 138, 4, 139, 9, 139, 4, 140, 9, 140, 4, 141, 9, 141, 4, 142, + 9, 142, 4, 143, 9, 143, 4, 144, 9, 144, 4, 145, 9, 145, 4, 146, 9, 146, + 4, 147, 9, 147, 4, 148, 9, 148, 3, 2, 3, 2, 3, 3, 3, 3, 3, 4, 3, 4, 3, + 5, 3, 5, 3, 5, 3, 6, 3, 6, 3, 7, 3, 7, 3, 8, 3, 8, 3, 9, 3, 9, 3, 10, 3, + 10, 3, 11, 3, 11, 3, 12, 3, 12, 3, 13, 3, 13, 3, 13, 3, 14, 3, 14, 3, 15, + 3, 15, 3, 16, 3, 16, 3, 17, 3, 17, 3, 18, 3, 18, 3, 19, 3, 19, 3, 19, 3, + 20, 3, 20, 3, 21, 3, 21, 3, 22, 3, 22, 3, 22, 3, 23, 3, 23, 3, 23, 3, 24, + 3, 24, 3, 25, 3, 25, 3, 26, 3, 26, 3, 27, 3, 27, 3, 28, 3, 28, 3, 29, 3, + 29, 3, 30, 3, 30, 3, 31, 3, 31, 3, 32, 3, 32, 3, 33, 3, 33, 3, 34, 3, 34, + 3, 35, 3, 35, 3, 36, 3, 36, 3, 37, 3, 37, 3, 38, 3, 38, 3, 39, 3, 39, 3, + 40, 3, 40, 3, 41, 3, 41, 3, 42, 3, 42, 3, 43, 3, 43, 3, 44, 3, 44, 3, 45, + 3, 45, 3, 46, 3, 46, 3, 47, 3, 47, 3, 47, 3, 47, 3, 47, 3, 47, 3, 48, 3, + 48, 3, 48, 3, 48, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, + 3, 49, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 51, 3, 51, 3, 51, 3, + 51, 3, 51, 3, 51, 3, 51, 3, 52, 3, 52, 3, 52, 3, 53, 3, 53, 3, 53, 3, 53, + 3, 53, 3, 53, 3, 54, 3, 54, 3, 54, 3, 55, 3, 55, 3, 55, 3, 55, 3, 55, 3, + 55, 3, 55, 3, 56, 3, 56, 3, 56, 3, 56, 3, 57, 3, 57, 3, 57, 3, 57, 3, 57, + 3, 57, 3, 57, 3, 58, 3, 58, 3, 58, 3, 58, 3, 58, 3, 58, 3, 58, 3, 59, 3, + 59, 3, 59, 3, 59, 3, 59, 3, 59, 3, 59, 3, 60, 3, 60, 3, 60, 3, 60, 3, 60, + 3, 61, 3, 61, 3, 61, 3, 61, 3, 61, 3, 61, 3, 62, 3, 62, 3, 62, 3, 62, 3, + 62, 3, 63, 3, 63, 3, 63, 3, 63, 3, 63, 3, 63, 3, 63, 3, 64, 3, 64, 3, 64, + 3, 64, 3, 64, 3, 64, 3, 64, 3, 64, 3, 64, 3, 65, 3, 65, 3, 65, 3, 65, 3, + 65, 3, 65, 3, 66, 3, 66, 3, 66, 3, 67, 3, 67, 3, 67, 3, 67, 3, 67, 3, 68, + 3, 68, 3, 68, 3, 68, 3, 68, 3, 68, 3, 69, 3, 69, 3, 69, 3, 69, 3, 69, 3, + 69, 3, 69, 3, 69, 3, 69, 3, 69, 3, 70, 3, 70, 3, 70, 3, 70, 3, 71, 3, 71, + 3, 71, 3, 71, 3, 71, 3, 71, 3, 71, 3, 71, 3, 71, 3, 71, 3, 71, 3, 72, 3, + 72, 3, 72, 3, 72, 3, 72, 3, 73, 3, 73, 3, 73, 3, 73, 3, 73, 3, 73, 3, 74, + 3, 74, 3, 74, 3, 75, 3, 75, 3, 75, 3, 75, 3, 76, 3, 76, 3, 76, 3, 76, 3, + 77, 3, 77, 3, 77, 3, 77, 3, 78, 3, 78, 3, 78, 3, 79, 3, 79, 3, 79, 3, 79, + 3, 79, 3, 79, 3, 79, 3, 80, 3, 80, 3, 80, 3, 80, 3, 80, 3, 81, 3, 81, 3, + 81, 3, 81, 3, 81, 3, 81, 3, 81, 3, 81, 3, 81, 3, 82, 3, 82, 3, 82, 3, 83, + 3, 83, 3, 83, 3, 83, 3, 83, 3, 84, 3, 84, 3, 84, 3, 84, 3, 84, 3, 84, 3, + 85, 3, 85, 3, 85, 3, 85, 3, 86, 3, 86, 3, 86, 3, 86, 3, 86, 3, 87, 3, 87, + 3, 87, 3, 87, 3, 87, 3, 87, 3, 87, 3, 88, 3, 88, 3, 88, 3, 88, 3, 88, 3, + 89, 3, 89, 3, 89, 3, 89, 3, 89, 3, 89, 3, 90, 3, 90, 3, 90, 3, 90, 3, 90, + 3, 90, 3, 90, 3, 91, 3, 91, 3, 91, 3, 91, 3, 91, 3, 92, 3, 92, 3, 92, 3, + 92, 3, 92, 3, 93, 3, 93, 3, 93, 3, 93, 3, 94, 3, 94, 3, 94, 3, 94, 3, 94, + 3, 95, 3, 95, 3, 95, 3, 95, 3, 95, 3, 96, 3, 96, 3, 96, 7, 96, 671, 10, + 96, 12, 96, 14, 96, 674, 11, 96, 3, 96, 3, 96, 3, 96, 3, 96, 7, 96, 680, + 10, 96, 12, 96, 14, 96, 683, 11, 96, 3, 96, 5, 96, 686, 10, 96, 3, 97, + 3, 97, 3, 97, 3, 97, 3, 97, 3, 97, 3, 97, 3, 97, 3, 97, 3, 97, 3, 97, 3, + 97, 3, 97, 3, 97, 3, 97, 3, 97, 3, 97, 3, 97, 5, 97, 706, 10, 97, 3, 98, + 3, 98, 3, 98, 3, 98, 6, 98, 712, 10, 98, 13, 98, 14, 98, 713, 3, 99, 3, + 99, 3, 99, 7, 99, 719, 10, 99, 12, 99, 14, 99, 722, 11, 99, 5, 99, 724, + 10, 99, 3, 100, 3, 100, 6, 100, 728, 10, 100, 13, 100, 14, 100, 729, 3, + 101, 5, 101, 733, 10, 101, 3, 102, 3, 102, 5, 102, 737, 10, 102, 3, 103, + 3, 103, 5, 103, 741, 10, 103, 3, 104, 3, 104, 5, 104, 745, 10, 104, 3, + 105, 3, 105, 3, 106, 3, 106, 5, 106, 751, 10, 106, 3, 107, 3, 107, 3, 108, + 6, 108, 756, 10, 108, 13, 108, 14, 108, 757, 3, 108, 6, 108, 761, 10, 108, + 13, 108, 14, 108, 762, 3, 108, 3, 108, 6, 108, 767, 10, 108, 13, 108, 14, + 108, 768, 3, 108, 3, 108, 6, 108, 773, 10, 108, 13, 108, 14, 108, 774, + 5, 108, 777, 10, 108, 3, 108, 3, 108, 5, 108, 781, 10, 108, 3, 108, 6, + 108, 784, 10, 108, 13, 108, 14, 108, 785, 3, 109, 7, 109, 789, 10, 109, + 12, 109, 14, 109, 792, 11, 109, 3, 109, 3, 109, 6, 109, 796, 10, 109, 13, + 109, 14, 109, 797, 3, 110, 3, 110, 3, 110, 3, 110, 3, 110, 3, 110, 3, 110, + 3, 110, 3, 110, 3, 110, 3, 110, 3, 111, 3, 111, 3, 111, 3, 112, 3, 112, + 3, 112, 3, 112, 3, 113, 3, 113, 3, 113, 3, 113, 3, 113, 3, 113, 3, 113, + 3, 113, 3, 114, 3, 114, 3, 114, 3, 114, 3, 114, 3, 114, 3, 114, 3, 115, + 3, 115, 3, 115, 3, 115, 3, 115, 3, 115, 3, 115, 3, 115, 3, 115, 3, 115, + 3, 116, 3, 116, 3, 116, 3, 116, 3, 116, 3, 116, 3, 116, 3, 117, 3, 117, + 3, 117, 3, 118, 3, 118, 3, 118, 3, 118, 3, 119, 3, 119, 3, 119, 3, 119, + 3, 119, 3, 120, 3, 120, 3, 120, 3, 120, 3, 120, 3, 120, 3, 120, 3, 121, + 3, 121, 3, 121, 3, 121, 3, 121, 3, 121, 3, 121, 3, 121, 3, 122, 3, 122, + 7, 122, 879, 10, 122, 12, 122, 14, 122, 882, 11, 122, 3, 123, 3, 123, 5, + 123, 886, 10, 123, 3, 124, 3, 124, 5, 124, 890, 10, 124, 3, 125, 3, 125, + 7, 125, 894, 10, 125, 12, 125, 14, 125, 897, 11, 125, 3, 125, 6, 125, 900, + 10, 125, 13, 125, 14, 125, 901, 3, 126, 6, 126, 905, 10, 126, 13, 126, + 14, 126, 906, 3, 127, 3, 127, 3, 127, 3, 127, 3, 127, 3, 127, 3, 127, 3, + 127, 3, 127, 3, 127, 3, 127, 3, 127, 5, 127, 921, 10, 127, 3, 128, 3, 128, + 3, 128, 3, 128, 3, 128, 3, 128, 7, 128, 929, 10, 128, 12, 128, 14, 128, + 932, 11, 128, 3, 128, 3, 128, 3, 128, 3, 128, 3, 128, 3, 128, 7, 128, 940, + 10, 128, 12, 128, 14, 128, 943, 11, 128, 3, 128, 5, 128, 946, 10, 128, + 3, 128, 3, 128, 5, 128, 950, 10, 128, 5, 128, 952, 10, 128, 3, 129, 3, + 129, 3, 130, 3, 130, 3, 131, 3, 131, 3, 132, 3, 132, 3, 133, 3, 133, 3, + 134, 3, 134, 3, 135, 3, 135, 3, 136, 3, 136, 3, 137, 3, 137, 3, 138, 3, + 138, 3, 139, 3, 139, 3, 140, 3, 140, 3, 141, 3, 141, 3, 142, 3, 142, 3, + 143, 3, 143, 3, 144, 3, 144, 3, 145, 3, 145, 3, 146, 3, 146, 3, 147, 3, + 147, 3, 148, 3, 148, 2, 2, 149, 3, 3, 5, 4, 7, 5, 9, 6, 11, 7, 13, 8, 15, + 9, 17, 10, 19, 11, 21, 12, 23, 13, 25, 14, 27, 15, 29, 16, 31, 17, 33, + 18, 35, 19, 37, 20, 39, 21, 41, 22, 43, 23, 45, 24, 47, 25, 49, 26, 51, + 27, 53, 28, 55, 29, 57, 30, 59, 31, 61, 32, 63, 33, 65, 34, 67, 35, 69, + 36, 71, 37, 73, 38, 75, 39, 77, 40, 79, 41, 81, 42, 83, 43, 85, 44, 87, + 45, 89, 46, 91, 47, 93, 48, 95, 49, 97, 50, 99, 51, 101, 52, 103, 53, 105, + 54, 107, 55, 109, 56, 111, 57, 113, 58, 115, 59, 117, 60, 119, 61, 121, + 62, 123, 63, 125, 64, 127, 65, 129, 66, 131, 67, 133, 68, 135, 69, 137, + 70, 139, 71, 141, 72, 143, 73, 145, 74, 147, 75, 149, 76, 151, 77, 153, + 78, 155, 79, 157, 80, 159, 81, 161, 82, 163, 83, 165, 84, 167, 85, 169, + 86, 171, 87, 173, 88, 175, 89, 177, 90, 179, 91, 181, 92, 183, 93, 185, + 94, 187, 95, 189, 96, 191, 97, 193, 98, 195, 99, 197, 100, 199, 101, 201, + 102, 203, 103, 205, 104, 207, 105, 209, 106, 211, 107, 213, 108, 215, 109, + 217, 110, 219, 111, 221, 112, 223, 113, 225, 114, 227, 115, 229, 116, 231, + 117, 233, 118, 235, 119, 237, 120, 239, 121, 241, 122, 243, 123, 245, 124, + 247, 125, 249, 126, 251, 127, 253, 128, 255, 129, 257, 2, 259, 2, 261, + 2, 263, 2, 265, 2, 267, 2, 269, 2, 271, 2, 273, 2, 275, 2, 277, 2, 279, + 2, 281, 2, 283, 2, 285, 2, 287, 2, 289, 2, 291, 2, 293, 2, 295, 2, 3, 2, + 47, 4, 2, 87, 87, 119, 119, 4, 2, 80, 80, 112, 112, 4, 2, 75, 75, 107, + 107, 4, 2, 81, 81, 113, 113, 4, 2, 67, 67, 99, 99, 4, 2, 78, 78, 110, 110, + 4, 2, 82, 82, 114, 114, 4, 2, 86, 86, 118, 118, 4, 2, 79, 79, 111, 111, + 4, 2, 69, 69, 101, 101, 4, 2, 74, 74, 106, 106, 4, 2, 89, 89, 121, 121, + 4, 2, 70, 70, 102, 102, 4, 2, 85, 85, 117, 117, 4, 2, 71, 71, 103, 103, + 4, 2, 84, 84, 116, 116, 4, 2, 73, 73, 105, 105, 4, 2, 88, 88, 120, 120, + 4, 2, 91, 91, 123, 123, 4, 2, 68, 68, 100, 100, 4, 2, 77, 77, 109, 109, + 4, 2, 90, 90, 122, 122, 4, 2, 72, 72, 104, 104, 15, 2, 36, 36, 41, 41, + 68, 68, 72, 72, 80, 80, 84, 84, 86, 86, 94, 94, 100, 100, 104, 104, 112, + 112, 116, 116, 118, 118, 4, 2, 67, 72, 99, 104, 4, 2, 83, 83, 115, 115, + 10, 2, 162, 162, 5762, 5762, 6160, 6160, 8194, 8204, 8234, 8235, 8241, + 8241, 8289, 8289, 12290, 12290, 3, 2, 14, 14, 3, 2, 98, 98, 3, 2, 32, 32, + 3, 2, 44, 44, 4, 2, 41, 41, 94, 94, 4, 2, 12, 12, 15, 15, 3, 2, 49, 49, + 3, 2, 31, 31, 3, 2, 30, 30, 3, 2, 15, 15, 19, 2, 38, 38, 164, 167, 1425, + 1425, 1549, 1549, 2548, 2549, 2557, 2557, 2803, 2803, 3067, 3067, 3649, + 3649, 6109, 6109, 8354, 8385, 43066, 43066, 65022, 65022, 65131, 65131, + 65286, 65286, 65506, 65507, 65511, 65512, 3, 2, 34, 34, 8, 2, 97, 97, 8257, + 8258, 8278, 8278, 65077, 65078, 65103, 65105, 65345, 65345, 3, 2, 11, 11, + 4, 2, 36, 36, 94, 94, 3, 2, 12, 12, 3, 2, 13, 13, 3, 2, 33, 33, 4, 691, + 2, 50, 2, 59, 2, 67, 2, 92, 2, 97, 2, 97, 2, 99, 2, 124, 2, 172, 2, 172, + 2, 183, 2, 183, 2, 185, 2, 185, 2, 188, 2, 188, 2, 194, 2, 216, 2, 218, + 2, 248, 2, 250, 2, 707, 2, 712, 2, 723, 2, 738, 2, 742, 2, 750, 2, 750, + 2, 752, 2, 752, 2, 770, 2, 886, 2, 888, 2, 889, 2, 892, 2, 895, 2, 897, + 2, 897, 2, 904, 2, 908, 2, 910, 2, 910, 2, 912, 2, 931, 2, 933, 2, 1015, + 2, 1017, 2, 1155, 2, 1157, 2, 1161, 2, 1164, 2, 1329, 2, 1331, 2, 1368, + 2, 1371, 2, 1371, 2, 1379, 2, 1417, 2, 1427, 2, 1471, 2, 1473, 2, 1473, + 2, 1475, 2, 1476, 2, 1478, 2, 1479, 2, 1481, 2, 1481, 2, 1490, 2, 1516, + 2, 1522, 2, 1524, 2, 1554, 2, 1564, 2, 1570, 2, 1643, 2, 1648, 2, 1749, + 2, 1751, 2, 1758, 2, 1761, 2, 1770, 2, 1772, 2, 1790, 2, 1793, 2, 1793, + 2, 1810, 2, 1868, 2, 1871, 2, 1971, 2, 1986, 2, 2039, 2, 2044, 2, 2044, + 2, 2050, 2, 2095, 2, 2114, 2, 2141, 2, 2146, 2, 2156, 2, 2210, 2, 2230, + 2, 2232, 2, 2239, 2, 2262, 2, 2275, 2, 2277, 2, 2405, 2, 2408, 2, 2417, + 2, 2419, 2, 2437, 2, 2439, 2, 2446, 2, 2449, 2, 2450, 2, 2453, 2, 2474, + 2, 2476, 2, 2482, 2, 2484, 2, 2484, 2, 2488, 2, 2491, 2, 2494, 2, 2502, + 2, 2505, 2, 2506, 2, 2509, 2, 2512, 2, 2521, 2, 2521, 2, 2526, 2, 2527, + 2, 2529, 2, 2533, 2, 2536, 2, 2547, 2, 2558, 2, 2558, 2, 2563, 2, 2565, + 2, 2567, 2, 2572, 2, 2577, 2, 2578, 2, 2581, 2, 2602, 2, 2604, 2, 2610, + 2, 2612, 2, 2613, 2, 2615, 2, 2616, 2, 2618, 2, 2619, 2, 2622, 2, 2622, + 2, 2624, 2, 2628, 2, 2633, 2, 2634, 2, 2637, 2, 2639, 2, 2643, 2, 2643, + 2, 2651, 2, 2654, 2, 2656, 2, 2656, 2, 2664, 2, 2679, 2, 2691, 2, 2693, + 2, 2695, 2, 2703, 2, 2705, 2, 2707, 2, 2709, 2, 2730, 2, 2732, 2, 2738, + 2, 2740, 2, 2741, 2, 2743, 2, 2747, 2, 2750, 2, 2759, 2, 2761, 2, 2763, + 2, 2765, 2, 2767, 2, 2770, 2, 2770, 2, 2786, 2, 2789, 2, 2792, 2, 2801, + 2, 2811, 2, 2817, 2, 2819, 2, 2821, 2, 2823, 2, 2830, 2, 2833, 2, 2834, + 2, 2837, 2, 2858, 2, 2860, 2, 2866, 2, 2868, 2, 2869, 2, 2871, 2, 2875, + 2, 2878, 2, 2886, 2, 2889, 2, 2890, 2, 2893, 2, 2895, 2, 2904, 2, 2905, + 2, 2910, 2, 2911, 2, 2913, 2, 2917, 2, 2920, 2, 2929, 2, 2931, 2, 2931, + 2, 2948, 2, 2949, 2, 2951, 2, 2956, 2, 2960, 2, 2962, 2, 2964, 2, 2967, + 2, 2971, 2, 2972, 2, 2974, 2, 2974, 2, 2976, 2, 2977, 2, 2981, 2, 2982, + 2, 2986, 2, 2988, 2, 2992, 2, 3003, 2, 3008, 2, 3012, 2, 3016, 2, 3018, + 2, 3020, 2, 3023, 2, 3026, 2, 3026, 2, 3033, 2, 3033, 2, 3048, 2, 3057, + 2, 3074, 2, 3077, 2, 3079, 2, 3086, 2, 3088, 2, 3090, 2, 3092, 2, 3114, + 2, 3116, 2, 3131, 2, 3135, 2, 3142, 2, 3144, 2, 3146, 2, 3148, 2, 3151, + 2, 3159, 2, 3160, 2, 3162, 2, 3164, 2, 3170, 2, 3173, 2, 3176, 2, 3185, + 2, 3202, 2, 3205, 2, 3207, 2, 3214, 2, 3216, 2, 3218, 2, 3220, 2, 3242, + 2, 3244, 2, 3253, 2, 3255, 2, 3259, 2, 3262, 2, 3270, 2, 3272, 2, 3274, + 2, 3276, 2, 3279, 2, 3287, 2, 3288, 2, 3296, 2, 3296, 2, 3298, 2, 3301, + 2, 3304, 2, 3313, 2, 3315, 2, 3316, 2, 3330, 2, 3333, 2, 3335, 2, 3342, + 2, 3344, 2, 3346, 2, 3348, 2, 3398, 2, 3400, 2, 3402, 2, 3404, 2, 3408, + 2, 3414, 2, 3417, 2, 3425, 2, 3429, 2, 3432, 2, 3441, 2, 3452, 2, 3457, + 2, 3460, 2, 3461, 2, 3463, 2, 3480, 2, 3484, 2, 3507, 2, 3509, 2, 3517, + 2, 3519, 2, 3519, 2, 3522, 2, 3528, 2, 3532, 2, 3532, 2, 3537, 2, 3542, + 2, 3544, 2, 3544, 2, 3546, 2, 3553, 2, 3560, 2, 3569, 2, 3572, 2, 3573, + 2, 3587, 2, 3644, 2, 3650, 2, 3664, 2, 3666, 2, 3675, 2, 3715, 2, 3716, + 2, 3718, 2, 3718, 2, 3721, 2, 3722, 2, 3724, 2, 3724, 2, 3727, 2, 3727, + 2, 3734, 2, 3737, 2, 3739, 2, 3745, 2, 3747, 2, 3749, 2, 3751, 2, 3751, + 2, 3753, 2, 3753, 2, 3756, 2, 3757, 2, 3759, 2, 3771, 2, 3773, 2, 3775, + 2, 3778, 2, 3782, 2, 3784, 2, 3784, 2, 3786, 2, 3791, 2, 3794, 2, 3803, + 2, 3806, 2, 3809, 2, 3842, 2, 3842, 2, 3866, 2, 3867, 2, 3874, 2, 3883, + 2, 3895, 2, 3895, 2, 3897, 2, 3897, 2, 3899, 2, 3899, 2, 3904, 2, 3913, + 2, 3915, 2, 3950, 2, 3955, 2, 3974, 2, 3976, 2, 3993, 2, 3995, 2, 4030, + 2, 4040, 2, 4040, 2, 4098, 2, 4171, 2, 4178, 2, 4255, 2, 4258, 2, 4295, + 2, 4297, 2, 4297, 2, 4303, 2, 4303, 2, 4306, 2, 4348, 2, 4350, 2, 4682, + 2, 4684, 2, 4687, 2, 4690, 2, 4696, 2, 4698, 2, 4698, 2, 4700, 2, 4703, + 2, 4706, 2, 4746, 2, 4748, 2, 4751, 2, 4754, 2, 4786, 2, 4788, 2, 4791, + 2, 4794, 2, 4800, 2, 4802, 2, 4802, 2, 4804, 2, 4807, 2, 4810, 2, 4824, + 2, 4826, 2, 4882, 2, 4884, 2, 4887, 2, 4890, 2, 4956, 2, 4959, 2, 4961, + 2, 4971, 2, 4979, 2, 4994, 2, 5009, 2, 5026, 2, 5111, 2, 5114, 2, 5119, + 2, 5123, 2, 5742, 2, 5745, 2, 5761, 2, 5763, 2, 5788, 2, 5794, 2, 5868, + 2, 5872, 2, 5882, 2, 5890, 2, 5902, 2, 5904, 2, 5910, 2, 5922, 2, 5942, + 2, 5954, 2, 5973, 2, 5986, 2, 5998, 2, 6000, 2, 6002, 2, 6004, 2, 6005, + 2, 6018, 2, 6101, 2, 6105, 2, 6105, 2, 6110, 2, 6111, 2, 6114, 2, 6123, + 2, 6157, 2, 6159, 2, 6162, 2, 6171, 2, 6178, 2, 6265, 2, 6274, 2, 6316, + 2, 6322, 2, 6391, 2, 6402, 2, 6432, 2, 6434, 2, 6445, 2, 6450, 2, 6461, + 2, 6472, 2, 6511, 2, 6514, 2, 6518, 2, 6530, 2, 6573, 2, 6578, 2, 6603, + 2, 6610, 2, 6620, 2, 6658, 2, 6685, 2, 6690, 2, 6752, 2, 6754, 2, 6782, + 2, 6785, 2, 6795, 2, 6802, 2, 6811, 2, 6825, 2, 6825, 2, 6834, 2, 6847, + 2, 6914, 2, 6989, 2, 6994, 2, 7003, 2, 7021, 2, 7029, 2, 7042, 2, 7157, + 2, 7170, 2, 7225, 2, 7234, 2, 7243, 2, 7247, 2, 7295, 2, 7298, 2, 7306, + 2, 7378, 2, 7380, 2, 7382, 2, 7419, 2, 7426, 2, 7675, 2, 7677, 2, 7959, + 2, 7962, 2, 7967, 2, 7970, 2, 8007, 2, 8010, 2, 8015, 2, 8018, 2, 8025, + 2, 8027, 2, 8027, 2, 8029, 2, 8029, 2, 8031, 2, 8031, 2, 8033, 2, 8063, + 2, 8066, 2, 8118, 2, 8120, 2, 8126, 2, 8128, 2, 8128, 2, 8132, 2, 8134, + 2, 8136, 2, 8142, 2, 8146, 2, 8149, 2, 8152, 2, 8157, 2, 8162, 2, 8174, + 2, 8180, 2, 8182, 2, 8184, 2, 8190, 2, 8257, 2, 8258, 2, 8278, 2, 8278, + 2, 8307, 2, 8307, 2, 8321, 2, 8321, 2, 8338, 2, 8350, 2, 8402, 2, 8414, + 2, 8419, 2, 8419, 2, 8423, 2, 8434, 2, 8452, 2, 8452, 2, 8457, 2, 8457, + 2, 8460, 2, 8469, 2, 8471, 2, 8471, 2, 8474, 2, 8479, 2, 8486, 2, 8486, + 2, 8488, 2, 8488, 2, 8490, 2, 8490, 2, 8492, 2, 8507, 2, 8510, 2, 8513, + 2, 8519, 2, 8523, 2, 8528, 2, 8528, 2, 8546, 2, 8586, 2, 11266, 2, 11312, + 2, 11314, 2, 11360, 2, 11362, 2, 11494, 2, 11501, 2, 11509, 2, 11522, 2, + 11559, 2, 11561, 2, 11561, 2, 11567, 2, 11567, 2, 11570, 2, 11625, 2, 11633, + 2, 11633, 2, 11649, 2, 11672, 2, 11682, 2, 11688, 2, 11690, 2, 11696, 2, + 11698, 2, 11704, 2, 11706, 2, 11712, 2, 11714, 2, 11720, 2, 11722, 2, 11728, + 2, 11730, 2, 11736, 2, 11738, 2, 11744, 2, 11746, 2, 11777, 2, 12295, 2, + 12297, 2, 12323, 2, 12337, 2, 12339, 2, 12343, 2, 12346, 2, 12350, 2, 12355, + 2, 12440, 2, 12443, 2, 12449, 2, 12451, 2, 12540, 2, 12542, 2, 12545, 2, + 12551, 2, 12592, 2, 12595, 2, 12688, 2, 12706, 2, 12732, 2, 12786, 2, 12801, + 2, 13314, 2, 19895, 2, 19970, 2, 40940, 2, 40962, 2, 42126, 2, 42194, 2, + 42239, 2, 42242, 2, 42510, 2, 42514, 2, 42541, 2, 42562, 2, 42609, 2, 42614, + 2, 42623, 2, 42625, 2, 42739, 2, 42777, 2, 42785, 2, 42788, 2, 42890, 2, + 42893, 2, 42928, 2, 42930, 2, 42937, 2, 43001, 2, 43049, 2, 43074, 2, 43125, + 2, 43138, 2, 43207, 2, 43218, 2, 43227, 2, 43234, 2, 43257, 2, 43261, 2, + 43261, 2, 43263, 2, 43263, 2, 43266, 2, 43311, 2, 43314, 2, 43349, 2, 43362, + 2, 43390, 2, 43394, 2, 43458, 2, 43473, 2, 43483, 2, 43490, 2, 43520, 2, + 43522, 2, 43576, 2, 43586, 2, 43599, 2, 43602, 2, 43611, 2, 43618, 2, 43640, + 2, 43644, 2, 43716, 2, 43741, 2, 43743, 2, 43746, 2, 43761, 2, 43764, 2, + 43768, 2, 43779, 2, 43784, 2, 43787, 2, 43792, 2, 43795, 2, 43800, 2, 43810, + 2, 43816, 2, 43818, 2, 43824, 2, 43826, 2, 43868, 2, 43870, 2, 43879, 2, + 43890, 2, 44012, 2, 44014, 2, 44015, 2, 44018, 2, 44027, 2, 44034, 2, 55205, + 2, 55218, 2, 55240, 2, 55245, 2, 55293, 2, 63746, 2, 64111, 2, 64114, 2, + 64219, 2, 64258, 2, 64264, 2, 64277, 2, 64281, 2, 64287, 2, 64298, 2, 64300, + 2, 64312, 2, 64314, 2, 64318, 2, 64320, 2, 64320, 2, 64322, 2, 64323, 2, + 64325, 2, 64326, 2, 64328, 2, 64435, 2, 64469, 2, 64831, 2, 64850, 2, 64913, + 2, 64916, 2, 64969, 2, 65010, 2, 65021, 2, 65026, 2, 65041, 2, 65058, 2, + 65073, 2, 65077, 2, 65078, 2, 65103, 2, 65105, 2, 65138, 2, 65142, 2, 65144, + 2, 65278, 2, 65298, 2, 65307, 2, 65315, 2, 65340, 2, 65345, 2, 65345, 2, + 65347, 2, 65372, 2, 65384, 2, 65472, 2, 65476, 2, 65481, 2, 65484, 2, 65489, + 2, 65492, 2, 65497, 2, 65500, 2, 65502, 2, 2, 3, 13, 3, 15, 3, 40, 3, 42, + 3, 60, 3, 62, 3, 63, 3, 65, 3, 79, 3, 82, 3, 95, 3, 130, 3, 252, 3, 322, + 3, 374, 3, 511, 3, 511, 3, 642, 3, 670, 3, 674, 3, 722, 3, 738, 3, 738, + 3, 770, 3, 801, 3, 815, 3, 844, 3, 850, 3, 892, 3, 898, 3, 927, 3, 930, + 3, 965, 3, 970, 3, 977, 3, 979, 3, 983, 3, 1026, 3, 1183, 3, 1186, 3, 1195, + 3, 1202, 3, 1237, 3, 1242, 3, 1277, 3, 1282, 3, 1321, 3, 1330, 3, 1381, + 3, 1538, 3, 1848, 3, 1858, 3, 1879, 3, 1890, 3, 1897, 3, 2050, 3, 2055, + 3, 2058, 3, 2058, 3, 2060, 3, 2103, 3, 2105, 3, 2106, 3, 2110, 3, 2110, + 3, 2113, 3, 2135, 3, 2146, 3, 2168, 3, 2178, 3, 2208, 3, 2274, 3, 2292, + 3, 2294, 3, 2295, 3, 2306, 3, 2327, 3, 2338, 3, 2363, 3, 2434, 3, 2489, + 3, 2496, 3, 2497, 3, 2562, 3, 2565, 3, 2567, 3, 2568, 3, 2574, 3, 2581, + 3, 2583, 3, 2585, 3, 2587, 3, 2613, 3, 2618, 3, 2620, 3, 2625, 3, 2625, + 3, 2658, 3, 2686, 3, 2690, 3, 2718, 3, 2754, 3, 2761, 3, 2763, 3, 2792, + 3, 2818, 3, 2871, 3, 2882, 3, 2903, 3, 2914, 3, 2932, 3, 2946, 3, 2963, + 3, 3074, 3, 3146, 3, 3202, 3, 3252, 3, 3266, 3, 3316, 3, 4098, 3, 4168, + 3, 4200, 3, 4209, 3, 4225, 3, 4284, 3, 4306, 3, 4330, 3, 4338, 3, 4347, + 3, 4354, 3, 4406, 3, 4408, 3, 4417, 3, 4434, 3, 4469, 3, 4472, 3, 4472, + 3, 4482, 3, 4550, 3, 4556, 3, 4558, 3, 4562, 3, 4572, 3, 4574, 3, 4574, + 3, 4610, 3, 4627, 3, 4629, 3, 4665, 3, 4672, 3, 4672, 3, 4738, 3, 4744, + 3, 4746, 3, 4746, 3, 4748, 3, 4751, 3, 4753, 3, 4767, 3, 4769, 3, 4778, + 3, 4786, 3, 4844, 3, 4850, 3, 4859, 3, 4866, 3, 4869, 3, 4871, 3, 4878, + 3, 4881, 3, 4882, 3, 4885, 3, 4906, 3, 4908, 3, 4914, 3, 4916, 3, 4917, + 3, 4919, 3, 4923, 3, 4926, 3, 4934, 3, 4937, 3, 4938, 3, 4941, 3, 4943, + 3, 4946, 3, 4946, 3, 4953, 3, 4953, 3, 4959, 3, 4965, 3, 4968, 3, 4974, + 3, 4978, 3, 4982, 3, 5122, 3, 5196, 3, 5202, 3, 5211, 3, 5250, 3, 5319, + 3, 5321, 3, 5321, 3, 5330, 3, 5339, 3, 5506, 3, 5559, 3, 5562, 3, 5570, + 3, 5594, 3, 5599, 3, 5634, 3, 5698, 3, 5702, 3, 5702, 3, 5714, 3, 5723, + 3, 5762, 3, 5817, 3, 5826, 3, 5835, 3, 5890, 3, 5915, 3, 5919, 3, 5933, + 3, 5938, 3, 5947, 3, 6306, 3, 6379, 3, 6401, 3, 6401, 3, 6658, 3, 6720, + 3, 6729, 3, 6729, 3, 6738, 3, 6789, 3, 6792, 3, 6811, 3, 6850, 3, 6906, + 3, 7170, 3, 7178, 3, 7180, 3, 7224, 3, 7226, 3, 7234, 3, 7250, 3, 7259, + 3, 7284, 3, 7313, 3, 7316, 3, 7337, 3, 7339, 3, 7352, 3, 7426, 3, 7432, + 3, 7434, 3, 7435, 3, 7437, 3, 7480, 3, 7484, 3, 7484, 3, 7486, 3, 7487, + 3, 7489, 3, 7497, 3, 7506, 3, 7515, 3, 8194, 3, 9115, 3, 9218, 3, 9328, + 3, 9346, 3, 9541, 3, 12290, 3, 13360, 3, 17410, 3, 17992, 3, 26626, 3, + 27194, 3, 27202, 3, 27232, 3, 27234, 3, 27243, 3, 27346, 3, 27375, 3, 27378, + 3, 27382, 3, 27394, 3, 27448, 3, 27458, 3, 27461, 3, 27474, 3, 27483, 3, + 27493, 3, 27513, 3, 27519, 3, 27537, 3, 28418, 3, 28486, 3, 28498, 3, 28544, + 3, 28561, 3, 28577, 3, 28642, 3, 28643, 3, 28674, 3, 34798, 3, 34818, 3, + 35572, 3, 45058, 3, 45344, 3, 45426, 3, 45821, 3, 48130, 3, 48236, 3, 48242, + 3, 48254, 3, 48258, 3, 48266, 3, 48274, 3, 48283, 3, 48287, 3, 48288, 3, + 53607, 3, 53611, 3, 53615, 3, 53620, 3, 53629, 3, 53636, 3, 53639, 3, 53645, + 3, 53676, 3, 53679, 3, 53828, 3, 53830, 3, 54274, 3, 54358, 3, 54360, 3, + 54430, 3, 54432, 3, 54433, 3, 54436, 3, 54436, 3, 54439, 3, 54440, 3, 54443, + 3, 54446, 3, 54448, 3, 54459, 3, 54461, 3, 54461, 3, 54463, 3, 54469, 3, + 54471, 3, 54535, 3, 54537, 3, 54540, 3, 54543, 3, 54550, 3, 54552, 3, 54558, + 3, 54560, 3, 54587, 3, 54589, 3, 54592, 3, 54594, 3, 54598, 3, 54600, 3, + 54600, 3, 54604, 3, 54610, 3, 54612, 3, 54951, 3, 54954, 3, 54978, 3, 54980, + 3, 55004, 3, 55006, 3, 55036, 3, 55038, 3, 55062, 3, 55064, 3, 55094, 3, + 55096, 3, 55120, 3, 55122, 3, 55152, 3, 55154, 3, 55178, 3, 55180, 3, 55210, + 3, 55212, 3, 55236, 3, 55238, 3, 55245, 3, 55248, 3, 55297, 3, 55810, 3, + 55864, 3, 55869, 3, 55918, 3, 55927, 3, 55927, 3, 55942, 3, 55942, 3, 55965, + 3, 55969, 3, 55971, 3, 55985, 3, 57346, 3, 57352, 3, 57354, 3, 57370, 3, + 57373, 3, 57379, 3, 57381, 3, 57382, 3, 57384, 3, 57388, 3, 59394, 3, 59590, + 3, 59602, 3, 59608, 3, 59650, 3, 59724, 3, 59730, 3, 59739, 3, 60930, 3, + 60933, 3, 60935, 3, 60961, 3, 60963, 3, 60964, 3, 60966, 3, 60966, 3, 60969, + 3, 60969, 3, 60971, 3, 60980, 3, 60982, 3, 60985, 3, 60987, 3, 60987, 3, + 60989, 3, 60989, 3, 60996, 3, 60996, 3, 61001, 3, 61001, 3, 61003, 3, 61003, + 3, 61005, 3, 61005, 3, 61007, 3, 61009, 3, 61011, 3, 61012, 3, 61014, 3, + 61014, 3, 61017, 3, 61017, 3, 61019, 3, 61019, 3, 61021, 3, 61021, 3, 61023, + 3, 61023, 3, 61025, 3, 61025, 3, 61027, 3, 61028, 3, 61030, 3, 61030, 3, + 61033, 3, 61036, 3, 61038, 3, 61044, 3, 61046, 3, 61049, 3, 61051, 3, 61054, + 3, 61056, 3, 61056, 3, 61058, 3, 61067, 3, 61069, 3, 61085, 3, 61091, 3, + 61093, 3, 61095, 3, 61099, 3, 61101, 3, 61117, 3, 2, 4, 42712, 4, 42754, + 4, 46902, 4, 46914, 4, 47135, 4, 47138, 4, 52899, 4, 52914, 4, 60386, 4, + 63490, 4, 64031, 4, 258, 16, 497, 16, 587, 2, 67, 2, 92, 2, 99, 2, 124, + 2, 172, 2, 172, 2, 183, 2, 183, 2, 188, 2, 188, 2, 194, 2, 216, 2, 218, + 2, 248, 2, 250, 2, 707, 2, 712, 2, 723, 2, 738, 2, 742, 2, 750, 2, 750, + 2, 752, 2, 752, 2, 882, 2, 886, 2, 888, 2, 889, 2, 892, 2, 895, 2, 897, + 2, 897, 2, 904, 2, 904, 2, 906, 2, 908, 2, 910, 2, 910, 2, 912, 2, 931, + 2, 933, 2, 1015, 2, 1017, 2, 1155, 2, 1164, 2, 1329, 2, 1331, 2, 1368, + 2, 1371, 2, 1371, 2, 1379, 2, 1417, 2, 1490, 2, 1516, 2, 1522, 2, 1524, + 2, 1570, 2, 1612, 2, 1648, 2, 1649, 2, 1651, 2, 1749, 2, 1751, 2, 1751, + 2, 1767, 2, 1768, 2, 1776, 2, 1777, 2, 1788, 2, 1790, 2, 1793, 2, 1793, + 2, 1810, 2, 1810, 2, 1812, 2, 1841, 2, 1871, 2, 1959, 2, 1971, 2, 1971, + 2, 1996, 2, 2028, 2, 2038, 2, 2039, 2, 2044, 2, 2044, 2, 2050, 2, 2071, + 2, 2076, 2, 2076, 2, 2086, 2, 2086, 2, 2090, 2, 2090, 2, 2114, 2, 2138, + 2, 2146, 2, 2156, 2, 2210, 2, 2230, 2, 2232, 2, 2239, 2, 2310, 2, 2363, + 2, 2367, 2, 2367, 2, 2386, 2, 2386, 2, 2394, 2, 2403, 2, 2419, 2, 2434, + 2, 2439, 2, 2446, 2, 2449, 2, 2450, 2, 2453, 2, 2474, 2, 2476, 2, 2482, + 2, 2484, 2, 2484, 2, 2488, 2, 2491, 2, 2495, 2, 2495, 2, 2512, 2, 2512, + 2, 2526, 2, 2527, 2, 2529, 2, 2531, 2, 2546, 2, 2547, 2, 2558, 2, 2558, + 2, 2567, 2, 2572, 2, 2577, 2, 2578, 2, 2581, 2, 2602, 2, 2604, 2, 2610, + 2, 2612, 2, 2613, 2, 2615, 2, 2616, 2, 2618, 2, 2619, 2, 2651, 2, 2654, + 2, 2656, 2, 2656, 2, 2676, 2, 2678, 2, 2695, 2, 2703, 2, 2705, 2, 2707, + 2, 2709, 2, 2730, 2, 2732, 2, 2738, 2, 2740, 2, 2741, 2, 2743, 2, 2747, + 2, 2751, 2, 2751, 2, 2770, 2, 2770, 2, 2786, 2, 2787, 2, 2811, 2, 2811, + 2, 2823, 2, 2830, 2, 2833, 2, 2834, 2, 2837, 2, 2858, 2, 2860, 2, 2866, + 2, 2868, 2, 2869, 2, 2871, 2, 2875, 2, 2879, 2, 2879, 2, 2910, 2, 2911, + 2, 2913, 2, 2915, 2, 2931, 2, 2931, 2, 2949, 2, 2949, 2, 2951, 2, 2956, + 2, 2960, 2, 2962, 2, 2964, 2, 2967, 2, 2971, 2, 2972, 2, 2974, 2, 2974, + 2, 2976, 2, 2977, 2, 2981, 2, 2982, 2, 2986, 2, 2988, 2, 2992, 2, 3003, + 2, 3026, 2, 3026, 2, 3079, 2, 3086, 2, 3088, 2, 3090, 2, 3092, 2, 3114, + 2, 3116, 2, 3131, 2, 3135, 2, 3135, 2, 3162, 2, 3164, 2, 3170, 2, 3171, + 2, 3202, 2, 3202, 2, 3207, 2, 3214, 2, 3216, 2, 3218, 2, 3220, 2, 3242, + 2, 3244, 2, 3253, 2, 3255, 2, 3259, 2, 3263, 2, 3263, 2, 3296, 2, 3296, + 2, 3298, 2, 3299, 2, 3315, 2, 3316, 2, 3335, 2, 3342, 2, 3344, 2, 3346, + 2, 3348, 2, 3388, 2, 3391, 2, 3391, 2, 3408, 2, 3408, 2, 3414, 2, 3416, + 2, 3425, 2, 3427, 2, 3452, 2, 3457, 2, 3463, 2, 3480, 2, 3484, 2, 3507, + 2, 3509, 2, 3517, 2, 3519, 2, 3519, 2, 3522, 2, 3528, 2, 3587, 2, 3634, + 2, 3636, 2, 3637, 2, 3650, 2, 3656, 2, 3715, 2, 3716, 2, 3718, 2, 3718, + 2, 3721, 2, 3722, 2, 3724, 2, 3724, 2, 3727, 2, 3727, 2, 3734, 2, 3737, + 2, 3739, 2, 3745, 2, 3747, 2, 3749, 2, 3751, 2, 3751, 2, 3753, 2, 3753, + 2, 3756, 2, 3757, 2, 3759, 2, 3762, 2, 3764, 2, 3765, 2, 3775, 2, 3775, + 2, 3778, 2, 3782, 2, 3784, 2, 3784, 2, 3806, 2, 3809, 2, 3842, 2, 3842, + 2, 3906, 2, 3913, 2, 3915, 2, 3950, 2, 3978, 2, 3982, 2, 4098, 2, 4140, + 2, 4161, 2, 4161, 2, 4178, 2, 4183, 2, 4188, 2, 4191, 2, 4195, 2, 4195, + 2, 4199, 2, 4200, 2, 4208, 2, 4210, 2, 4215, 2, 4227, 2, 4240, 2, 4240, + 2, 4258, 2, 4295, 2, 4297, 2, 4297, 2, 4303, 2, 4303, 2, 4306, 2, 4348, + 2, 4350, 2, 4682, 2, 4684, 2, 4687, 2, 4690, 2, 4696, 2, 4698, 2, 4698, + 2, 4700, 2, 4703, 2, 4706, 2, 4746, 2, 4748, 2, 4751, 2, 4754, 2, 4786, + 2, 4788, 2, 4791, 2, 4794, 2, 4800, 2, 4802, 2, 4802, 2, 4804, 2, 4807, + 2, 4810, 2, 4824, 2, 4826, 2, 4882, 2, 4884, 2, 4887, 2, 4890, 2, 4956, + 2, 4994, 2, 5009, 2, 5026, 2, 5111, 2, 5114, 2, 5119, 2, 5123, 2, 5742, + 2, 5745, 2, 5761, 2, 5763, 2, 5788, 2, 5794, 2, 5868, 2, 5872, 2, 5882, + 2, 5890, 2, 5902, 2, 5904, 2, 5907, 2, 5922, 2, 5939, 2, 5954, 2, 5971, + 2, 5986, 2, 5998, 2, 6000, 2, 6002, 2, 6018, 2, 6069, 2, 6105, 2, 6105, + 2, 6110, 2, 6110, 2, 6178, 2, 6265, 2, 6274, 2, 6314, 2, 6316, 2, 6316, + 2, 6322, 2, 6391, 2, 6402, 2, 6432, 2, 6482, 2, 6511, 2, 6514, 2, 6518, + 2, 6530, 2, 6573, 2, 6578, 2, 6603, 2, 6658, 2, 6680, 2, 6690, 2, 6742, + 2, 6825, 2, 6825, 2, 6919, 2, 6965, 2, 6983, 2, 6989, 2, 7045, 2, 7074, + 2, 7088, 2, 7089, 2, 7100, 2, 7143, 2, 7170, 2, 7205, 2, 7247, 2, 7249, + 2, 7260, 2, 7295, 2, 7298, 2, 7306, 2, 7403, 2, 7406, 2, 7408, 2, 7411, + 2, 7415, 2, 7416, 2, 7426, 2, 7617, 2, 7682, 2, 7959, 2, 7962, 2, 7967, + 2, 7970, 2, 8007, 2, 8010, 2, 8015, 2, 8018, 2, 8025, 2, 8027, 2, 8027, + 2, 8029, 2, 8029, 2, 8031, 2, 8031, 2, 8033, 2, 8063, 2, 8066, 2, 8118, + 2, 8120, 2, 8126, 2, 8128, 2, 8128, 2, 8132, 2, 8134, 2, 8136, 2, 8142, + 2, 8146, 2, 8149, 2, 8152, 2, 8157, 2, 8162, 2, 8174, 2, 8180, 2, 8182, + 2, 8184, 2, 8190, 2, 8307, 2, 8307, 2, 8321, 2, 8321, 2, 8338, 2, 8350, + 2, 8452, 2, 8452, 2, 8457, 2, 8457, 2, 8460, 2, 8469, 2, 8471, 2, 8471, + 2, 8474, 2, 8479, 2, 8486, 2, 8486, 2, 8488, 2, 8488, 2, 8490, 2, 8490, + 2, 8492, 2, 8507, 2, 8510, 2, 8513, 2, 8519, 2, 8523, 2, 8528, 2, 8528, + 2, 8546, 2, 8586, 2, 11266, 2, 11312, 2, 11314, 2, 11360, 2, 11362, 2, + 11494, 2, 11501, 2, 11504, 2, 11508, 2, 11509, 2, 11522, 2, 11559, 2, 11561, + 2, 11561, 2, 11567, 2, 11567, 2, 11570, 2, 11625, 2, 11633, 2, 11633, 2, + 11650, 2, 11672, 2, 11682, 2, 11688, 2, 11690, 2, 11696, 2, 11698, 2, 11704, + 2, 11706, 2, 11712, 2, 11714, 2, 11720, 2, 11722, 2, 11728, 2, 11730, 2, + 11736, 2, 11738, 2, 11744, 2, 12295, 2, 12297, 2, 12323, 2, 12331, 2, 12339, + 2, 12343, 2, 12346, 2, 12350, 2, 12355, 2, 12440, 2, 12445, 2, 12449, 2, + 12451, 2, 12540, 2, 12542, 2, 12545, 2, 12551, 2, 12592, 2, 12595, 2, 12688, + 2, 12706, 2, 12732, 2, 12786, 2, 12801, 2, 13314, 2, 19895, 2, 19970, 2, + 40940, 2, 40962, 2, 42126, 2, 42194, 2, 42239, 2, 42242, 2, 42510, 2, 42514, + 2, 42529, 2, 42540, 2, 42541, 2, 42562, 2, 42608, 2, 42625, 2, 42655, 2, + 42658, 2, 42737, 2, 42777, 2, 42785, 2, 42788, 2, 42890, 2, 42893, 2, 42928, + 2, 42930, 2, 42937, 2, 43001, 2, 43011, 2, 43013, 2, 43015, 2, 43017, 2, + 43020, 2, 43022, 2, 43044, 2, 43074, 2, 43125, 2, 43140, 2, 43189, 2, 43252, + 2, 43257, 2, 43261, 2, 43261, 2, 43263, 2, 43263, 2, 43276, 2, 43303, 2, + 43314, 2, 43336, 2, 43362, 2, 43390, 2, 43398, 2, 43444, 2, 43473, 2, 43473, + 2, 43490, 2, 43494, 2, 43496, 2, 43505, 2, 43516, 2, 43520, 2, 43522, 2, + 43562, 2, 43586, 2, 43588, 2, 43590, 2, 43597, 2, 43618, 2, 43640, 2, 43644, + 2, 43644, 2, 43648, 2, 43697, 2, 43699, 2, 43699, 2, 43703, 2, 43704, 2, + 43707, 2, 43711, 2, 43714, 2, 43714, 2, 43716, 2, 43716, 2, 43741, 2, 43743, + 2, 43746, 2, 43756, 2, 43764, 2, 43766, 2, 43779, 2, 43784, 2, 43787, 2, + 43792, 2, 43795, 2, 43800, 2, 43810, 2, 43816, 2, 43818, 2, 43824, 2, 43826, + 2, 43868, 2, 43870, 2, 43879, 2, 43890, 2, 44004, 2, 44034, 2, 55205, 2, + 55218, 2, 55240, 2, 55245, 2, 55293, 2, 63746, 2, 64111, 2, 64114, 2, 64219, + 2, 64258, 2, 64264, 2, 64277, 2, 64281, 2, 64287, 2, 64287, 2, 64289, 2, + 64298, 2, 64300, 2, 64312, 2, 64314, 2, 64318, 2, 64320, 2, 64320, 2, 64322, + 2, 64323, 2, 64325, 2, 64326, 2, 64328, 2, 64435, 2, 64469, 2, 64831, 2, + 64850, 2, 64913, 2, 64916, 2, 64969, 2, 65010, 2, 65021, 2, 65138, 2, 65142, + 2, 65144, 2, 65278, 2, 65315, 2, 65340, 2, 65347, 2, 65372, 2, 65384, 2, + 65472, 2, 65476, 2, 65481, 2, 65484, 2, 65489, 2, 65492, 2, 65497, 2, 65500, + 2, 65502, 2, 2, 3, 13, 3, 15, 3, 40, 3, 42, 3, 60, 3, 62, 3, 63, 3, 65, + 3, 79, 3, 82, 3, 95, 3, 130, 3, 252, 3, 322, 3, 374, 3, 642, 3, 670, 3, + 674, 3, 722, 3, 770, 3, 801, 3, 815, 3, 844, 3, 850, 3, 887, 3, 898, 3, + 927, 3, 930, 3, 965, 3, 970, 3, 977, 3, 979, 3, 983, 3, 1026, 3, 1183, + 3, 1202, 3, 1237, 3, 1242, 3, 1277, 3, 1282, 3, 1321, 3, 1330, 3, 1381, + 3, 1538, 3, 1848, 3, 1858, 3, 1879, 3, 1890, 3, 1897, 3, 2050, 3, 2055, + 3, 2058, 3, 2058, 3, 2060, 3, 2103, 3, 2105, 3, 2106, 3, 2110, 3, 2110, + 3, 2113, 3, 2135, 3, 2146, 3, 2168, 3, 2178, 3, 2208, 3, 2274, 3, 2292, + 3, 2294, 3, 2295, 3, 2306, 3, 2327, 3, 2338, 3, 2363, 3, 2434, 3, 2489, + 3, 2496, 3, 2497, 3, 2562, 3, 2562, 3, 2578, 3, 2581, 3, 2583, 3, 2585, + 3, 2587, 3, 2613, 3, 2658, 3, 2686, 3, 2690, 3, 2718, 3, 2754, 3, 2761, + 3, 2763, 3, 2790, 3, 2818, 3, 2871, 3, 2882, 3, 2903, 3, 2914, 3, 2932, + 3, 2946, 3, 2963, 3, 3074, 3, 3146, 3, 3202, 3, 3252, 3, 3266, 3, 3316, + 3, 4101, 3, 4153, 3, 4229, 3, 4273, 3, 4306, 3, 4330, 3, 4357, 3, 4392, + 3, 4434, 3, 4468, 3, 4472, 3, 4472, 3, 4485, 3, 4532, 3, 4547, 3, 4550, + 3, 4572, 3, 4572, 3, 4574, 3, 4574, 3, 4610, 3, 4627, 3, 4629, 3, 4653, + 3, 4738, 3, 4744, 3, 4746, 3, 4746, 3, 4748, 3, 4751, 3, 4753, 3, 4767, + 3, 4769, 3, 4778, 3, 4786, 3, 4832, 3, 4871, 3, 4878, 3, 4881, 3, 4882, + 3, 4885, 3, 4906, 3, 4908, 3, 4914, 3, 4916, 3, 4917, 3, 4919, 3, 4923, + 3, 4927, 3, 4927, 3, 4946, 3, 4946, 3, 4959, 3, 4963, 3, 5122, 3, 5174, + 3, 5193, 3, 5196, 3, 5250, 3, 5297, 3, 5318, 3, 5319, 3, 5321, 3, 5321, + 3, 5506, 3, 5552, 3, 5594, 3, 5597, 3, 5634, 3, 5681, 3, 5702, 3, 5702, + 3, 5762, 3, 5804, 3, 5890, 3, 5915, 3, 6306, 3, 6369, 3, 6401, 3, 6401, + 3, 6658, 3, 6658, 3, 6669, 3, 6708, 3, 6716, 3, 6716, 3, 6738, 3, 6738, + 3, 6750, 3, 6789, 3, 6792, 3, 6795, 3, 6850, 3, 6906, 3, 7170, 3, 7178, + 3, 7180, 3, 7216, 3, 7234, 3, 7234, 3, 7284, 3, 7313, 3, 7426, 3, 7432, + 3, 7434, 3, 7435, 3, 7437, 3, 7474, 3, 7496, 3, 7496, 3, 8194, 3, 9115, + 3, 9218, 3, 9328, 3, 9346, 3, 9541, 3, 12290, 3, 13360, 3, 17410, 3, 17992, + 3, 26626, 3, 27194, 3, 27202, 3, 27232, 3, 27346, 3, 27375, 3, 27394, 3, + 27441, 3, 27458, 3, 27461, 3, 27493, 3, 27513, 3, 27519, 3, 27537, 3, 28418, + 3, 28486, 3, 28498, 3, 28498, 3, 28565, 3, 28577, 3, 28642, 3, 28643, 3, + 28674, 3, 34798, 3, 34818, 3, 35572, 3, 45058, 3, 45344, 3, 45426, 3, 45821, + 3, 48130, 3, 48236, 3, 48242, 3, 48254, 3, 48258, 3, 48266, 3, 48274, 3, + 48283, 3, 54274, 3, 54358, 3, 54360, 3, 54430, 3, 54432, 3, 54433, 3, 54436, + 3, 54436, 3, 54439, 3, 54440, 3, 54443, 3, 54446, 3, 54448, 3, 54459, 3, + 54461, 3, 54461, 3, 54463, 3, 54469, 3, 54471, 3, 54535, 3, 54537, 3, 54540, + 3, 54543, 3, 54550, 3, 54552, 3, 54558, 3, 54560, 3, 54587, 3, 54589, 3, + 54592, 3, 54594, 3, 54598, 3, 54600, 3, 54600, 3, 54604, 3, 54610, 3, 54612, + 3, 54951, 3, 54954, 3, 54978, 3, 54980, 3, 55004, 3, 55006, 3, 55036, 3, + 55038, 3, 55062, 3, 55064, 3, 55094, 3, 55096, 3, 55120, 3, 55122, 3, 55152, + 3, 55154, 3, 55178, 3, 55180, 3, 55210, 3, 55212, 3, 55236, 3, 55238, 3, + 55245, 3, 59394, 3, 59590, 3, 59650, 3, 59717, 3, 60930, 3, 60933, 3, 60935, + 3, 60961, 3, 60963, 3, 60964, 3, 60966, 3, 60966, 3, 60969, 3, 60969, 3, + 60971, 3, 60980, 3, 60982, 3, 60985, 3, 60987, 3, 60987, 3, 60989, 3, 60989, + 3, 60996, 3, 60996, 3, 61001, 3, 61001, 3, 61003, 3, 61003, 3, 61005, 3, + 61005, 3, 61007, 3, 61009, 3, 61011, 3, 61012, 3, 61014, 3, 61014, 3, 61017, + 3, 61017, 3, 61019, 3, 61019, 3, 61021, 3, 61021, 3, 61023, 3, 61023, 3, + 61025, 3, 61025, 3, 61027, 3, 61028, 3, 61030, 3, 61030, 3, 61033, 3, 61036, + 3, 61038, 3, 61044, 3, 61046, 3, 61049, 3, 61051, 3, 61054, 3, 61056, 3, + 61056, 3, 61058, 3, 61067, 3, 61069, 3, 61085, 3, 61091, 3, 61093, 3, 61095, + 3, 61099, 3, 61101, 3, 61117, 3, 2, 4, 42712, 4, 42754, 4, 46902, 4, 46914, + 4, 47135, 4, 47138, 4, 52899, 4, 52914, 4, 60386, 4, 63490, 4, 64031, 4, + 1020, 2, 3, 3, 2, 2, 2, 2, 5, 3, 2, 2, 2, 2, 7, 3, 2, 2, 2, 2, 9, 3, 2, + 2, 2, 2, 11, 3, 2, 2, 2, 2, 13, 3, 2, 2, 2, 2, 15, 3, 2, 2, 2, 2, 17, 3, + 2, 2, 2, 2, 19, 3, 2, 2, 2, 2, 21, 3, 2, 2, 2, 2, 23, 3, 2, 2, 2, 2, 25, + 3, 2, 2, 2, 2, 27, 3, 2, 2, 2, 2, 29, 3, 2, 2, 2, 2, 31, 3, 2, 2, 2, 2, + 33, 3, 2, 2, 2, 2, 35, 3, 2, 2, 2, 2, 37, 3, 2, 2, 2, 2, 39, 3, 2, 2, 2, + 2, 41, 3, 2, 2, 2, 2, 43, 3, 2, 2, 2, 2, 45, 3, 2, 2, 2, 2, 47, 3, 2, 2, + 2, 2, 49, 3, 2, 2, 2, 2, 51, 3, 2, 2, 2, 2, 53, 3, 2, 2, 2, 2, 55, 3, 2, + 2, 2, 2, 57, 3, 2, 2, 2, 2, 59, 3, 2, 2, 2, 2, 61, 3, 2, 2, 2, 2, 63, 3, + 2, 2, 2, 2, 65, 3, 2, 2, 2, 2, 67, 3, 2, 2, 2, 2, 69, 3, 2, 2, 2, 2, 71, + 3, 2, 2, 2, 2, 73, 3, 2, 2, 2, 2, 75, 3, 2, 2, 2, 2, 77, 3, 2, 2, 2, 2, + 79, 3, 2, 2, 2, 2, 81, 3, 2, 2, 2, 2, 83, 3, 2, 2, 2, 2, 85, 3, 2, 2, 2, + 2, 87, 3, 2, 2, 2, 2, 89, 3, 2, 2, 2, 2, 91, 3, 2, 2, 2, 2, 93, 3, 2, 2, + 2, 2, 95, 3, 2, 2, 2, 2, 97, 3, 2, 2, 2, 2, 99, 3, 2, 2, 2, 2, 101, 3, + 2, 2, 2, 2, 103, 3, 2, 2, 2, 2, 105, 3, 2, 2, 2, 2, 107, 3, 2, 2, 2, 2, + 109, 3, 2, 2, 2, 2, 111, 3, 2, 2, 2, 2, 113, 3, 2, 2, 2, 2, 115, 3, 2, + 2, 2, 2, 117, 3, 2, 2, 2, 2, 119, 3, 2, 2, 2, 2, 121, 3, 2, 2, 2, 2, 123, + 3, 2, 2, 2, 2, 125, 3, 2, 2, 2, 2, 127, 3, 2, 2, 2, 2, 129, 3, 2, 2, 2, + 2, 131, 3, 2, 2, 2, 2, 133, 3, 2, 2, 2, 2, 135, 3, 2, 2, 2, 2, 137, 3, + 2, 2, 2, 2, 139, 3, 2, 2, 2, 2, 141, 3, 2, 2, 2, 2, 143, 3, 2, 2, 2, 2, + 145, 3, 2, 2, 2, 2, 147, 3, 2, 2, 2, 2, 149, 3, 2, 2, 2, 2, 151, 3, 2, + 2, 2, 2, 153, 3, 2, 2, 2, 2, 155, 3, 2, 2, 2, 2, 157, 3, 2, 2, 2, 2, 159, + 3, 2, 2, 2, 2, 161, 3, 2, 2, 2, 2, 163, 3, 2, 2, 2, 2, 165, 3, 2, 2, 2, + 2, 167, 3, 2, 2, 2, 2, 169, 3, 2, 2, 2, 2, 171, 3, 2, 2, 2, 2, 173, 3, + 2, 2, 2, 2, 175, 3, 2, 2, 2, 2, 177, 3, 2, 2, 2, 2, 179, 3, 2, 2, 2, 2, + 181, 3, 2, 2, 2, 2, 183, 3, 2, 2, 2, 2, 185, 3, 2, 2, 2, 2, 187, 3, 2, + 2, 2, 2, 189, 3, 2, 2, 2, 2, 191, 3, 2, 2, 2, 2, 193, 3, 2, 2, 2, 2, 195, + 3, 2, 2, 2, 2, 197, 3, 2, 2, 2, 2, 199, 3, 2, 2, 2, 2, 201, 3, 2, 2, 2, + 2, 203, 3, 2, 2, 2, 2, 205, 3, 2, 2, 2, 2, 207, 3, 2, 2, 2, 2, 209, 3, + 2, 2, 2, 2, 211, 3, 2, 2, 2, 2, 213, 3, 2, 2, 2, 2, 215, 3, 2, 2, 2, 2, + 217, 3, 2, 2, 2, 2, 219, 3, 2, 2, 2, 2, 221, 3, 2, 2, 2, 2, 223, 3, 2, + 2, 2, 2, 225, 3, 2, 2, 2, 2, 227, 3, 2, 2, 2, 2, 229, 3, 2, 2, 2, 2, 231, + 3, 2, 2, 2, 2, 233, 3, 2, 2, 2, 2, 235, 3, 2, 2, 2, 2, 237, 3, 2, 2, 2, + 2, 239, 3, 2, 2, 2, 2, 241, 3, 2, 2, 2, 2, 243, 3, 2, 2, 2, 2, 245, 3, + 2, 2, 2, 2, 247, 3, 2, 2, 2, 2, 249, 3, 2, 2, 2, 2, 251, 3, 2, 2, 2, 2, + 253, 3, 2, 2, 2, 2, 255, 3, 2, 2, 2, 3, 297, 3, 2, 2, 2, 5, 299, 3, 2, + 2, 2, 7, 301, 3, 2, 2, 2, 9, 303, 3, 2, 2, 2, 11, 306, 3, 2, 2, 2, 13, + 308, 3, 2, 2, 2, 15, 310, 3, 2, 2, 2, 17, 312, 3, 2, 2, 2, 19, 314, 3, + 2, 2, 2, 21, 316, 3, 2, 2, 2, 23, 318, 3, 2, 2, 2, 25, 320, 3, 2, 2, 2, + 27, 323, 3, 2, 2, 2, 29, 325, 3, 2, 2, 2, 31, 327, 3, 2, 2, 2, 33, 329, + 3, 2, 2, 2, 35, 331, 3, 2, 2, 2, 37, 333, 3, 2, 2, 2, 39, 336, 3, 2, 2, + 2, 41, 338, 3, 2, 2, 2, 43, 340, 3, 2, 2, 2, 45, 343, 3, 2, 2, 2, 47, 346, + 3, 2, 2, 2, 49, 348, 3, 2, 2, 2, 51, 350, 3, 2, 2, 2, 53, 352, 3, 2, 2, + 2, 55, 354, 3, 2, 2, 2, 57, 356, 3, 2, 2, 2, 59, 358, 3, 2, 2, 2, 61, 360, + 3, 2, 2, 2, 63, 362, 3, 2, 2, 2, 65, 364, 3, 2, 2, 2, 67, 366, 3, 2, 2, + 2, 69, 368, 3, 2, 2, 2, 71, 370, 3, 2, 2, 2, 73, 372, 3, 2, 2, 2, 75, 374, + 3, 2, 2, 2, 77, 376, 3, 2, 2, 2, 79, 378, 3, 2, 2, 2, 81, 380, 3, 2, 2, + 2, 83, 382, 3, 2, 2, 2, 85, 384, 3, 2, 2, 2, 87, 386, 3, 2, 2, 2, 89, 388, + 3, 2, 2, 2, 91, 390, 3, 2, 2, 2, 93, 392, 3, 2, 2, 2, 95, 398, 3, 2, 2, + 2, 97, 402, 3, 2, 2, 2, 99, 411, 3, 2, 2, 2, 101, 417, 3, 2, 2, 2, 103, + 424, 3, 2, 2, 2, 105, 427, 3, 2, 2, 2, 107, 433, 3, 2, 2, 2, 109, 436, + 3, 2, 2, 2, 111, 443, 3, 2, 2, 2, 113, 447, 3, 2, 2, 2, 115, 454, 3, 2, + 2, 2, 117, 461, 3, 2, 2, 2, 119, 468, 3, 2, 2, 2, 121, 473, 3, 2, 2, 2, + 123, 479, 3, 2, 2, 2, 125, 484, 3, 2, 2, 2, 127, 491, 3, 2, 2, 2, 129, + 500, 3, 2, 2, 2, 131, 506, 3, 2, 2, 2, 133, 509, 3, 2, 2, 2, 135, 514, + 3, 2, 2, 2, 137, 520, 3, 2, 2, 2, 139, 530, 3, 2, 2, 2, 141, 534, 3, 2, + 2, 2, 143, 545, 3, 2, 2, 2, 145, 550, 3, 2, 2, 2, 147, 556, 3, 2, 2, 2, + 149, 559, 3, 2, 2, 2, 151, 563, 3, 2, 2, 2, 153, 567, 3, 2, 2, 2, 155, + 571, 3, 2, 2, 2, 157, 574, 3, 2, 2, 2, 159, 581, 3, 2, 2, 2, 161, 586, + 3, 2, 2, 2, 163, 595, 3, 2, 2, 2, 165, 598, 3, 2, 2, 2, 167, 603, 3, 2, + 2, 2, 169, 609, 3, 2, 2, 2, 171, 613, 3, 2, 2, 2, 173, 618, 3, 2, 2, 2, + 175, 625, 3, 2, 2, 2, 177, 630, 3, 2, 2, 2, 179, 636, 3, 2, 2, 2, 181, + 643, 3, 2, 2, 2, 183, 648, 3, 2, 2, 2, 185, 653, 3, 2, 2, 2, 187, 657, + 3, 2, 2, 2, 189, 662, 3, 2, 2, 2, 191, 685, 3, 2, 2, 2, 193, 687, 3, 2, + 2, 2, 195, 707, 3, 2, 2, 2, 197, 723, 3, 2, 2, 2, 199, 725, 3, 2, 2, 2, + 201, 732, 3, 2, 2, 2, 203, 736, 3, 2, 2, 2, 205, 740, 3, 2, 2, 2, 207, + 744, 3, 2, 2, 2, 209, 746, 3, 2, 2, 2, 211, 750, 3, 2, 2, 2, 213, 752, + 3, 2, 2, 2, 215, 776, 3, 2, 2, 2, 217, 790, 3, 2, 2, 2, 219, 799, 3, 2, + 2, 2, 221, 810, 3, 2, 2, 2, 223, 813, 3, 2, 2, 2, 225, 817, 3, 2, 2, 2, + 227, 825, 3, 2, 2, 2, 229, 832, 3, 2, 2, 2, 231, 842, 3, 2, 2, 2, 233, + 849, 3, 2, 2, 2, 235, 852, 3, 2, 2, 2, 237, 856, 3, 2, 2, 2, 239, 861, + 3, 2, 2, 2, 241, 868, 3, 2, 2, 2, 243, 876, 3, 2, 2, 2, 245, 885, 3, 2, + 2, 2, 247, 889, 3, 2, 2, 2, 249, 899, 3, 2, 2, 2, 251, 904, 3, 2, 2, 2, + 253, 920, 3, 2, 2, 2, 255, 951, 3, 2, 2, 2, 257, 953, 3, 2, 2, 2, 259, + 955, 3, 2, 2, 2, 261, 957, 3, 2, 2, 2, 263, 959, 3, 2, 2, 2, 265, 961, + 3, 2, 2, 2, 267, 963, 3, 2, 2, 2, 269, 965, 3, 2, 2, 2, 271, 967, 3, 2, + 2, 2, 273, 969, 3, 2, 2, 2, 275, 971, 3, 2, 2, 2, 277, 973, 3, 2, 2, 2, + 279, 975, 3, 2, 2, 2, 281, 977, 3, 2, 2, 2, 283, 979, 3, 2, 2, 2, 285, + 981, 3, 2, 2, 2, 287, 983, 3, 2, 2, 2, 289, 985, 3, 2, 2, 2, 291, 987, + 3, 2, 2, 2, 293, 989, 3, 2, 2, 2, 295, 991, 3, 2, 2, 2, 297, 298, 7, 61, + 2, 2, 298, 4, 3, 2, 2, 2, 299, 300, 7, 46, 2, 2, 300, 6, 3, 2, 2, 2, 301, + 302, 7, 63, 2, 2, 302, 8, 3, 2, 2, 2, 303, 304, 7, 45, 2, 2, 304, 305, + 7, 63, 2, 2, 305, 10, 3, 2, 2, 2, 306, 307, 7, 44, 2, 2, 307, 12, 3, 2, + 2, 2, 308, 309, 7, 42, 2, 2, 309, 14, 3, 2, 2, 2, 310, 311, 7, 43, 2, 2, + 311, 16, 3, 2, 2, 2, 312, 313, 7, 93, 2, 2, 313, 18, 3, 2, 2, 2, 314, 315, + 7, 95, 2, 2, 315, 20, 3, 2, 2, 2, 316, 317, 7, 60, 2, 2, 317, 22, 3, 2, + 2, 2, 318, 319, 7, 126, 2, 2, 319, 24, 3, 2, 2, 2, 320, 321, 7, 48, 2, + 2, 321, 322, 7, 48, 2, 2, 322, 26, 3, 2, 2, 2, 323, 324, 7, 45, 2, 2, 324, + 28, 3, 2, 2, 2, 325, 326, 7, 47, 2, 2, 326, 30, 3, 2, 2, 2, 327, 328, 7, + 49, 2, 2, 328, 32, 3, 2, 2, 2, 329, 330, 7, 39, 2, 2, 330, 34, 3, 2, 2, + 2, 331, 332, 7, 96, 2, 2, 332, 36, 3, 2, 2, 2, 333, 334, 7, 62, 2, 2, 334, + 335, 7, 64, 2, 2, 335, 38, 3, 2, 2, 2, 336, 337, 7, 62, 2, 2, 337, 40, + 3, 2, 2, 2, 338, 339, 7, 64, 2, 2, 339, 42, 3, 2, 2, 2, 340, 341, 7, 62, + 2, 2, 341, 342, 7, 63, 2, 2, 342, 44, 3, 2, 2, 2, 343, 344, 7, 64, 2, 2, + 344, 345, 7, 63, 2, 2, 345, 46, 3, 2, 2, 2, 346, 347, 7, 48, 2, 2, 347, + 48, 3, 2, 2, 2, 348, 349, 7, 125, 2, 2, 349, 50, 3, 2, 2, 2, 350, 351, + 7, 127, 2, 2, 351, 52, 3, 2, 2, 2, 352, 353, 7, 38, 2, 2, 353, 54, 3, 2, + 2, 2, 354, 355, 7, 10218, 2, 2, 355, 56, 3, 2, 2, 2, 356, 357, 7, 12298, + 2, 2, 357, 58, 3, 2, 2, 2, 358, 359, 7, 65126, 2, 2, 359, 60, 3, 2, 2, + 2, 360, 361, 7, 65310, 2, 2, 361, 62, 3, 2, 2, 2, 362, 363, 7, 10219, 2, + 2, 363, 64, 3, 2, 2, 2, 364, 365, 7, 12299, 2, 2, 365, 66, 3, 2, 2, 2, + 366, 367, 7, 65127, 2, 2, 367, 68, 3, 2, 2, 2, 368, 369, 7, 65312, 2, 2, + 369, 70, 3, 2, 2, 2, 370, 371, 7, 175, 2, 2, 371, 72, 3, 2, 2, 2, 372, + 373, 7, 8210, 2, 2, 373, 74, 3, 2, 2, 2, 374, 375, 7, 8211, 2, 2, 375, + 76, 3, 2, 2, 2, 376, 377, 7, 8212, 2, 2, 377, 78, 3, 2, 2, 2, 378, 379, + 7, 8213, 2, 2, 379, 80, 3, 2, 2, 2, 380, 381, 7, 8214, 2, 2, 381, 82, 3, + 2, 2, 2, 382, 383, 7, 8215, 2, 2, 383, 84, 3, 2, 2, 2, 384, 385, 7, 8724, + 2, 2, 385, 86, 3, 2, 2, 2, 386, 387, 7, 65114, 2, 2, 387, 88, 3, 2, 2, + 2, 388, 389, 7, 65125, 2, 2, 389, 90, 3, 2, 2, 2, 390, 391, 7, 65295, 2, + 2, 391, 92, 3, 2, 2, 2, 392, 393, 9, 2, 2, 2, 393, 394, 9, 3, 2, 2, 394, + 395, 9, 4, 2, 2, 395, 396, 9, 5, 2, 2, 396, 397, 9, 3, 2, 2, 397, 94, 3, + 2, 2, 2, 398, 399, 9, 6, 2, 2, 399, 400, 9, 7, 2, 2, 400, 401, 9, 7, 2, + 2, 401, 96, 3, 2, 2, 2, 402, 403, 9, 5, 2, 2, 403, 404, 9, 8, 2, 2, 404, + 405, 9, 9, 2, 2, 405, 406, 9, 4, 2, 2, 406, 407, 9, 5, 2, 2, 407, 408, + 9, 3, 2, 2, 408, 409, 9, 6, 2, 2, 409, 410, 9, 7, 2, 2, 410, 98, 3, 2, + 2, 2, 411, 412, 9, 10, 2, 2, 412, 413, 9, 6, 2, 2, 413, 414, 9, 9, 2, 2, + 414, 415, 9, 11, 2, 2, 415, 416, 9, 12, 2, 2, 416, 100, 3, 2, 2, 2, 417, + 418, 9, 2, 2, 2, 418, 419, 9, 3, 2, 2, 419, 420, 9, 13, 2, 2, 420, 421, + 9, 4, 2, 2, 421, 422, 9, 3, 2, 2, 422, 423, 9, 14, 2, 2, 423, 102, 3, 2, + 2, 2, 424, 425, 9, 6, 2, 2, 425, 426, 9, 15, 2, 2, 426, 104, 3, 2, 2, 2, + 427, 428, 9, 10, 2, 2, 428, 429, 9, 16, 2, 2, 429, 430, 9, 17, 2, 2, 430, + 431, 9, 18, 2, 2, 431, 432, 9, 16, 2, 2, 432, 106, 3, 2, 2, 2, 433, 434, + 9, 5, 2, 2, 434, 435, 9, 3, 2, 2, 435, 108, 3, 2, 2, 2, 436, 437, 9, 11, + 2, 2, 437, 438, 9, 17, 2, 2, 438, 439, 9, 16, 2, 2, 439, 440, 9, 6, 2, + 2, 440, 441, 9, 9, 2, 2, 441, 442, 9, 16, 2, 2, 442, 110, 3, 2, 2, 2, 443, + 444, 9, 15, 2, 2, 444, 445, 9, 16, 2, 2, 445, 446, 9, 9, 2, 2, 446, 112, + 3, 2, 2, 2, 447, 448, 9, 14, 2, 2, 448, 449, 9, 16, 2, 2, 449, 450, 9, + 9, 2, 2, 450, 451, 9, 6, 2, 2, 451, 452, 9, 11, 2, 2, 452, 453, 9, 12, + 2, 2, 453, 114, 3, 2, 2, 2, 454, 455, 9, 14, 2, 2, 455, 456, 9, 16, 2, + 2, 456, 457, 9, 7, 2, 2, 457, 458, 9, 16, 2, 2, 458, 459, 9, 9, 2, 2, 459, + 460, 9, 16, 2, 2, 460, 116, 3, 2, 2, 2, 461, 462, 9, 17, 2, 2, 462, 463, + 9, 16, 2, 2, 463, 464, 9, 10, 2, 2, 464, 465, 9, 5, 2, 2, 465, 466, 9, + 19, 2, 2, 466, 467, 9, 16, 2, 2, 467, 118, 3, 2, 2, 2, 468, 469, 9, 11, + 2, 2, 469, 470, 9, 6, 2, 2, 470, 471, 9, 7, 2, 2, 471, 472, 9, 7, 2, 2, + 472, 120, 3, 2, 2, 2, 473, 474, 9, 20, 2, 2, 474, 475, 9, 4, 2, 2, 475, + 476, 9, 16, 2, 2, 476, 477, 9, 7, 2, 2, 477, 478, 9, 14, 2, 2, 478, 122, + 3, 2, 2, 2, 479, 480, 9, 13, 2, 2, 480, 481, 9, 4, 2, 2, 481, 482, 9, 9, + 2, 2, 482, 483, 9, 12, 2, 2, 483, 124, 3, 2, 2, 2, 484, 485, 9, 17, 2, + 2, 485, 486, 9, 16, 2, 2, 486, 487, 9, 9, 2, 2, 487, 488, 9, 2, 2, 2, 488, + 489, 9, 17, 2, 2, 489, 490, 9, 3, 2, 2, 490, 126, 3, 2, 2, 2, 491, 492, + 9, 14, 2, 2, 492, 493, 9, 4, 2, 2, 493, 494, 9, 15, 2, 2, 494, 495, 9, + 9, 2, 2, 495, 496, 9, 4, 2, 2, 496, 497, 9, 3, 2, 2, 497, 498, 9, 11, 2, + 2, 498, 499, 9, 9, 2, 2, 499, 128, 3, 2, 2, 2, 500, 501, 9, 5, 2, 2, 501, + 502, 9, 17, 2, 2, 502, 503, 9, 14, 2, 2, 503, 504, 9, 16, 2, 2, 504, 505, + 9, 17, 2, 2, 505, 130, 3, 2, 2, 2, 506, 507, 9, 21, 2, 2, 507, 508, 9, + 20, 2, 2, 508, 132, 3, 2, 2, 2, 509, 510, 9, 15, 2, 2, 510, 511, 9, 22, + 2, 2, 511, 512, 9, 4, 2, 2, 512, 513, 9, 8, 2, 2, 513, 134, 3, 2, 2, 2, + 514, 515, 9, 7, 2, 2, 515, 516, 9, 4, 2, 2, 516, 517, 9, 10, 2, 2, 517, + 518, 9, 4, 2, 2, 518, 519, 9, 9, 2, 2, 519, 136, 3, 2, 2, 2, 520, 521, + 9, 6, 2, 2, 521, 522, 9, 15, 2, 2, 522, 523, 9, 11, 2, 2, 523, 524, 9, + 16, 2, 2, 524, 525, 9, 3, 2, 2, 525, 526, 9, 14, 2, 2, 526, 527, 9, 4, + 2, 2, 527, 528, 9, 3, 2, 2, 528, 529, 9, 18, 2, 2, 529, 138, 3, 2, 2, 2, + 530, 531, 9, 6, 2, 2, 531, 532, 9, 15, 2, 2, 532, 533, 9, 11, 2, 2, 533, + 140, 3, 2, 2, 2, 534, 535, 9, 14, 2, 2, 535, 536, 9, 16, 2, 2, 536, 537, + 9, 15, 2, 2, 537, 538, 9, 11, 2, 2, 538, 539, 9, 16, 2, 2, 539, 540, 9, + 3, 2, 2, 540, 541, 9, 14, 2, 2, 541, 542, 9, 4, 2, 2, 542, 543, 9, 3, 2, + 2, 543, 544, 9, 18, 2, 2, 544, 142, 3, 2, 2, 2, 545, 546, 9, 14, 2, 2, + 546, 547, 9, 16, 2, 2, 547, 548, 9, 15, 2, 2, 548, 549, 9, 11, 2, 2, 549, + 144, 3, 2, 2, 2, 550, 551, 9, 13, 2, 2, 551, 552, 9, 12, 2, 2, 552, 553, + 9, 16, 2, 2, 553, 554, 9, 17, 2, 2, 554, 555, 9, 16, 2, 2, 555, 146, 3, + 2, 2, 2, 556, 557, 9, 5, 2, 2, 557, 558, 9, 17, 2, 2, 558, 148, 3, 2, 2, + 2, 559, 560, 9, 23, 2, 2, 560, 561, 9, 5, 2, 2, 561, 562, 9, 17, 2, 2, + 562, 150, 3, 2, 2, 2, 563, 564, 9, 6, 2, 2, 564, 565, 9, 3, 2, 2, 565, + 566, 9, 14, 2, 2, 566, 152, 3, 2, 2, 2, 567, 568, 9, 3, 2, 2, 568, 569, + 9, 5, 2, 2, 569, 570, 9, 9, 2, 2, 570, 154, 3, 2, 2, 2, 571, 572, 9, 4, + 2, 2, 572, 573, 9, 3, 2, 2, 573, 156, 3, 2, 2, 2, 574, 575, 9, 15, 2, 2, + 575, 576, 9, 9, 2, 2, 576, 577, 9, 6, 2, 2, 577, 578, 9, 17, 2, 2, 578, + 579, 9, 9, 2, 2, 579, 580, 9, 15, 2, 2, 580, 158, 3, 2, 2, 2, 581, 582, + 9, 16, 2, 2, 582, 583, 9, 3, 2, 2, 583, 584, 9, 14, 2, 2, 584, 585, 9, + 15, 2, 2, 585, 160, 3, 2, 2, 2, 586, 587, 9, 11, 2, 2, 587, 588, 9, 5, + 2, 2, 588, 589, 9, 3, 2, 2, 589, 590, 9, 9, 2, 2, 590, 591, 9, 6, 2, 2, + 591, 592, 9, 4, 2, 2, 592, 593, 9, 3, 2, 2, 593, 594, 9, 15, 2, 2, 594, + 162, 3, 2, 2, 2, 595, 596, 9, 4, 2, 2, 596, 597, 9, 15, 2, 2, 597, 164, + 3, 2, 2, 2, 598, 599, 9, 3, 2, 2, 599, 600, 9, 2, 2, 2, 600, 601, 9, 7, + 2, 2, 601, 602, 9, 7, 2, 2, 602, 166, 3, 2, 2, 2, 603, 604, 9, 11, 2, 2, + 604, 605, 9, 5, 2, 2, 605, 606, 9, 2, 2, 2, 606, 607, 9, 3, 2, 2, 607, + 608, 9, 9, 2, 2, 608, 168, 3, 2, 2, 2, 609, 610, 9, 6, 2, 2, 610, 611, + 9, 3, 2, 2, 611, 612, 9, 20, 2, 2, 612, 170, 3, 2, 2, 2, 613, 614, 9, 3, + 2, 2, 614, 615, 9, 5, 2, 2, 615, 616, 9, 3, 2, 2, 616, 617, 9, 16, 2, 2, + 617, 172, 3, 2, 2, 2, 618, 619, 9, 15, 2, 2, 619, 620, 9, 4, 2, 2, 620, + 621, 9, 3, 2, 2, 621, 622, 9, 18, 2, 2, 622, 623, 9, 7, 2, 2, 623, 624, + 9, 16, 2, 2, 624, 174, 3, 2, 2, 2, 625, 626, 9, 9, 2, 2, 626, 627, 9, 17, + 2, 2, 627, 628, 9, 2, 2, 2, 628, 629, 9, 16, 2, 2, 629, 176, 3, 2, 2, 2, + 630, 631, 9, 24, 2, 2, 631, 632, 9, 6, 2, 2, 632, 633, 9, 7, 2, 2, 633, + 634, 9, 15, 2, 2, 634, 635, 9, 16, 2, 2, 635, 178, 3, 2, 2, 2, 636, 637, + 9, 16, 2, 2, 637, 638, 9, 23, 2, 2, 638, 639, 9, 4, 2, 2, 639, 640, 9, + 15, 2, 2, 640, 641, 9, 9, 2, 2, 641, 642, 9, 15, 2, 2, 642, 180, 3, 2, + 2, 2, 643, 644, 9, 11, 2, 2, 644, 645, 9, 6, 2, 2, 645, 646, 9, 15, 2, + 2, 646, 647, 9, 16, 2, 2, 647, 182, 3, 2, 2, 2, 648, 649, 9, 16, 2, 2, + 649, 650, 9, 7, 2, 2, 650, 651, 9, 15, 2, 2, 651, 652, 9, 16, 2, 2, 652, + 184, 3, 2, 2, 2, 653, 654, 9, 16, 2, 2, 654, 655, 9, 3, 2, 2, 655, 656, + 9, 14, 2, 2, 656, 186, 3, 2, 2, 2, 657, 658, 9, 13, 2, 2, 658, 659, 9, + 12, 2, 2, 659, 660, 9, 16, 2, 2, 660, 661, 9, 3, 2, 2, 661, 188, 3, 2, + 2, 2, 662, 663, 9, 9, 2, 2, 663, 664, 9, 12, 2, 2, 664, 665, 9, 16, 2, + 2, 665, 666, 9, 3, 2, 2, 666, 190, 3, 2, 2, 2, 667, 672, 7, 36, 2, 2, 668, + 671, 5, 287, 144, 2, 669, 671, 5, 193, 97, 2, 670, 668, 3, 2, 2, 2, 670, + 669, 3, 2, 2, 2, 671, 674, 3, 2, 2, 2, 672, 670, 3, 2, 2, 2, 672, 673, + 3, 2, 2, 2, 673, 675, 3, 2, 2, 2, 674, 672, 3, 2, 2, 2, 675, 686, 7, 36, + 2, 2, 676, 681, 7, 41, 2, 2, 677, 680, 5, 267, 134, 2, 678, 680, 5, 193, + 97, 2, 679, 677, 3, 2, 2, 2, 679, 678, 3, 2, 2, 2, 680, 683, 3, 2, 2, 2, + 681, 679, 3, 2, 2, 2, 681, 682, 3, 2, 2, 2, 682, 684, 3, 2, 2, 2, 683, + 681, 3, 2, 2, 2, 684, 686, 7, 41, 2, 2, 685, 667, 3, 2, 2, 2, 685, 676, + 3, 2, 2, 2, 686, 192, 3, 2, 2, 2, 687, 705, 7, 94, 2, 2, 688, 706, 9, 25, + 2, 2, 689, 690, 9, 2, 2, 2, 690, 691, 5, 203, 102, 2, 691, 692, 5, 203, + 102, 2, 692, 693, 5, 203, 102, 2, 693, 694, 5, 203, 102, 2, 694, 706, 3, + 2, 2, 2, 695, 696, 9, 2, 2, 2, 696, 697, 5, 203, 102, 2, 697, 698, 5, 203, + 102, 2, 698, 699, 5, 203, 102, 2, 699, 700, 5, 203, 102, 2, 700, 701, 5, + 203, 102, 2, 701, 702, 5, 203, 102, 2, 702, 703, 5, 203, 102, 2, 703, 704, + 5, 203, 102, 2, 704, 706, 3, 2, 2, 2, 705, 688, 3, 2, 2, 2, 705, 689, 3, + 2, 2, 2, 705, 695, 3, 2, 2, 2, 706, 194, 3, 2, 2, 2, 707, 708, 7, 50, 2, + 2, 708, 709, 7, 122, 2, 2, 709, 711, 3, 2, 2, 2, 710, 712, 5, 203, 102, + 2, 711, 710, 3, 2, 2, 2, 712, 713, 3, 2, 2, 2, 713, 711, 3, 2, 2, 2, 713, + 714, 3, 2, 2, 2, 714, 196, 3, 2, 2, 2, 715, 724, 5, 213, 107, 2, 716, 720, + 5, 207, 104, 2, 717, 719, 5, 205, 103, 2, 718, 717, 3, 2, 2, 2, 719, 722, + 3, 2, 2, 2, 720, 718, 3, 2, 2, 2, 720, 721, 3, 2, 2, 2, 721, 724, 3, 2, + 2, 2, 722, 720, 3, 2, 2, 2, 723, 715, 3, 2, 2, 2, 723, 716, 3, 2, 2, 2, + 724, 198, 3, 2, 2, 2, 725, 727, 5, 213, 107, 2, 726, 728, 5, 211, 106, + 2, 727, 726, 3, 2, 2, 2, 728, 729, 3, 2, 2, 2, 729, 727, 3, 2, 2, 2, 729, + 730, 3, 2, 2, 2, 730, 200, 3, 2, 2, 2, 731, 733, 9, 26, 2, 2, 732, 731, + 3, 2, 2, 2, 733, 202, 3, 2, 2, 2, 734, 737, 5, 205, 103, 2, 735, 737, 5, + 201, 101, 2, 736, 734, 3, 2, 2, 2, 736, 735, 3, 2, 2, 2, 737, 204, 3, 2, + 2, 2, 738, 741, 5, 213, 107, 2, 739, 741, 5, 207, 104, 2, 740, 738, 3, + 2, 2, 2, 740, 739, 3, 2, 2, 2, 741, 206, 3, 2, 2, 2, 742, 745, 5, 209, + 105, 2, 743, 745, 4, 58, 59, 2, 744, 742, 3, 2, 2, 2, 744, 743, 3, 2, 2, + 2, 745, 208, 3, 2, 2, 2, 746, 747, 4, 51, 57, 2, 747, 210, 3, 2, 2, 2, + 748, 751, 5, 213, 107, 2, 749, 751, 5, 209, 105, 2, 750, 748, 3, 2, 2, + 2, 750, 749, 3, 2, 2, 2, 751, 212, 3, 2, 2, 2, 752, 753, 7, 50, 2, 2, 753, + 214, 3, 2, 2, 2, 754, 756, 5, 205, 103, 2, 755, 754, 3, 2, 2, 2, 756, 757, + 3, 2, 2, 2, 757, 755, 3, 2, 2, 2, 757, 758, 3, 2, 2, 2, 758, 777, 3, 2, + 2, 2, 759, 761, 5, 205, 103, 2, 760, 759, 3, 2, 2, 2, 761, 762, 3, 2, 2, + 2, 762, 760, 3, 2, 2, 2, 762, 763, 3, 2, 2, 2, 763, 764, 3, 2, 2, 2, 764, + 766, 7, 48, 2, 2, 765, 767, 5, 205, 103, 2, 766, 765, 3, 2, 2, 2, 767, + 768, 3, 2, 2, 2, 768, 766, 3, 2, 2, 2, 768, 769, 3, 2, 2, 2, 769, 777, + 3, 2, 2, 2, 770, 772, 7, 48, 2, 2, 771, 773, 5, 205, 103, 2, 772, 771, + 3, 2, 2, 2, 773, 774, 3, 2, 2, 2, 774, 772, 3, 2, 2, 2, 774, 775, 3, 2, + 2, 2, 775, 777, 3, 2, 2, 2, 776, 755, 3, 2, 2, 2, 776, 760, 3, 2, 2, 2, + 776, 770, 3, 2, 2, 2, 777, 778, 3, 2, 2, 2, 778, 780, 9, 16, 2, 2, 779, + 781, 7, 47, 2, 2, 780, 779, 3, 2, 2, 2, 780, 781, 3, 2, 2, 2, 781, 783, + 3, 2, 2, 2, 782, 784, 5, 205, 103, 2, 783, 782, 3, 2, 2, 2, 784, 785, 3, + 2, 2, 2, 785, 783, 3, 2, 2, 2, 785, 786, 3, 2, 2, 2, 786, 216, 3, 2, 2, + 2, 787, 789, 5, 205, 103, 2, 788, 787, 3, 2, 2, 2, 789, 792, 3, 2, 2, 2, + 790, 788, 3, 2, 2, 2, 790, 791, 3, 2, 2, 2, 791, 793, 3, 2, 2, 2, 792, + 790, 3, 2, 2, 2, 793, 795, 7, 48, 2, 2, 794, 796, 5, 205, 103, 2, 795, + 794, 3, 2, 2, 2, 796, 797, 3, 2, 2, 2, 797, 795, 3, 2, 2, 2, 797, 798, + 3, 2, 2, 2, 798, 218, 3, 2, 2, 2, 799, 800, 9, 11, 2, 2, 800, 801, 9, 5, + 2, 2, 801, 802, 9, 3, 2, 2, 802, 803, 9, 15, 2, 2, 803, 804, 9, 9, 2, 2, + 804, 805, 9, 17, 2, 2, 805, 806, 9, 6, 2, 2, 806, 807, 9, 4, 2, 2, 807, + 808, 9, 3, 2, 2, 808, 809, 9, 9, 2, 2, 809, 220, 3, 2, 2, 2, 810, 811, + 9, 14, 2, 2, 811, 812, 9, 5, 2, 2, 812, 222, 3, 2, 2, 2, 813, 814, 9, 24, + 2, 2, 814, 815, 9, 5, 2, 2, 815, 816, 9, 17, 2, 2, 816, 224, 3, 2, 2, 2, + 817, 818, 9, 17, 2, 2, 818, 819, 9, 16, 2, 2, 819, 820, 9, 27, 2, 2, 820, + 821, 9, 2, 2, 2, 821, 822, 9, 4, 2, 2, 822, 823, 9, 17, 2, 2, 823, 824, + 9, 16, 2, 2, 824, 226, 3, 2, 2, 2, 825, 826, 9, 2, 2, 2, 826, 827, 9, 3, + 2, 2, 827, 828, 9, 4, 2, 2, 828, 829, 9, 27, 2, 2, 829, 830, 9, 2, 2, 2, + 830, 831, 9, 16, 2, 2, 831, 228, 3, 2, 2, 2, 832, 833, 9, 10, 2, 2, 833, + 834, 9, 6, 2, 2, 834, 835, 9, 3, 2, 2, 835, 836, 9, 14, 2, 2, 836, 837, + 9, 6, 2, 2, 837, 838, 9, 9, 2, 2, 838, 839, 9, 5, 2, 2, 839, 840, 9, 17, + 2, 2, 840, 841, 9, 20, 2, 2, 841, 230, 3, 2, 2, 2, 842, 843, 9, 15, 2, + 2, 843, 844, 9, 11, 2, 2, 844, 845, 9, 6, 2, 2, 845, 846, 9, 7, 2, 2, 846, + 847, 9, 6, 2, 2, 847, 848, 9, 17, 2, 2, 848, 232, 3, 2, 2, 2, 849, 850, + 9, 5, 2, 2, 850, 851, 9, 24, 2, 2, 851, 234, 3, 2, 2, 2, 852, 853, 9, 6, + 2, 2, 853, 854, 9, 14, 2, 2, 854, 855, 9, 14, 2, 2, 855, 236, 3, 2, 2, + 2, 856, 857, 9, 14, 2, 2, 857, 858, 9, 17, 2, 2, 858, 859, 9, 5, 2, 2, + 859, 860, 9, 8, 2, 2, 860, 238, 3, 2, 2, 2, 861, 862, 9, 24, 2, 2, 862, + 863, 9, 4, 2, 2, 863, 864, 9, 7, 2, 2, 864, 865, 9, 9, 2, 2, 865, 866, + 9, 16, 2, 2, 866, 867, 9, 17, 2, 2, 867, 240, 3, 2, 2, 2, 868, 869, 9, + 16, 2, 2, 869, 870, 9, 23, 2, 2, 870, 871, 9, 9, 2, 2, 871, 872, 9, 17, + 2, 2, 872, 873, 9, 6, 2, 2, 873, 874, 9, 11, 2, 2, 874, 875, 9, 9, 2, 2, + 875, 242, 3, 2, 2, 2, 876, 880, 5, 245, 123, 2, 877, 879, 5, 247, 124, + 2, 878, 877, 3, 2, 2, 2, 879, 882, 3, 2, 2, 2, 880, 878, 3, 2, 2, 2, 880, + 881, 3, 2, 2, 2, 881, 244, 3, 2, 2, 2, 882, 880, 3, 2, 2, 2, 883, 886, + 5, 295, 148, 2, 884, 886, 5, 283, 142, 2, 885, 883, 3, 2, 2, 2, 885, 884, + 3, 2, 2, 2, 886, 246, 3, 2, 2, 2, 887, 890, 5, 263, 132, 2, 888, 890, 5, + 279, 140, 2, 889, 887, 3, 2, 2, 2, 889, 888, 3, 2, 2, 2, 890, 248, 3, 2, + 2, 2, 891, 895, 7, 98, 2, 2, 892, 894, 5, 259, 130, 2, 893, 892, 3, 2, + 2, 2, 894, 897, 3, 2, 2, 2, 895, 893, 3, 2, 2, 2, 895, 896, 3, 2, 2, 2, + 896, 898, 3, 2, 2, 2, 897, 895, 3, 2, 2, 2, 898, 900, 7, 98, 2, 2, 899, + 891, 3, 2, 2, 2, 900, 901, 3, 2, 2, 2, 901, 899, 3, 2, 2, 2, 901, 902, + 3, 2, 2, 2, 902, 250, 3, 2, 2, 2, 903, 905, 5, 253, 127, 2, 904, 903, 3, + 2, 2, 2, 905, 906, 3, 2, 2, 2, 906, 904, 3, 2, 2, 2, 906, 907, 3, 2, 2, + 2, 907, 252, 3, 2, 2, 2, 908, 921, 5, 281, 141, 2, 909, 921, 5, 285, 143, + 2, 910, 921, 5, 289, 145, 2, 911, 921, 5, 291, 146, 2, 912, 921, 5, 257, + 129, 2, 913, 921, 5, 277, 139, 2, 914, 921, 5, 275, 138, 2, 915, 921, 5, + 273, 137, 2, 916, 921, 5, 261, 131, 2, 917, 921, 5, 293, 147, 2, 918, 921, + 9, 28, 2, 2, 919, 921, 5, 255, 128, 2, 920, 908, 3, 2, 2, 2, 920, 909, + 3, 2, 2, 2, 920, 910, 3, 2, 2, 2, 920, 911, 3, 2, 2, 2, 920, 912, 3, 2, + 2, 2, 920, 913, 3, 2, 2, 2, 920, 914, 3, 2, 2, 2, 920, 915, 3, 2, 2, 2, + 920, 916, 3, 2, 2, 2, 920, 917, 3, 2, 2, 2, 920, 918, 3, 2, 2, 2, 920, + 919, 3, 2, 2, 2, 921, 254, 3, 2, 2, 2, 922, 923, 7, 49, 2, 2, 923, 924, + 7, 44, 2, 2, 924, 930, 3, 2, 2, 2, 925, 929, 5, 265, 133, 2, 926, 927, + 7, 44, 2, 2, 927, 929, 5, 271, 136, 2, 928, 925, 3, 2, 2, 2, 928, 926, + 3, 2, 2, 2, 929, 932, 3, 2, 2, 2, 930, 928, 3, 2, 2, 2, 930, 931, 3, 2, + 2, 2, 931, 933, 3, 2, 2, 2, 932, 930, 3, 2, 2, 2, 933, 934, 7, 44, 2, 2, + 934, 952, 7, 49, 2, 2, 935, 936, 7, 49, 2, 2, 936, 937, 7, 49, 2, 2, 937, + 941, 3, 2, 2, 2, 938, 940, 5, 269, 135, 2, 939, 938, 3, 2, 2, 2, 940, 943, + 3, 2, 2, 2, 941, 939, 3, 2, 2, 2, 941, 942, 3, 2, 2, 2, 942, 945, 3, 2, + 2, 2, 943, 941, 3, 2, 2, 2, 944, 946, 5, 277, 139, 2, 945, 944, 3, 2, 2, + 2, 945, 946, 3, 2, 2, 2, 946, 949, 3, 2, 2, 2, 947, 950, 5, 289, 145, 2, + 948, 950, 7, 2, 2, 3, 949, 947, 3, 2, 2, 2, 949, 948, 3, 2, 2, 2, 950, + 952, 3, 2, 2, 2, 951, 922, 3, 2, 2, 2, 951, 935, 3, 2, 2, 2, 952, 256, + 3, 2, 2, 2, 953, 954, 9, 29, 2, 2, 954, 258, 3, 2, 2, 2, 955, 956, 10, + 30, 2, 2, 956, 260, 3, 2, 2, 2, 957, 958, 9, 31, 2, 2, 958, 262, 3, 2, + 2, 2, 959, 960, 9, 47, 2, 2, 960, 264, 3, 2, 2, 2, 961, 962, 10, 32, 2, + 2, 962, 266, 3, 2, 2, 2, 963, 964, 10, 33, 2, 2, 964, 268, 3, 2, 2, 2, + 965, 966, 10, 34, 2, 2, 966, 270, 3, 2, 2, 2, 967, 968, 10, 35, 2, 2, 968, + 272, 3, 2, 2, 2, 969, 970, 9, 36, 2, 2, 970, 274, 3, 2, 2, 2, 971, 972, + 9, 37, 2, 2, 972, 276, 3, 2, 2, 2, 973, 974, 9, 38, 2, 2, 974, 278, 3, + 2, 2, 2, 975, 976, 9, 39, 2, 2, 976, 280, 3, 2, 2, 2, 977, 978, 9, 40, + 2, 2, 978, 282, 3, 2, 2, 2, 979, 980, 9, 41, 2, 2, 980, 284, 3, 2, 2, 2, + 981, 982, 9, 42, 2, 2, 982, 286, 3, 2, 2, 2, 983, 984, 10, 43, 2, 2, 984, + 288, 3, 2, 2, 2, 985, 986, 9, 44, 2, 2, 986, 290, 3, 2, 2, 2, 987, 988, + 9, 45, 2, 2, 988, 292, 3, 2, 2, 2, 989, 990, 9, 46, 2, 2, 990, 294, 3, + 2, 2, 2, 991, 992, 9, 48, 2, 2, 992, 296, 3, 2, 2, 2, 40, 2, 670, 672, + 679, 681, 685, 705, 713, 720, 723, 729, 732, 736, 740, 744, 750, 757, 762, + 768, 774, 776, 780, 785, 790, 797, 880, 885, 889, 895, 901, 906, 920, 928, + 930, 941, 945, 949, 951, 2, +} + +var lexerChannelNames = []string{ + "DEFAULT_TOKEN_CHANNEL", "HIDDEN", +} + +var lexerModeNames = []string{ + "DEFAULT_MODE", +} + +var lexerLiteralNames = []string{ + "", "';'", "','", "'='", "'+='", "'*'", "'('", "')'", "'['", "']'", "':'", + "'|'", "'..'", "'+'", "'-'", "'/'", "'%'", "'^'", "'<>'", "'<'", "'>'", + "'<='", "'>='", "'.'", "'{'", "'}'", "'$'", "'\u27E8'", "'\u3008'", "'\uFE64'", + "'\uFF1C'", "'\u27E9'", "'\u3009'", "'\uFE65'", "'\uFF1E'", "'\u00AD'", + "'\u2010'", "'\u2011'", "'\u2012'", "'\u2013'", "'\u2014'", "'\u2015'", + "'\u2212'", "'\uFE58'", "'\uFE63'", "'\uFF0D'", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", + "'0'", +} + +var lexerSymbolicNames = []string{ + "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", "UNION", "ALL", "OPTIONAL", "MATCH", + "UNWIND", "AS", "MERGE", "ON", "CREATE", "SET", "DETACH", "DELETE", "REMOVE", + "CALL", "YIELD", "WITH", "RETURN", "DISTINCT", "ORDER", "BY", "L_SKIP", + "LIMIT", "ASCENDING", "ASC", "DESCENDING", "DESC", "WHERE", "OR", "XOR", + "AND", "NOT", "IN", "STARTS", "ENDS", "CONTAINS", "IS", "NULL", "COUNT", + "ANY", "NONE", "SINGLE", "TRUE", "FALSE", "EXISTS", "CASE", "ELSE", "END", + "WHEN", "THEN", "StringLiteral", "EscapedChar", "HexInteger", "DecimalInteger", + "OctalInteger", "HexLetter", "HexDigit", "Digit", "NonZeroDigit", "NonZeroOctDigit", + "OctDigit", "ZeroDigit", "ExponentDecimalReal", "RegularDecimalReal", "CONSTRAINT", + "DO", "FOR", "REQUIRE", "UNIQUE", "MANDATORY", "SCALAR", "OF", "ADD", "DROP", + "FILTER", "EXTRACT", "UnescapedSymbolicName", "IdentifierStart", "IdentifierPart", + "EscapedSymbolicName", "SP", "WHITESPACE", "Comment", +} + +var lexerRuleNames = []string{ + "T__0", "T__1", "T__2", "T__3", "T__4", "T__5", "T__6", "T__7", "T__8", + "T__9", "T__10", "T__11", "T__12", "T__13", "T__14", "T__15", "T__16", + "T__17", "T__18", "T__19", "T__20", "T__21", "T__22", "T__23", "T__24", + "T__25", "T__26", "T__27", "T__28", "T__29", "T__30", "T__31", "T__32", + "T__33", "T__34", "T__35", "T__36", "T__37", "T__38", "T__39", "T__40", + "T__41", "T__42", "T__43", "T__44", "UNION", "ALL", "OPTIONAL", "MATCH", + "UNWIND", "AS", "MERGE", "ON", "CREATE", "SET", "DETACH", "DELETE", "REMOVE", + "CALL", "YIELD", "WITH", "RETURN", "DISTINCT", "ORDER", "BY", "L_SKIP", + "LIMIT", "ASCENDING", "ASC", "DESCENDING", "DESC", "WHERE", "OR", "XOR", + "AND", "NOT", "IN", "STARTS", "ENDS", "CONTAINS", "IS", "NULL", "COUNT", + "ANY", "NONE", "SINGLE", "TRUE", "FALSE", "EXISTS", "CASE", "ELSE", "END", + "WHEN", "THEN", "StringLiteral", "EscapedChar", "HexInteger", "DecimalInteger", + "OctalInteger", "HexLetter", "HexDigit", "Digit", "NonZeroDigit", "NonZeroOctDigit", + "OctDigit", "ZeroDigit", "ExponentDecimalReal", "RegularDecimalReal", "CONSTRAINT", + "DO", "FOR", "REQUIRE", "UNIQUE", "MANDATORY", "SCALAR", "OF", "ADD", "DROP", + "FILTER", "EXTRACT", "UnescapedSymbolicName", "IdentifierStart", "IdentifierPart", + "EscapedSymbolicName", "SP", "WHITESPACE", "Comment", "FF", "EscapedSymbolicName_0", + "RS", "ID_Continue", "Comment_1", "StringLiteral_1", "Comment_3", "Comment_2", + "GS", "FS", "CR", "Sc", "SPACE", "Pc", "TAB", "StringLiteral_0", "LF", + "VT", "US", "ID_Start", +} + +type CypherLexer struct { + *antlr.BaseLexer + channelNames []string + modeNames []string + // TODO: EOF string +} + +// NewCypherLexer produces a new lexer instance for the optional input antlr.CharStream. +// +// The *CypherLexer instance produced may be reused by calling the SetInputStream method. +// The initial lexer configuration is expensive to construct, and the object is not thread-safe; +// however, if used within a Golang sync.Pool, the construction cost amortizes well and the +// objects can be used in a thread-safe manner. +func NewCypherLexer(input antlr.CharStream) *CypherLexer { + l := new(CypherLexer) + lexerDeserializer := antlr.NewATNDeserializer(nil) + lexerAtn := lexerDeserializer.DeserializeFromUInt16(serializedLexerAtn) + lexerDecisionToDFA := make([]*antlr.DFA, len(lexerAtn.DecisionToState)) + for index, ds := range lexerAtn.DecisionToState { + lexerDecisionToDFA[index] = antlr.NewDFA(ds, index) + } + l.BaseLexer = antlr.NewBaseLexer(input) + l.Interpreter = antlr.NewLexerATNSimulator(l, lexerAtn, lexerDecisionToDFA, antlr.NewPredictionContextCache()) + + l.channelNames = lexerChannelNames + l.modeNames = lexerModeNames + l.RuleNames = lexerRuleNames + l.LiteralNames = lexerLiteralNames + l.SymbolicNames = lexerSymbolicNames + l.GrammarFileName = "Cypher.g4" + // TODO: l.EOF = antlr.TokenEOF + + return l +} + +// CypherLexer tokens. +const ( + CypherLexerT__0 = 1 + CypherLexerT__1 = 2 + CypherLexerT__2 = 3 + CypherLexerT__3 = 4 + CypherLexerT__4 = 5 + CypherLexerT__5 = 6 + CypherLexerT__6 = 7 + CypherLexerT__7 = 8 + CypherLexerT__8 = 9 + CypherLexerT__9 = 10 + CypherLexerT__10 = 11 + CypherLexerT__11 = 12 + CypherLexerT__12 = 13 + CypherLexerT__13 = 14 + CypherLexerT__14 = 15 + CypherLexerT__15 = 16 + CypherLexerT__16 = 17 + CypherLexerT__17 = 18 + CypherLexerT__18 = 19 + CypherLexerT__19 = 20 + CypherLexerT__20 = 21 + CypherLexerT__21 = 22 + CypherLexerT__22 = 23 + CypherLexerT__23 = 24 + CypherLexerT__24 = 25 + CypherLexerT__25 = 26 + CypherLexerT__26 = 27 + CypherLexerT__27 = 28 + CypherLexerT__28 = 29 + CypherLexerT__29 = 30 + CypherLexerT__30 = 31 + CypherLexerT__31 = 32 + CypherLexerT__32 = 33 + CypherLexerT__33 = 34 + CypherLexerT__34 = 35 + CypherLexerT__35 = 36 + CypherLexerT__36 = 37 + CypherLexerT__37 = 38 + CypherLexerT__38 = 39 + CypherLexerT__39 = 40 + CypherLexerT__40 = 41 + CypherLexerT__41 = 42 + CypherLexerT__42 = 43 + CypherLexerT__43 = 44 + CypherLexerT__44 = 45 + CypherLexerUNION = 46 + CypherLexerALL = 47 + CypherLexerOPTIONAL = 48 + CypherLexerMATCH = 49 + CypherLexerUNWIND = 50 + CypherLexerAS = 51 + CypherLexerMERGE = 52 + CypherLexerON = 53 + CypherLexerCREATE = 54 + CypherLexerSET = 55 + CypherLexerDETACH = 56 + CypherLexerDELETE = 57 + CypherLexerREMOVE = 58 + CypherLexerCALL = 59 + CypherLexerYIELD = 60 + CypherLexerWITH = 61 + CypherLexerRETURN = 62 + CypherLexerDISTINCT = 63 + CypherLexerORDER = 64 + CypherLexerBY = 65 + CypherLexerL_SKIP = 66 + CypherLexerLIMIT = 67 + CypherLexerASCENDING = 68 + CypherLexerASC = 69 + CypherLexerDESCENDING = 70 + CypherLexerDESC = 71 + CypherLexerWHERE = 72 + CypherLexerOR = 73 + CypherLexerXOR = 74 + CypherLexerAND = 75 + CypherLexerNOT = 76 + CypherLexerIN = 77 + CypherLexerSTARTS = 78 + CypherLexerENDS = 79 + CypherLexerCONTAINS = 80 + CypherLexerIS = 81 + CypherLexerNULL = 82 + CypherLexerCOUNT = 83 + CypherLexerANY = 84 + CypherLexerNONE = 85 + CypherLexerSINGLE = 86 + CypherLexerTRUE = 87 + CypherLexerFALSE = 88 + CypherLexerEXISTS = 89 + CypherLexerCASE = 90 + CypherLexerELSE = 91 + CypherLexerEND = 92 + CypherLexerWHEN = 93 + CypherLexerTHEN = 94 + CypherLexerStringLiteral = 95 + CypherLexerEscapedChar = 96 + CypherLexerHexInteger = 97 + CypherLexerDecimalInteger = 98 + CypherLexerOctalInteger = 99 + CypherLexerHexLetter = 100 + CypherLexerHexDigit = 101 + CypherLexerDigit = 102 + CypherLexerNonZeroDigit = 103 + CypherLexerNonZeroOctDigit = 104 + CypherLexerOctDigit = 105 + CypherLexerZeroDigit = 106 + CypherLexerExponentDecimalReal = 107 + CypherLexerRegularDecimalReal = 108 + CypherLexerCONSTRAINT = 109 + CypherLexerDO = 110 + CypherLexerFOR = 111 + CypherLexerREQUIRE = 112 + CypherLexerUNIQUE = 113 + CypherLexerMANDATORY = 114 + CypherLexerSCALAR = 115 + CypherLexerOF = 116 + CypherLexerADD = 117 + CypherLexerDROP = 118 + CypherLexerFILTER = 119 + CypherLexerEXTRACT = 120 + CypherLexerUnescapedSymbolicName = 121 + CypherLexerIdentifierStart = 122 + CypherLexerIdentifierPart = 123 + CypherLexerEscapedSymbolicName = 124 + CypherLexerSP = 125 + CypherLexerWHITESPACE = 126 + CypherLexerComment = 127 +) diff --git a/parser/cypher_listener.go b/parser/cypher_listener.go new file mode 100644 index 0000000..5e98e34 --- /dev/null +++ b/parser/cypher_listener.go @@ -0,0 +1,604 @@ +// Code generated from Cypher.g4 by ANTLR 4.9. DO NOT EDIT. + +package parser // Cypher + +import "github.com/antlr/antlr4/runtime/Go/antlr" + +// CypherListener is a complete listener for a parse tree produced by CypherParser. +type CypherListener interface { + antlr.ParseTreeListener + + // EnterOC_Cypher is called when entering the oC_Cypher production. + EnterOC_Cypher(c *OC_CypherContext) + + // EnterOC_Statement is called when entering the oC_Statement production. + EnterOC_Statement(c *OC_StatementContext) + + // EnterOC_Query is called when entering the oC_Query production. + EnterOC_Query(c *OC_QueryContext) + + // EnterOC_RegularQuery is called when entering the oC_RegularQuery production. + EnterOC_RegularQuery(c *OC_RegularQueryContext) + + // EnterOC_Union is called when entering the oC_Union production. + EnterOC_Union(c *OC_UnionContext) + + // EnterOC_SingleQuery is called when entering the oC_SingleQuery production. + EnterOC_SingleQuery(c *OC_SingleQueryContext) + + // EnterOC_SinglePartQuery is called when entering the oC_SinglePartQuery production. + EnterOC_SinglePartQuery(c *OC_SinglePartQueryContext) + + // EnterOC_MultiPartQuery is called when entering the oC_MultiPartQuery production. + EnterOC_MultiPartQuery(c *OC_MultiPartQueryContext) + + // EnterOC_UpdatingClause is called when entering the oC_UpdatingClause production. + EnterOC_UpdatingClause(c *OC_UpdatingClauseContext) + + // EnterOC_ReadingClause is called when entering the oC_ReadingClause production. + EnterOC_ReadingClause(c *OC_ReadingClauseContext) + + // EnterOC_Match is called when entering the oC_Match production. + EnterOC_Match(c *OC_MatchContext) + + // EnterOC_Unwind is called when entering the oC_Unwind production. + EnterOC_Unwind(c *OC_UnwindContext) + + // EnterOC_Merge is called when entering the oC_Merge production. + EnterOC_Merge(c *OC_MergeContext) + + // EnterOC_MergeAction is called when entering the oC_MergeAction production. + EnterOC_MergeAction(c *OC_MergeActionContext) + + // EnterOC_Create is called when entering the oC_Create production. + EnterOC_Create(c *OC_CreateContext) + + // EnterOC_Set is called when entering the oC_Set production. + EnterOC_Set(c *OC_SetContext) + + // EnterOC_SetItem is called when entering the oC_SetItem production. + EnterOC_SetItem(c *OC_SetItemContext) + + // EnterOC_Delete is called when entering the oC_Delete production. + EnterOC_Delete(c *OC_DeleteContext) + + // EnterOC_Remove is called when entering the oC_Remove production. + EnterOC_Remove(c *OC_RemoveContext) + + // EnterOC_RemoveItem is called when entering the oC_RemoveItem production. + EnterOC_RemoveItem(c *OC_RemoveItemContext) + + // EnterOC_InQueryCall is called when entering the oC_InQueryCall production. + EnterOC_InQueryCall(c *OC_InQueryCallContext) + + // EnterOC_StandaloneCall is called when entering the oC_StandaloneCall production. + EnterOC_StandaloneCall(c *OC_StandaloneCallContext) + + // EnterOC_YieldItems is called when entering the oC_YieldItems production. + EnterOC_YieldItems(c *OC_YieldItemsContext) + + // EnterOC_YieldItem is called when entering the oC_YieldItem production. + EnterOC_YieldItem(c *OC_YieldItemContext) + + // EnterOC_With is called when entering the oC_With production. + EnterOC_With(c *OC_WithContext) + + // EnterOC_Return is called when entering the oC_Return production. + EnterOC_Return(c *OC_ReturnContext) + + // EnterOC_ProjectionBody is called when entering the oC_ProjectionBody production. + EnterOC_ProjectionBody(c *OC_ProjectionBodyContext) + + // EnterOC_ProjectionItems is called when entering the oC_ProjectionItems production. + EnterOC_ProjectionItems(c *OC_ProjectionItemsContext) + + // EnterOC_ProjectionItem is called when entering the oC_ProjectionItem production. + EnterOC_ProjectionItem(c *OC_ProjectionItemContext) + + // EnterOC_Order is called when entering the oC_Order production. + EnterOC_Order(c *OC_OrderContext) + + // EnterOC_Skip is called when entering the oC_Skip production. + EnterOC_Skip(c *OC_SkipContext) + + // EnterOC_Limit is called when entering the oC_Limit production. + EnterOC_Limit(c *OC_LimitContext) + + // EnterOC_SortItem is called when entering the oC_SortItem production. + EnterOC_SortItem(c *OC_SortItemContext) + + // EnterOC_Where is called when entering the oC_Where production. + EnterOC_Where(c *OC_WhereContext) + + // EnterOC_Pattern is called when entering the oC_Pattern production. + EnterOC_Pattern(c *OC_PatternContext) + + // EnterOC_PatternPart is called when entering the oC_PatternPart production. + EnterOC_PatternPart(c *OC_PatternPartContext) + + // EnterOC_AnonymousPatternPart is called when entering the oC_AnonymousPatternPart production. + EnterOC_AnonymousPatternPart(c *OC_AnonymousPatternPartContext) + + // EnterOC_PatternElement is called when entering the oC_PatternElement production. + EnterOC_PatternElement(c *OC_PatternElementContext) + + // EnterOC_NodePattern is called when entering the oC_NodePattern production. + EnterOC_NodePattern(c *OC_NodePatternContext) + + // EnterOC_PatternElementChain is called when entering the oC_PatternElementChain production. + EnterOC_PatternElementChain(c *OC_PatternElementChainContext) + + // EnterOC_RelationshipPattern is called when entering the oC_RelationshipPattern production. + EnterOC_RelationshipPattern(c *OC_RelationshipPatternContext) + + // EnterOC_RelationshipDetail is called when entering the oC_RelationshipDetail production. + EnterOC_RelationshipDetail(c *OC_RelationshipDetailContext) + + // EnterOC_Properties is called when entering the oC_Properties production. + EnterOC_Properties(c *OC_PropertiesContext) + + // EnterOC_RelationshipTypes is called when entering the oC_RelationshipTypes production. + EnterOC_RelationshipTypes(c *OC_RelationshipTypesContext) + + // EnterOC_NodeLabels is called when entering the oC_NodeLabels production. + EnterOC_NodeLabels(c *OC_NodeLabelsContext) + + // EnterOC_NodeLabel is called when entering the oC_NodeLabel production. + EnterOC_NodeLabel(c *OC_NodeLabelContext) + + // EnterOC_RangeLiteral is called when entering the oC_RangeLiteral production. + EnterOC_RangeLiteral(c *OC_RangeLiteralContext) + + // EnterOC_LabelName is called when entering the oC_LabelName production. + EnterOC_LabelName(c *OC_LabelNameContext) + + // EnterOC_RelTypeName is called when entering the oC_RelTypeName production. + EnterOC_RelTypeName(c *OC_RelTypeNameContext) + + // EnterOC_Expression is called when entering the oC_Expression production. + EnterOC_Expression(c *OC_ExpressionContext) + + // EnterOC_OrExpression is called when entering the oC_OrExpression production. + EnterOC_OrExpression(c *OC_OrExpressionContext) + + // EnterOC_XorExpression is called when entering the oC_XorExpression production. + EnterOC_XorExpression(c *OC_XorExpressionContext) + + // EnterOC_AndExpression is called when entering the oC_AndExpression production. + EnterOC_AndExpression(c *OC_AndExpressionContext) + + // EnterOC_NotExpression is called when entering the oC_NotExpression production. + EnterOC_NotExpression(c *OC_NotExpressionContext) + + // EnterOC_ComparisonExpression is called when entering the oC_ComparisonExpression production. + EnterOC_ComparisonExpression(c *OC_ComparisonExpressionContext) + + // EnterOC_AddOrSubtractExpression is called when entering the oC_AddOrSubtractExpression production. + EnterOC_AddOrSubtractExpression(c *OC_AddOrSubtractExpressionContext) + + // EnterOC_MultiplyDivideModuloExpression is called when entering the oC_MultiplyDivideModuloExpression production. + EnterOC_MultiplyDivideModuloExpression(c *OC_MultiplyDivideModuloExpressionContext) + + // EnterOC_PowerOfExpression is called when entering the oC_PowerOfExpression production. + EnterOC_PowerOfExpression(c *OC_PowerOfExpressionContext) + + // EnterOC_UnaryAddOrSubtractExpression is called when entering the oC_UnaryAddOrSubtractExpression production. + EnterOC_UnaryAddOrSubtractExpression(c *OC_UnaryAddOrSubtractExpressionContext) + + // EnterOC_StringListNullOperatorExpression is called when entering the oC_StringListNullOperatorExpression production. + EnterOC_StringListNullOperatorExpression(c *OC_StringListNullOperatorExpressionContext) + + // EnterOC_ListOperatorExpression is called when entering the oC_ListOperatorExpression production. + EnterOC_ListOperatorExpression(c *OC_ListOperatorExpressionContext) + + // EnterOC_StringOperatorExpression is called when entering the oC_StringOperatorExpression production. + EnterOC_StringOperatorExpression(c *OC_StringOperatorExpressionContext) + + // EnterOC_NullOperatorExpression is called when entering the oC_NullOperatorExpression production. + EnterOC_NullOperatorExpression(c *OC_NullOperatorExpressionContext) + + // EnterOC_PropertyOrLabelsExpression is called when entering the oC_PropertyOrLabelsExpression production. + EnterOC_PropertyOrLabelsExpression(c *OC_PropertyOrLabelsExpressionContext) + + // EnterOC_Atom is called when entering the oC_Atom production. + EnterOC_Atom(c *OC_AtomContext) + + // EnterOC_Literal is called when entering the oC_Literal production. + EnterOC_Literal(c *OC_LiteralContext) + + // EnterOC_BooleanLiteral is called when entering the oC_BooleanLiteral production. + EnterOC_BooleanLiteral(c *OC_BooleanLiteralContext) + + // EnterOC_ListLiteral is called when entering the oC_ListLiteral production. + EnterOC_ListLiteral(c *OC_ListLiteralContext) + + // EnterOC_PartialComparisonExpression is called when entering the oC_PartialComparisonExpression production. + EnterOC_PartialComparisonExpression(c *OC_PartialComparisonExpressionContext) + + // EnterOC_ParenthesizedExpression is called when entering the oC_ParenthesizedExpression production. + EnterOC_ParenthesizedExpression(c *OC_ParenthesizedExpressionContext) + + // EnterOC_RelationshipsPattern is called when entering the oC_RelationshipsPattern production. + EnterOC_RelationshipsPattern(c *OC_RelationshipsPatternContext) + + // EnterOC_FilterExpression is called when entering the oC_FilterExpression production. + EnterOC_FilterExpression(c *OC_FilterExpressionContext) + + // EnterOC_IdInColl is called when entering the oC_IdInColl production. + EnterOC_IdInColl(c *OC_IdInCollContext) + + // EnterOC_FunctionInvocation is called when entering the oC_FunctionInvocation production. + EnterOC_FunctionInvocation(c *OC_FunctionInvocationContext) + + // EnterOC_FunctionName is called when entering the oC_FunctionName production. + EnterOC_FunctionName(c *OC_FunctionNameContext) + + // EnterOC_ExplicitProcedureInvocation is called when entering the oC_ExplicitProcedureInvocation production. + EnterOC_ExplicitProcedureInvocation(c *OC_ExplicitProcedureInvocationContext) + + // EnterOC_ImplicitProcedureInvocation is called when entering the oC_ImplicitProcedureInvocation production. + EnterOC_ImplicitProcedureInvocation(c *OC_ImplicitProcedureInvocationContext) + + // EnterOC_ProcedureResultField is called when entering the oC_ProcedureResultField production. + EnterOC_ProcedureResultField(c *OC_ProcedureResultFieldContext) + + // EnterOC_ProcedureName is called when entering the oC_ProcedureName production. + EnterOC_ProcedureName(c *OC_ProcedureNameContext) + + // EnterOC_Namespace is called when entering the oC_Namespace production. + EnterOC_Namespace(c *OC_NamespaceContext) + + // EnterOC_ListComprehension is called when entering the oC_ListComprehension production. + EnterOC_ListComprehension(c *OC_ListComprehensionContext) + + // EnterOC_PatternComprehension is called when entering the oC_PatternComprehension production. + EnterOC_PatternComprehension(c *OC_PatternComprehensionContext) + + // EnterOC_PropertyLookup is called when entering the oC_PropertyLookup production. + EnterOC_PropertyLookup(c *OC_PropertyLookupContext) + + // EnterOC_CaseExpression is called when entering the oC_CaseExpression production. + EnterOC_CaseExpression(c *OC_CaseExpressionContext) + + // EnterOC_CaseAlternatives is called when entering the oC_CaseAlternatives production. + EnterOC_CaseAlternatives(c *OC_CaseAlternativesContext) + + // EnterOC_Variable is called when entering the oC_Variable production. + EnterOC_Variable(c *OC_VariableContext) + + // EnterOC_NumberLiteral is called when entering the oC_NumberLiteral production. + EnterOC_NumberLiteral(c *OC_NumberLiteralContext) + + // EnterOC_MapLiteral is called when entering the oC_MapLiteral production. + EnterOC_MapLiteral(c *OC_MapLiteralContext) + + // EnterOC_Parameter is called when entering the oC_Parameter production. + EnterOC_Parameter(c *OC_ParameterContext) + + // EnterOC_PropertyExpression is called when entering the oC_PropertyExpression production. + EnterOC_PropertyExpression(c *OC_PropertyExpressionContext) + + // EnterOC_PropertyKeyName is called when entering the oC_PropertyKeyName production. + EnterOC_PropertyKeyName(c *OC_PropertyKeyNameContext) + + // EnterOC_IntegerLiteral is called when entering the oC_IntegerLiteral production. + EnterOC_IntegerLiteral(c *OC_IntegerLiteralContext) + + // EnterOC_DoubleLiteral is called when entering the oC_DoubleLiteral production. + EnterOC_DoubleLiteral(c *OC_DoubleLiteralContext) + + // EnterOC_SchemaName is called when entering the oC_SchemaName production. + EnterOC_SchemaName(c *OC_SchemaNameContext) + + // EnterOC_ReservedWord is called when entering the oC_ReservedWord production. + EnterOC_ReservedWord(c *OC_ReservedWordContext) + + // EnterOC_SymbolicName is called when entering the oC_SymbolicName production. + EnterOC_SymbolicName(c *OC_SymbolicNameContext) + + // EnterOC_LeftArrowHead is called when entering the oC_LeftArrowHead production. + EnterOC_LeftArrowHead(c *OC_LeftArrowHeadContext) + + // EnterOC_RightArrowHead is called when entering the oC_RightArrowHead production. + EnterOC_RightArrowHead(c *OC_RightArrowHeadContext) + + // EnterOC_Dash is called when entering the oC_Dash production. + EnterOC_Dash(c *OC_DashContext) + + // ExitOC_Cypher is called when exiting the oC_Cypher production. + ExitOC_Cypher(c *OC_CypherContext) + + // ExitOC_Statement is called when exiting the oC_Statement production. + ExitOC_Statement(c *OC_StatementContext) + + // ExitOC_Query is called when exiting the oC_Query production. + ExitOC_Query(c *OC_QueryContext) + + // ExitOC_RegularQuery is called when exiting the oC_RegularQuery production. + ExitOC_RegularQuery(c *OC_RegularQueryContext) + + // ExitOC_Union is called when exiting the oC_Union production. + ExitOC_Union(c *OC_UnionContext) + + // ExitOC_SingleQuery is called when exiting the oC_SingleQuery production. + ExitOC_SingleQuery(c *OC_SingleQueryContext) + + // ExitOC_SinglePartQuery is called when exiting the oC_SinglePartQuery production. + ExitOC_SinglePartQuery(c *OC_SinglePartQueryContext) + + // ExitOC_MultiPartQuery is called when exiting the oC_MultiPartQuery production. + ExitOC_MultiPartQuery(c *OC_MultiPartQueryContext) + + // ExitOC_UpdatingClause is called when exiting the oC_UpdatingClause production. + ExitOC_UpdatingClause(c *OC_UpdatingClauseContext) + + // ExitOC_ReadingClause is called when exiting the oC_ReadingClause production. + ExitOC_ReadingClause(c *OC_ReadingClauseContext) + + // ExitOC_Match is called when exiting the oC_Match production. + ExitOC_Match(c *OC_MatchContext) + + // ExitOC_Unwind is called when exiting the oC_Unwind production. + ExitOC_Unwind(c *OC_UnwindContext) + + // ExitOC_Merge is called when exiting the oC_Merge production. + ExitOC_Merge(c *OC_MergeContext) + + // ExitOC_MergeAction is called when exiting the oC_MergeAction production. + ExitOC_MergeAction(c *OC_MergeActionContext) + + // ExitOC_Create is called when exiting the oC_Create production. + ExitOC_Create(c *OC_CreateContext) + + // ExitOC_Set is called when exiting the oC_Set production. + ExitOC_Set(c *OC_SetContext) + + // ExitOC_SetItem is called when exiting the oC_SetItem production. + ExitOC_SetItem(c *OC_SetItemContext) + + // ExitOC_Delete is called when exiting the oC_Delete production. + ExitOC_Delete(c *OC_DeleteContext) + + // ExitOC_Remove is called when exiting the oC_Remove production. + ExitOC_Remove(c *OC_RemoveContext) + + // ExitOC_RemoveItem is called when exiting the oC_RemoveItem production. + ExitOC_RemoveItem(c *OC_RemoveItemContext) + + // ExitOC_InQueryCall is called when exiting the oC_InQueryCall production. + ExitOC_InQueryCall(c *OC_InQueryCallContext) + + // ExitOC_StandaloneCall is called when exiting the oC_StandaloneCall production. + ExitOC_StandaloneCall(c *OC_StandaloneCallContext) + + // ExitOC_YieldItems is called when exiting the oC_YieldItems production. + ExitOC_YieldItems(c *OC_YieldItemsContext) + + // ExitOC_YieldItem is called when exiting the oC_YieldItem production. + ExitOC_YieldItem(c *OC_YieldItemContext) + + // ExitOC_With is called when exiting the oC_With production. + ExitOC_With(c *OC_WithContext) + + // ExitOC_Return is called when exiting the oC_Return production. + ExitOC_Return(c *OC_ReturnContext) + + // ExitOC_ProjectionBody is called when exiting the oC_ProjectionBody production. + ExitOC_ProjectionBody(c *OC_ProjectionBodyContext) + + // ExitOC_ProjectionItems is called when exiting the oC_ProjectionItems production. + ExitOC_ProjectionItems(c *OC_ProjectionItemsContext) + + // ExitOC_ProjectionItem is called when exiting the oC_ProjectionItem production. + ExitOC_ProjectionItem(c *OC_ProjectionItemContext) + + // ExitOC_Order is called when exiting the oC_Order production. + ExitOC_Order(c *OC_OrderContext) + + // ExitOC_Skip is called when exiting the oC_Skip production. + ExitOC_Skip(c *OC_SkipContext) + + // ExitOC_Limit is called when exiting the oC_Limit production. + ExitOC_Limit(c *OC_LimitContext) + + // ExitOC_SortItem is called when exiting the oC_SortItem production. + ExitOC_SortItem(c *OC_SortItemContext) + + // ExitOC_Where is called when exiting the oC_Where production. + ExitOC_Where(c *OC_WhereContext) + + // ExitOC_Pattern is called when exiting the oC_Pattern production. + ExitOC_Pattern(c *OC_PatternContext) + + // ExitOC_PatternPart is called when exiting the oC_PatternPart production. + ExitOC_PatternPart(c *OC_PatternPartContext) + + // ExitOC_AnonymousPatternPart is called when exiting the oC_AnonymousPatternPart production. + ExitOC_AnonymousPatternPart(c *OC_AnonymousPatternPartContext) + + // ExitOC_PatternElement is called when exiting the oC_PatternElement production. + ExitOC_PatternElement(c *OC_PatternElementContext) + + // ExitOC_NodePattern is called when exiting the oC_NodePattern production. + ExitOC_NodePattern(c *OC_NodePatternContext) + + // ExitOC_PatternElementChain is called when exiting the oC_PatternElementChain production. + ExitOC_PatternElementChain(c *OC_PatternElementChainContext) + + // ExitOC_RelationshipPattern is called when exiting the oC_RelationshipPattern production. + ExitOC_RelationshipPattern(c *OC_RelationshipPatternContext) + + // ExitOC_RelationshipDetail is called when exiting the oC_RelationshipDetail production. + ExitOC_RelationshipDetail(c *OC_RelationshipDetailContext) + + // ExitOC_Properties is called when exiting the oC_Properties production. + ExitOC_Properties(c *OC_PropertiesContext) + + // ExitOC_RelationshipTypes is called when exiting the oC_RelationshipTypes production. + ExitOC_RelationshipTypes(c *OC_RelationshipTypesContext) + + // ExitOC_NodeLabels is called when exiting the oC_NodeLabels production. + ExitOC_NodeLabels(c *OC_NodeLabelsContext) + + // ExitOC_NodeLabel is called when exiting the oC_NodeLabel production. + ExitOC_NodeLabel(c *OC_NodeLabelContext) + + // ExitOC_RangeLiteral is called when exiting the oC_RangeLiteral production. + ExitOC_RangeLiteral(c *OC_RangeLiteralContext) + + // ExitOC_LabelName is called when exiting the oC_LabelName production. + ExitOC_LabelName(c *OC_LabelNameContext) + + // ExitOC_RelTypeName is called when exiting the oC_RelTypeName production. + ExitOC_RelTypeName(c *OC_RelTypeNameContext) + + // ExitOC_Expression is called when exiting the oC_Expression production. + ExitOC_Expression(c *OC_ExpressionContext) + + // ExitOC_OrExpression is called when exiting the oC_OrExpression production. + ExitOC_OrExpression(c *OC_OrExpressionContext) + + // ExitOC_XorExpression is called when exiting the oC_XorExpression production. + ExitOC_XorExpression(c *OC_XorExpressionContext) + + // ExitOC_AndExpression is called when exiting the oC_AndExpression production. + ExitOC_AndExpression(c *OC_AndExpressionContext) + + // ExitOC_NotExpression is called when exiting the oC_NotExpression production. + ExitOC_NotExpression(c *OC_NotExpressionContext) + + // ExitOC_ComparisonExpression is called when exiting the oC_ComparisonExpression production. + ExitOC_ComparisonExpression(c *OC_ComparisonExpressionContext) + + // ExitOC_AddOrSubtractExpression is called when exiting the oC_AddOrSubtractExpression production. + ExitOC_AddOrSubtractExpression(c *OC_AddOrSubtractExpressionContext) + + // ExitOC_MultiplyDivideModuloExpression is called when exiting the oC_MultiplyDivideModuloExpression production. + ExitOC_MultiplyDivideModuloExpression(c *OC_MultiplyDivideModuloExpressionContext) + + // ExitOC_PowerOfExpression is called when exiting the oC_PowerOfExpression production. + ExitOC_PowerOfExpression(c *OC_PowerOfExpressionContext) + + // ExitOC_UnaryAddOrSubtractExpression is called when exiting the oC_UnaryAddOrSubtractExpression production. + ExitOC_UnaryAddOrSubtractExpression(c *OC_UnaryAddOrSubtractExpressionContext) + + // ExitOC_StringListNullOperatorExpression is called when exiting the oC_StringListNullOperatorExpression production. + ExitOC_StringListNullOperatorExpression(c *OC_StringListNullOperatorExpressionContext) + + // ExitOC_ListOperatorExpression is called when exiting the oC_ListOperatorExpression production. + ExitOC_ListOperatorExpression(c *OC_ListOperatorExpressionContext) + + // ExitOC_StringOperatorExpression is called when exiting the oC_StringOperatorExpression production. + ExitOC_StringOperatorExpression(c *OC_StringOperatorExpressionContext) + + // ExitOC_NullOperatorExpression is called when exiting the oC_NullOperatorExpression production. + ExitOC_NullOperatorExpression(c *OC_NullOperatorExpressionContext) + + // ExitOC_PropertyOrLabelsExpression is called when exiting the oC_PropertyOrLabelsExpression production. + ExitOC_PropertyOrLabelsExpression(c *OC_PropertyOrLabelsExpressionContext) + + // ExitOC_Atom is called when exiting the oC_Atom production. + ExitOC_Atom(c *OC_AtomContext) + + // ExitOC_Literal is called when exiting the oC_Literal production. + ExitOC_Literal(c *OC_LiteralContext) + + // ExitOC_BooleanLiteral is called when exiting the oC_BooleanLiteral production. + ExitOC_BooleanLiteral(c *OC_BooleanLiteralContext) + + // ExitOC_ListLiteral is called when exiting the oC_ListLiteral production. + ExitOC_ListLiteral(c *OC_ListLiteralContext) + + // ExitOC_PartialComparisonExpression is called when exiting the oC_PartialComparisonExpression production. + ExitOC_PartialComparisonExpression(c *OC_PartialComparisonExpressionContext) + + // ExitOC_ParenthesizedExpression is called when exiting the oC_ParenthesizedExpression production. + ExitOC_ParenthesizedExpression(c *OC_ParenthesizedExpressionContext) + + // ExitOC_RelationshipsPattern is called when exiting the oC_RelationshipsPattern production. + ExitOC_RelationshipsPattern(c *OC_RelationshipsPatternContext) + + // ExitOC_FilterExpression is called when exiting the oC_FilterExpression production. + ExitOC_FilterExpression(c *OC_FilterExpressionContext) + + // ExitOC_IdInColl is called when exiting the oC_IdInColl production. + ExitOC_IdInColl(c *OC_IdInCollContext) + + // ExitOC_FunctionInvocation is called when exiting the oC_FunctionInvocation production. + ExitOC_FunctionInvocation(c *OC_FunctionInvocationContext) + + // ExitOC_FunctionName is called when exiting the oC_FunctionName production. + ExitOC_FunctionName(c *OC_FunctionNameContext) + + // ExitOC_ExplicitProcedureInvocation is called when exiting the oC_ExplicitProcedureInvocation production. + ExitOC_ExplicitProcedureInvocation(c *OC_ExplicitProcedureInvocationContext) + + // ExitOC_ImplicitProcedureInvocation is called when exiting the oC_ImplicitProcedureInvocation production. + ExitOC_ImplicitProcedureInvocation(c *OC_ImplicitProcedureInvocationContext) + + // ExitOC_ProcedureResultField is called when exiting the oC_ProcedureResultField production. + ExitOC_ProcedureResultField(c *OC_ProcedureResultFieldContext) + + // ExitOC_ProcedureName is called when exiting the oC_ProcedureName production. + ExitOC_ProcedureName(c *OC_ProcedureNameContext) + + // ExitOC_Namespace is called when exiting the oC_Namespace production. + ExitOC_Namespace(c *OC_NamespaceContext) + + // ExitOC_ListComprehension is called when exiting the oC_ListComprehension production. + ExitOC_ListComprehension(c *OC_ListComprehensionContext) + + // ExitOC_PatternComprehension is called when exiting the oC_PatternComprehension production. + ExitOC_PatternComprehension(c *OC_PatternComprehensionContext) + + // ExitOC_PropertyLookup is called when exiting the oC_PropertyLookup production. + ExitOC_PropertyLookup(c *OC_PropertyLookupContext) + + // ExitOC_CaseExpression is called when exiting the oC_CaseExpression production. + ExitOC_CaseExpression(c *OC_CaseExpressionContext) + + // ExitOC_CaseAlternatives is called when exiting the oC_CaseAlternatives production. + ExitOC_CaseAlternatives(c *OC_CaseAlternativesContext) + + // ExitOC_Variable is called when exiting the oC_Variable production. + ExitOC_Variable(c *OC_VariableContext) + + // ExitOC_NumberLiteral is called when exiting the oC_NumberLiteral production. + ExitOC_NumberLiteral(c *OC_NumberLiteralContext) + + // ExitOC_MapLiteral is called when exiting the oC_MapLiteral production. + ExitOC_MapLiteral(c *OC_MapLiteralContext) + + // ExitOC_Parameter is called when exiting the oC_Parameter production. + ExitOC_Parameter(c *OC_ParameterContext) + + // ExitOC_PropertyExpression is called when exiting the oC_PropertyExpression production. + ExitOC_PropertyExpression(c *OC_PropertyExpressionContext) + + // ExitOC_PropertyKeyName is called when exiting the oC_PropertyKeyName production. + ExitOC_PropertyKeyName(c *OC_PropertyKeyNameContext) + + // ExitOC_IntegerLiteral is called when exiting the oC_IntegerLiteral production. + ExitOC_IntegerLiteral(c *OC_IntegerLiteralContext) + + // ExitOC_DoubleLiteral is called when exiting the oC_DoubleLiteral production. + ExitOC_DoubleLiteral(c *OC_DoubleLiteralContext) + + // ExitOC_SchemaName is called when exiting the oC_SchemaName production. + ExitOC_SchemaName(c *OC_SchemaNameContext) + + // ExitOC_ReservedWord is called when exiting the oC_ReservedWord production. + ExitOC_ReservedWord(c *OC_ReservedWordContext) + + // ExitOC_SymbolicName is called when exiting the oC_SymbolicName production. + ExitOC_SymbolicName(c *OC_SymbolicNameContext) + + // ExitOC_LeftArrowHead is called when exiting the oC_LeftArrowHead production. + ExitOC_LeftArrowHead(c *OC_LeftArrowHeadContext) + + // ExitOC_RightArrowHead is called when exiting the oC_RightArrowHead production. + ExitOC_RightArrowHead(c *OC_RightArrowHeadContext) + + // ExitOC_Dash is called when exiting the oC_Dash production. + ExitOC_Dash(c *OC_DashContext) +} diff --git a/parser/cypher_parser.go b/parser/cypher_parser.go new file mode 100644 index 0000000..4528f01 --- /dev/null +++ b/parser/cypher_parser.go @@ -0,0 +1,17574 @@ +// Code generated from Cypher.g4 by ANTLR 4.9. DO NOT EDIT. + +package parser // Cypher + +import ( + "fmt" + "reflect" + "strconv" + + "github.com/antlr/antlr4/runtime/Go/antlr" +) + +// Suppress unused import errors +var _ = fmt.Printf +var _ = reflect.Copy +var _ = strconv.Itoa + +var parserATN = []uint16{ + 3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 3, 129, 1549, + 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, + 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, + 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, + 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, + 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, 28, 4, + 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9, 32, 4, 33, 9, 33, 4, 34, + 9, 34, 4, 35, 9, 35, 4, 36, 9, 36, 4, 37, 9, 37, 4, 38, 9, 38, 4, 39, 9, + 39, 4, 40, 9, 40, 4, 41, 9, 41, 4, 42, 9, 42, 4, 43, 9, 43, 4, 44, 9, 44, + 4, 45, 9, 45, 4, 46, 9, 46, 4, 47, 9, 47, 4, 48, 9, 48, 4, 49, 9, 49, 4, + 50, 9, 50, 4, 51, 9, 51, 4, 52, 9, 52, 4, 53, 9, 53, 4, 54, 9, 54, 4, 55, + 9, 55, 4, 56, 9, 56, 4, 57, 9, 57, 4, 58, 9, 58, 4, 59, 9, 59, 4, 60, 9, + 60, 4, 61, 9, 61, 4, 62, 9, 62, 4, 63, 9, 63, 4, 64, 9, 64, 4, 65, 9, 65, + 4, 66, 9, 66, 4, 67, 9, 67, 4, 68, 9, 68, 4, 69, 9, 69, 4, 70, 9, 70, 4, + 71, 9, 71, 4, 72, 9, 72, 4, 73, 9, 73, 4, 74, 9, 74, 4, 75, 9, 75, 4, 76, + 9, 76, 4, 77, 9, 77, 4, 78, 9, 78, 4, 79, 9, 79, 4, 80, 9, 80, 4, 81, 9, + 81, 4, 82, 9, 82, 4, 83, 9, 83, 4, 84, 9, 84, 4, 85, 9, 85, 4, 86, 9, 86, + 4, 87, 9, 87, 4, 88, 9, 88, 4, 89, 9, 89, 4, 90, 9, 90, 4, 91, 9, 91, 4, + 92, 9, 92, 4, 93, 9, 93, 4, 94, 9, 94, 4, 95, 9, 95, 4, 96, 9, 96, 4, 97, + 9, 97, 4, 98, 9, 98, 4, 99, 9, 99, 4, 100, 9, 100, 3, 2, 5, 2, 202, 10, + 2, 3, 2, 3, 2, 5, 2, 206, 10, 2, 3, 2, 5, 2, 209, 10, 2, 3, 2, 5, 2, 212, + 10, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 4, 3, 4, 5, 4, 220, 10, 4, 3, 5, 3, 5, + 5, 5, 224, 10, 5, 3, 5, 7, 5, 227, 10, 5, 12, 5, 14, 5, 230, 11, 5, 3, + 6, 3, 6, 3, 6, 3, 6, 5, 6, 236, 10, 6, 3, 6, 3, 6, 3, 6, 5, 6, 241, 10, + 6, 3, 6, 5, 6, 244, 10, 6, 3, 7, 3, 7, 5, 7, 248, 10, 7, 3, 8, 3, 8, 5, + 8, 252, 10, 8, 7, 8, 254, 10, 8, 12, 8, 14, 8, 257, 11, 8, 3, 8, 3, 8, + 3, 8, 5, 8, 262, 10, 8, 7, 8, 264, 10, 8, 12, 8, 14, 8, 267, 11, 8, 3, + 8, 3, 8, 5, 8, 271, 10, 8, 3, 8, 7, 8, 274, 10, 8, 12, 8, 14, 8, 277, 11, + 8, 3, 8, 5, 8, 280, 10, 8, 3, 8, 5, 8, 283, 10, 8, 5, 8, 285, 10, 8, 3, + 9, 3, 9, 5, 9, 289, 10, 9, 7, 9, 291, 10, 9, 12, 9, 14, 9, 294, 11, 9, + 3, 9, 3, 9, 5, 9, 298, 10, 9, 7, 9, 300, 10, 9, 12, 9, 14, 9, 303, 11, + 9, 3, 9, 3, 9, 5, 9, 307, 10, 9, 6, 9, 309, 10, 9, 13, 9, 14, 9, 310, 3, + 9, 3, 9, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 5, 10, 320, 10, 10, 3, 11, + 3, 11, 3, 11, 5, 11, 325, 10, 11, 3, 12, 3, 12, 5, 12, 329, 10, 12, 3, + 12, 3, 12, 5, 12, 333, 10, 12, 3, 12, 3, 12, 5, 12, 337, 10, 12, 3, 12, + 5, 12, 340, 10, 12, 3, 13, 3, 13, 5, 13, 344, 10, 13, 3, 13, 3, 13, 3, + 13, 3, 13, 3, 13, 3, 13, 3, 14, 3, 14, 5, 14, 354, 10, 14, 3, 14, 3, 14, + 3, 14, 7, 14, 359, 10, 14, 12, 14, 14, 14, 362, 11, 14, 3, 15, 3, 15, 3, + 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 5, 15, 374, 10, 15, + 3, 16, 3, 16, 5, 16, 378, 10, 16, 3, 16, 3, 16, 3, 17, 3, 17, 5, 17, 384, + 10, 17, 3, 17, 3, 17, 5, 17, 388, 10, 17, 3, 17, 3, 17, 5, 17, 392, 10, + 17, 3, 17, 7, 17, 395, 10, 17, 12, 17, 14, 17, 398, 11, 17, 3, 18, 3, 18, + 5, 18, 402, 10, 18, 3, 18, 3, 18, 5, 18, 406, 10, 18, 3, 18, 3, 18, 3, + 18, 3, 18, 5, 18, 412, 10, 18, 3, 18, 3, 18, 5, 18, 416, 10, 18, 3, 18, + 3, 18, 3, 18, 3, 18, 5, 18, 422, 10, 18, 3, 18, 3, 18, 5, 18, 426, 10, + 18, 3, 18, 3, 18, 3, 18, 3, 18, 5, 18, 432, 10, 18, 3, 18, 3, 18, 5, 18, + 436, 10, 18, 3, 19, 3, 19, 5, 19, 440, 10, 19, 3, 19, 3, 19, 5, 19, 444, + 10, 19, 3, 19, 3, 19, 5, 19, 448, 10, 19, 3, 19, 3, 19, 5, 19, 452, 10, + 19, 3, 19, 7, 19, 455, 10, 19, 12, 19, 14, 19, 458, 11, 19, 3, 20, 3, 20, + 3, 20, 3, 20, 5, 20, 464, 10, 20, 3, 20, 3, 20, 5, 20, 468, 10, 20, 3, + 20, 7, 20, 471, 10, 20, 12, 20, 14, 20, 474, 11, 20, 3, 21, 3, 21, 3, 21, + 3, 21, 5, 21, 480, 10, 21, 3, 22, 3, 22, 3, 22, 3, 22, 5, 22, 486, 10, + 22, 3, 22, 3, 22, 3, 22, 5, 22, 491, 10, 22, 3, 23, 3, 23, 3, 23, 3, 23, + 5, 23, 497, 10, 23, 3, 23, 3, 23, 3, 23, 3, 23, 5, 23, 503, 10, 23, 3, + 24, 3, 24, 3, 24, 5, 24, 508, 10, 24, 3, 24, 3, 24, 5, 24, 512, 10, 24, + 3, 24, 7, 24, 515, 10, 24, 12, 24, 14, 24, 518, 11, 24, 5, 24, 520, 10, + 24, 3, 24, 5, 24, 523, 10, 24, 3, 24, 5, 24, 526, 10, 24, 3, 25, 3, 25, + 3, 25, 3, 25, 3, 25, 5, 25, 533, 10, 25, 3, 25, 3, 25, 3, 26, 3, 26, 3, + 26, 5, 26, 540, 10, 26, 3, 26, 5, 26, 543, 10, 26, 3, 27, 3, 27, 3, 27, + 3, 28, 5, 28, 549, 10, 28, 3, 28, 5, 28, 552, 10, 28, 3, 28, 3, 28, 3, + 28, 3, 28, 5, 28, 558, 10, 28, 3, 28, 3, 28, 5, 28, 562, 10, 28, 3, 28, + 3, 28, 5, 28, 566, 10, 28, 3, 29, 3, 29, 5, 29, 570, 10, 29, 3, 29, 3, + 29, 5, 29, 574, 10, 29, 3, 29, 7, 29, 577, 10, 29, 12, 29, 14, 29, 580, + 11, 29, 3, 29, 3, 29, 5, 29, 584, 10, 29, 3, 29, 3, 29, 5, 29, 588, 10, + 29, 3, 29, 7, 29, 591, 10, 29, 12, 29, 14, 29, 594, 11, 29, 5, 29, 596, + 10, 29, 3, 30, 3, 30, 3, 30, 3, 30, 3, 30, 3, 30, 3, 30, 5, 30, 605, 10, + 30, 3, 31, 3, 31, 3, 31, 3, 31, 3, 31, 3, 31, 3, 31, 5, 31, 614, 10, 31, + 3, 31, 7, 31, 617, 10, 31, 12, 31, 14, 31, 620, 11, 31, 3, 32, 3, 32, 3, + 32, 3, 32, 3, 33, 3, 33, 3, 33, 3, 33, 3, 34, 3, 34, 5, 34, 632, 10, 34, + 3, 34, 5, 34, 635, 10, 34, 3, 35, 3, 35, 3, 35, 3, 35, 3, 36, 3, 36, 5, + 36, 643, 10, 36, 3, 36, 3, 36, 5, 36, 647, 10, 36, 3, 36, 7, 36, 650, 10, + 36, 12, 36, 14, 36, 653, 11, 36, 3, 37, 3, 37, 5, 37, 657, 10, 37, 3, 37, + 3, 37, 5, 37, 661, 10, 37, 3, 37, 3, 37, 3, 37, 5, 37, 666, 10, 37, 3, + 38, 3, 38, 3, 39, 3, 39, 5, 39, 672, 10, 39, 3, 39, 7, 39, 675, 10, 39, + 12, 39, 14, 39, 678, 11, 39, 3, 39, 3, 39, 3, 39, 3, 39, 5, 39, 684, 10, + 39, 3, 40, 3, 40, 5, 40, 688, 10, 40, 3, 40, 3, 40, 5, 40, 692, 10, 40, + 5, 40, 694, 10, 40, 3, 40, 3, 40, 5, 40, 698, 10, 40, 5, 40, 700, 10, 40, + 3, 40, 3, 40, 5, 40, 704, 10, 40, 5, 40, 706, 10, 40, 3, 40, 3, 40, 3, + 41, 3, 41, 5, 41, 712, 10, 41, 3, 41, 3, 41, 3, 42, 3, 42, 5, 42, 718, + 10, 42, 3, 42, 3, 42, 5, 42, 722, 10, 42, 3, 42, 5, 42, 725, 10, 42, 3, + 42, 5, 42, 728, 10, 42, 3, 42, 3, 42, 5, 42, 732, 10, 42, 3, 42, 3, 42, + 3, 42, 3, 42, 5, 42, 738, 10, 42, 3, 42, 3, 42, 5, 42, 742, 10, 42, 3, + 42, 5, 42, 745, 10, 42, 3, 42, 5, 42, 748, 10, 42, 3, 42, 3, 42, 3, 42, + 3, 42, 5, 42, 754, 10, 42, 3, 42, 5, 42, 757, 10, 42, 3, 42, 5, 42, 760, + 10, 42, 3, 42, 3, 42, 5, 42, 764, 10, 42, 3, 42, 3, 42, 3, 42, 3, 42, 5, + 42, 770, 10, 42, 3, 42, 5, 42, 773, 10, 42, 3, 42, 5, 42, 776, 10, 42, + 3, 42, 3, 42, 5, 42, 780, 10, 42, 3, 43, 3, 43, 5, 43, 784, 10, 43, 3, + 43, 3, 43, 5, 43, 788, 10, 43, 5, 43, 790, 10, 43, 3, 43, 3, 43, 5, 43, + 794, 10, 43, 5, 43, 796, 10, 43, 3, 43, 5, 43, 799, 10, 43, 3, 43, 3, 43, + 5, 43, 803, 10, 43, 5, 43, 805, 10, 43, 3, 43, 3, 43, 3, 44, 3, 44, 5, + 44, 811, 10, 44, 3, 45, 3, 45, 5, 45, 815, 10, 45, 3, 45, 3, 45, 5, 45, + 819, 10, 45, 3, 45, 3, 45, 5, 45, 823, 10, 45, 3, 45, 5, 45, 826, 10, 45, + 3, 45, 7, 45, 829, 10, 45, 12, 45, 14, 45, 832, 11, 45, 3, 46, 3, 46, 5, + 46, 836, 10, 46, 3, 46, 7, 46, 839, 10, 46, 12, 46, 14, 46, 842, 11, 46, + 3, 47, 3, 47, 5, 47, 846, 10, 47, 3, 47, 3, 47, 3, 48, 3, 48, 5, 48, 852, + 10, 48, 3, 48, 3, 48, 5, 48, 856, 10, 48, 5, 48, 858, 10, 48, 3, 48, 3, + 48, 5, 48, 862, 10, 48, 3, 48, 3, 48, 5, 48, 866, 10, 48, 5, 48, 868, 10, + 48, 5, 48, 870, 10, 48, 3, 49, 3, 49, 3, 50, 3, 50, 3, 51, 3, 51, 3, 52, + 3, 52, 3, 52, 3, 52, 3, 52, 7, 52, 883, 10, 52, 12, 52, 14, 52, 886, 11, + 52, 3, 53, 3, 53, 3, 53, 3, 53, 3, 53, 7, 53, 893, 10, 53, 12, 53, 14, + 53, 896, 11, 53, 3, 54, 3, 54, 3, 54, 3, 54, 3, 54, 7, 54, 903, 10, 54, + 12, 54, 14, 54, 906, 11, 54, 3, 55, 3, 55, 5, 55, 910, 10, 55, 7, 55, 912, + 10, 55, 12, 55, 14, 55, 915, 11, 55, 3, 55, 3, 55, 3, 56, 3, 56, 5, 56, + 921, 10, 56, 3, 56, 7, 56, 924, 10, 56, 12, 56, 14, 56, 927, 11, 56, 3, + 57, 3, 57, 5, 57, 931, 10, 57, 3, 57, 3, 57, 5, 57, 935, 10, 57, 3, 57, + 3, 57, 5, 57, 939, 10, 57, 3, 57, 3, 57, 5, 57, 943, 10, 57, 3, 57, 7, + 57, 946, 10, 57, 12, 57, 14, 57, 949, 11, 57, 3, 58, 3, 58, 5, 58, 953, + 10, 58, 3, 58, 3, 58, 5, 58, 957, 10, 58, 3, 58, 3, 58, 5, 58, 961, 10, + 58, 3, 58, 3, 58, 5, 58, 965, 10, 58, 3, 58, 3, 58, 5, 58, 969, 10, 58, + 3, 58, 3, 58, 5, 58, 973, 10, 58, 3, 58, 7, 58, 976, 10, 58, 12, 58, 14, + 58, 979, 11, 58, 3, 59, 3, 59, 5, 59, 983, 10, 59, 3, 59, 3, 59, 5, 59, + 987, 10, 59, 3, 59, 7, 59, 990, 10, 59, 12, 59, 14, 59, 993, 11, 59, 3, + 60, 3, 60, 5, 60, 997, 10, 60, 7, 60, 999, 10, 60, 12, 60, 14, 60, 1002, + 11, 60, 3, 60, 3, 60, 3, 61, 3, 61, 3, 61, 3, 61, 7, 61, 1010, 10, 61, + 12, 61, 14, 61, 1013, 11, 61, 3, 62, 3, 62, 3, 62, 5, 62, 1018, 10, 62, + 3, 62, 3, 62, 5, 62, 1022, 10, 62, 3, 62, 3, 62, 3, 62, 3, 62, 3, 62, 5, + 62, 1029, 10, 62, 3, 62, 3, 62, 5, 62, 1033, 10, 62, 3, 62, 3, 62, 5, 62, + 1037, 10, 62, 3, 62, 5, 62, 1040, 10, 62, 3, 63, 3, 63, 3, 63, 3, 63, 3, + 63, 3, 63, 3, 63, 3, 63, 3, 63, 3, 63, 5, 63, 1052, 10, 63, 3, 63, 5, 63, + 1055, 10, 63, 3, 63, 3, 63, 3, 64, 3, 64, 3, 64, 3, 64, 3, 64, 3, 64, 3, + 64, 3, 64, 3, 64, 3, 64, 5, 64, 1069, 10, 64, 3, 65, 3, 65, 5, 65, 1073, + 10, 65, 3, 65, 7, 65, 1076, 10, 65, 12, 65, 14, 65, 1079, 11, 65, 3, 65, + 5, 65, 1082, 10, 65, 3, 65, 5, 65, 1085, 10, 65, 3, 66, 3, 66, 3, 66, 3, + 66, 3, 66, 5, 66, 1092, 10, 66, 3, 66, 3, 66, 5, 66, 1096, 10, 66, 3, 66, + 3, 66, 5, 66, 1100, 10, 66, 3, 66, 3, 66, 3, 66, 3, 66, 3, 66, 5, 66, 1107, + 10, 66, 3, 66, 3, 66, 5, 66, 1111, 10, 66, 3, 66, 3, 66, 5, 66, 1115, 10, + 66, 3, 66, 3, 66, 3, 66, 3, 66, 5, 66, 1121, 10, 66, 3, 66, 3, 66, 5, 66, + 1125, 10, 66, 3, 66, 3, 66, 5, 66, 1129, 10, 66, 3, 66, 3, 66, 3, 66, 3, + 66, 5, 66, 1135, 10, 66, 3, 66, 3, 66, 5, 66, 1139, 10, 66, 3, 66, 3, 66, + 5, 66, 1143, 10, 66, 3, 66, 3, 66, 3, 66, 3, 66, 5, 66, 1149, 10, 66, 3, + 66, 3, 66, 5, 66, 1153, 10, 66, 3, 66, 3, 66, 5, 66, 1157, 10, 66, 3, 66, + 3, 66, 3, 66, 3, 66, 3, 66, 3, 66, 5, 66, 1165, 10, 66, 3, 67, 3, 67, 3, + 67, 3, 67, 3, 67, 3, 67, 5, 67, 1173, 10, 67, 3, 68, 3, 68, 3, 69, 3, 69, + 5, 69, 1179, 10, 69, 3, 69, 3, 69, 5, 69, 1183, 10, 69, 3, 69, 3, 69, 5, + 69, 1187, 10, 69, 3, 69, 3, 69, 5, 69, 1191, 10, 69, 7, 69, 1193, 10, 69, + 12, 69, 14, 69, 1196, 11, 69, 5, 69, 1198, 10, 69, 3, 69, 3, 69, 3, 70, + 3, 70, 5, 70, 1204, 10, 70, 3, 70, 3, 70, 3, 70, 5, 70, 1209, 10, 70, 3, + 70, 3, 70, 3, 70, 5, 70, 1214, 10, 70, 3, 70, 3, 70, 3, 70, 5, 70, 1219, + 10, 70, 3, 70, 3, 70, 3, 70, 5, 70, 1224, 10, 70, 3, 70, 3, 70, 3, 70, + 5, 70, 1229, 10, 70, 3, 70, 5, 70, 1232, 10, 70, 3, 71, 3, 71, 5, 71, 1236, + 10, 71, 3, 71, 3, 71, 5, 71, 1240, 10, 71, 3, 71, 3, 71, 3, 72, 3, 72, + 5, 72, 1246, 10, 72, 3, 72, 6, 72, 1249, 10, 72, 13, 72, 14, 72, 1250, + 3, 73, 3, 73, 5, 73, 1255, 10, 73, 3, 73, 5, 73, 1258, 10, 73, 3, 74, 3, + 74, 3, 74, 3, 74, 3, 74, 3, 74, 3, 75, 3, 75, 5, 75, 1268, 10, 75, 3, 75, + 3, 75, 5, 75, 1272, 10, 75, 3, 75, 3, 75, 5, 75, 1276, 10, 75, 5, 75, 1278, + 10, 75, 3, 75, 3, 75, 5, 75, 1282, 10, 75, 3, 75, 3, 75, 5, 75, 1286, 10, + 75, 3, 75, 3, 75, 5, 75, 1290, 10, 75, 7, 75, 1292, 10, 75, 12, 75, 14, + 75, 1295, 11, 75, 5, 75, 1297, 10, 75, 3, 75, 3, 75, 3, 76, 3, 76, 3, 76, + 3, 76, 5, 76, 1305, 10, 76, 3, 77, 3, 77, 5, 77, 1309, 10, 77, 3, 77, 3, + 77, 5, 77, 1313, 10, 77, 3, 77, 3, 77, 5, 77, 1317, 10, 77, 3, 77, 3, 77, + 5, 77, 1321, 10, 77, 3, 77, 3, 77, 5, 77, 1325, 10, 77, 7, 77, 1327, 10, + 77, 12, 77, 14, 77, 1330, 11, 77, 5, 77, 1332, 10, 77, 3, 77, 3, 77, 3, + 78, 3, 78, 3, 79, 3, 79, 3, 80, 3, 80, 3, 80, 3, 81, 3, 81, 3, 81, 7, 81, + 1346, 10, 81, 12, 81, 14, 81, 1349, 11, 81, 3, 82, 3, 82, 5, 82, 1353, + 10, 82, 3, 82, 3, 82, 5, 82, 1357, 10, 82, 3, 82, 3, 82, 5, 82, 1361, 10, + 82, 3, 82, 5, 82, 1364, 10, 82, 3, 82, 5, 82, 1367, 10, 82, 3, 82, 3, 82, + 3, 83, 3, 83, 5, 83, 1373, 10, 83, 3, 83, 3, 83, 5, 83, 1377, 10, 83, 3, + 83, 3, 83, 5, 83, 1381, 10, 83, 5, 83, 1383, 10, 83, 3, 83, 3, 83, 5, 83, + 1387, 10, 83, 3, 83, 3, 83, 5, 83, 1391, 10, 83, 3, 83, 3, 83, 5, 83, 1395, + 10, 83, 5, 83, 1397, 10, 83, 3, 83, 3, 83, 5, 83, 1401, 10, 83, 3, 83, + 3, 83, 5, 83, 1405, 10, 83, 3, 83, 3, 83, 3, 84, 3, 84, 5, 84, 1411, 10, + 84, 3, 84, 3, 84, 3, 85, 3, 85, 5, 85, 1417, 10, 85, 3, 85, 6, 85, 1420, + 10, 85, 13, 85, 14, 85, 1421, 3, 85, 3, 85, 5, 85, 1426, 10, 85, 3, 85, + 3, 85, 5, 85, 1430, 10, 85, 3, 85, 6, 85, 1433, 10, 85, 13, 85, 14, 85, + 1434, 5, 85, 1437, 10, 85, 3, 85, 5, 85, 1440, 10, 85, 3, 85, 3, 85, 5, + 85, 1444, 10, 85, 3, 85, 5, 85, 1447, 10, 85, 3, 85, 5, 85, 1450, 10, 85, + 3, 85, 3, 85, 3, 86, 3, 86, 5, 86, 1456, 10, 86, 3, 86, 3, 86, 5, 86, 1460, + 10, 86, 3, 86, 3, 86, 5, 86, 1464, 10, 86, 3, 86, 3, 86, 3, 87, 3, 87, + 3, 88, 3, 88, 5, 88, 1472, 10, 88, 3, 89, 3, 89, 5, 89, 1476, 10, 89, 3, + 89, 3, 89, 5, 89, 1480, 10, 89, 3, 89, 3, 89, 5, 89, 1484, 10, 89, 3, 89, + 3, 89, 5, 89, 1488, 10, 89, 3, 89, 3, 89, 5, 89, 1492, 10, 89, 3, 89, 3, + 89, 5, 89, 1496, 10, 89, 3, 89, 3, 89, 5, 89, 1500, 10, 89, 3, 89, 3, 89, + 5, 89, 1504, 10, 89, 7, 89, 1506, 10, 89, 12, 89, 14, 89, 1509, 11, 89, + 5, 89, 1511, 10, 89, 3, 89, 3, 89, 3, 90, 3, 90, 3, 90, 5, 90, 1518, 10, + 90, 3, 91, 3, 91, 5, 91, 1522, 10, 91, 3, 91, 6, 91, 1525, 10, 91, 13, + 91, 14, 91, 1526, 3, 92, 3, 92, 3, 93, 3, 93, 3, 94, 3, 94, 3, 95, 3, 95, + 5, 95, 1537, 10, 95, 3, 96, 3, 96, 3, 97, 3, 97, 3, 98, 3, 98, 3, 99, 3, + 99, 3, 100, 3, 100, 3, 100, 2, 2, 101, 2, 4, 6, 8, 10, 12, 14, 16, 18, + 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, + 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, + 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, + 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, + 152, 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, + 182, 184, 186, 188, 190, 192, 194, 196, 198, 2, 12, 3, 2, 70, 73, 3, 2, + 15, 16, 3, 2, 89, 90, 3, 2, 99, 101, 3, 2, 109, 110, 6, 2, 48, 60, 63, + 84, 89, 96, 111, 120, 6, 2, 85, 88, 102, 102, 121, 123, 126, 126, 4, 2, + 21, 21, 29, 32, 4, 2, 22, 22, 33, 36, 4, 2, 16, 16, 37, 47, 2, 1766, 2, + 201, 3, 2, 2, 2, 4, 215, 3, 2, 2, 2, 6, 219, 3, 2, 2, 2, 8, 221, 3, 2, + 2, 2, 10, 243, 3, 2, 2, 2, 12, 247, 3, 2, 2, 2, 14, 284, 3, 2, 2, 2, 16, + 308, 3, 2, 2, 2, 18, 319, 3, 2, 2, 2, 20, 324, 3, 2, 2, 2, 22, 328, 3, + 2, 2, 2, 24, 341, 3, 2, 2, 2, 26, 351, 3, 2, 2, 2, 28, 373, 3, 2, 2, 2, + 30, 375, 3, 2, 2, 2, 32, 381, 3, 2, 2, 2, 34, 435, 3, 2, 2, 2, 36, 439, + 3, 2, 2, 2, 38, 459, 3, 2, 2, 2, 40, 479, 3, 2, 2, 2, 42, 481, 3, 2, 2, + 2, 44, 492, 3, 2, 2, 2, 46, 519, 3, 2, 2, 2, 48, 532, 3, 2, 2, 2, 50, 536, + 3, 2, 2, 2, 52, 544, 3, 2, 2, 2, 54, 551, 3, 2, 2, 2, 56, 595, 3, 2, 2, + 2, 58, 604, 3, 2, 2, 2, 60, 606, 3, 2, 2, 2, 62, 621, 3, 2, 2, 2, 64, 625, + 3, 2, 2, 2, 66, 629, 3, 2, 2, 2, 68, 636, 3, 2, 2, 2, 70, 640, 3, 2, 2, + 2, 72, 665, 3, 2, 2, 2, 74, 667, 3, 2, 2, 2, 76, 683, 3, 2, 2, 2, 78, 685, + 3, 2, 2, 2, 80, 709, 3, 2, 2, 2, 82, 779, 3, 2, 2, 2, 84, 781, 3, 2, 2, + 2, 86, 810, 3, 2, 2, 2, 88, 812, 3, 2, 2, 2, 90, 833, 3, 2, 2, 2, 92, 843, + 3, 2, 2, 2, 94, 849, 3, 2, 2, 2, 96, 871, 3, 2, 2, 2, 98, 873, 3, 2, 2, + 2, 100, 875, 3, 2, 2, 2, 102, 877, 3, 2, 2, 2, 104, 887, 3, 2, 2, 2, 106, + 897, 3, 2, 2, 2, 108, 913, 3, 2, 2, 2, 110, 918, 3, 2, 2, 2, 112, 928, + 3, 2, 2, 2, 114, 950, 3, 2, 2, 2, 116, 980, 3, 2, 2, 2, 118, 1000, 3, 2, + 2, 2, 120, 1005, 3, 2, 2, 2, 122, 1039, 3, 2, 2, 2, 124, 1051, 3, 2, 2, + 2, 126, 1068, 3, 2, 2, 2, 128, 1070, 3, 2, 2, 2, 130, 1164, 3, 2, 2, 2, + 132, 1172, 3, 2, 2, 2, 134, 1174, 3, 2, 2, 2, 136, 1176, 3, 2, 2, 2, 138, + 1231, 3, 2, 2, 2, 140, 1233, 3, 2, 2, 2, 142, 1243, 3, 2, 2, 2, 144, 1252, + 3, 2, 2, 2, 146, 1259, 3, 2, 2, 2, 148, 1265, 3, 2, 2, 2, 150, 1304, 3, + 2, 2, 2, 152, 1306, 3, 2, 2, 2, 154, 1335, 3, 2, 2, 2, 156, 1337, 3, 2, + 2, 2, 158, 1339, 3, 2, 2, 2, 160, 1347, 3, 2, 2, 2, 162, 1350, 3, 2, 2, + 2, 164, 1370, 3, 2, 2, 2, 166, 1408, 3, 2, 2, 2, 168, 1436, 3, 2, 2, 2, + 170, 1453, 3, 2, 2, 2, 172, 1467, 3, 2, 2, 2, 174, 1471, 3, 2, 2, 2, 176, + 1473, 3, 2, 2, 2, 178, 1514, 3, 2, 2, 2, 180, 1519, 3, 2, 2, 2, 182, 1528, + 3, 2, 2, 2, 184, 1530, 3, 2, 2, 2, 186, 1532, 3, 2, 2, 2, 188, 1536, 3, + 2, 2, 2, 190, 1538, 3, 2, 2, 2, 192, 1540, 3, 2, 2, 2, 194, 1542, 3, 2, + 2, 2, 196, 1544, 3, 2, 2, 2, 198, 1546, 3, 2, 2, 2, 200, 202, 7, 127, 2, + 2, 201, 200, 3, 2, 2, 2, 201, 202, 3, 2, 2, 2, 202, 203, 3, 2, 2, 2, 203, + 208, 5, 4, 3, 2, 204, 206, 7, 127, 2, 2, 205, 204, 3, 2, 2, 2, 205, 206, + 3, 2, 2, 2, 206, 207, 3, 2, 2, 2, 207, 209, 7, 3, 2, 2, 208, 205, 3, 2, + 2, 2, 208, 209, 3, 2, 2, 2, 209, 211, 3, 2, 2, 2, 210, 212, 7, 127, 2, + 2, 211, 210, 3, 2, 2, 2, 211, 212, 3, 2, 2, 2, 212, 213, 3, 2, 2, 2, 213, + 214, 7, 2, 2, 3, 214, 3, 3, 2, 2, 2, 215, 216, 5, 6, 4, 2, 216, 5, 3, 2, + 2, 2, 217, 220, 5, 8, 5, 2, 218, 220, 5, 44, 23, 2, 219, 217, 3, 2, 2, + 2, 219, 218, 3, 2, 2, 2, 220, 7, 3, 2, 2, 2, 221, 228, 5, 12, 7, 2, 222, + 224, 7, 127, 2, 2, 223, 222, 3, 2, 2, 2, 223, 224, 3, 2, 2, 2, 224, 225, + 3, 2, 2, 2, 225, 227, 5, 10, 6, 2, 226, 223, 3, 2, 2, 2, 227, 230, 3, 2, + 2, 2, 228, 226, 3, 2, 2, 2, 228, 229, 3, 2, 2, 2, 229, 9, 3, 2, 2, 2, 230, + 228, 3, 2, 2, 2, 231, 232, 7, 48, 2, 2, 232, 233, 7, 127, 2, 2, 233, 235, + 7, 49, 2, 2, 234, 236, 7, 127, 2, 2, 235, 234, 3, 2, 2, 2, 235, 236, 3, + 2, 2, 2, 236, 237, 3, 2, 2, 2, 237, 244, 5, 12, 7, 2, 238, 240, 7, 48, + 2, 2, 239, 241, 7, 127, 2, 2, 240, 239, 3, 2, 2, 2, 240, 241, 3, 2, 2, + 2, 241, 242, 3, 2, 2, 2, 242, 244, 5, 12, 7, 2, 243, 231, 3, 2, 2, 2, 243, + 238, 3, 2, 2, 2, 244, 11, 3, 2, 2, 2, 245, 248, 5, 14, 8, 2, 246, 248, + 5, 16, 9, 2, 247, 245, 3, 2, 2, 2, 247, 246, 3, 2, 2, 2, 248, 13, 3, 2, + 2, 2, 249, 251, 5, 20, 11, 2, 250, 252, 7, 127, 2, 2, 251, 250, 3, 2, 2, + 2, 251, 252, 3, 2, 2, 2, 252, 254, 3, 2, 2, 2, 253, 249, 3, 2, 2, 2, 254, + 257, 3, 2, 2, 2, 255, 253, 3, 2, 2, 2, 255, 256, 3, 2, 2, 2, 256, 258, + 3, 2, 2, 2, 257, 255, 3, 2, 2, 2, 258, 285, 5, 52, 27, 2, 259, 261, 5, + 20, 11, 2, 260, 262, 7, 127, 2, 2, 261, 260, 3, 2, 2, 2, 261, 262, 3, 2, + 2, 2, 262, 264, 3, 2, 2, 2, 263, 259, 3, 2, 2, 2, 264, 267, 3, 2, 2, 2, + 265, 263, 3, 2, 2, 2, 265, 266, 3, 2, 2, 2, 266, 268, 3, 2, 2, 2, 267, + 265, 3, 2, 2, 2, 268, 275, 5, 18, 10, 2, 269, 271, 7, 127, 2, 2, 270, 269, + 3, 2, 2, 2, 270, 271, 3, 2, 2, 2, 271, 272, 3, 2, 2, 2, 272, 274, 5, 18, + 10, 2, 273, 270, 3, 2, 2, 2, 274, 277, 3, 2, 2, 2, 275, 273, 3, 2, 2, 2, + 275, 276, 3, 2, 2, 2, 276, 282, 3, 2, 2, 2, 277, 275, 3, 2, 2, 2, 278, + 280, 7, 127, 2, 2, 279, 278, 3, 2, 2, 2, 279, 280, 3, 2, 2, 2, 280, 281, + 3, 2, 2, 2, 281, 283, 5, 52, 27, 2, 282, 279, 3, 2, 2, 2, 282, 283, 3, + 2, 2, 2, 283, 285, 3, 2, 2, 2, 284, 255, 3, 2, 2, 2, 284, 265, 3, 2, 2, + 2, 285, 15, 3, 2, 2, 2, 286, 288, 5, 20, 11, 2, 287, 289, 7, 127, 2, 2, + 288, 287, 3, 2, 2, 2, 288, 289, 3, 2, 2, 2, 289, 291, 3, 2, 2, 2, 290, + 286, 3, 2, 2, 2, 291, 294, 3, 2, 2, 2, 292, 290, 3, 2, 2, 2, 292, 293, + 3, 2, 2, 2, 293, 301, 3, 2, 2, 2, 294, 292, 3, 2, 2, 2, 295, 297, 5, 18, + 10, 2, 296, 298, 7, 127, 2, 2, 297, 296, 3, 2, 2, 2, 297, 298, 3, 2, 2, + 2, 298, 300, 3, 2, 2, 2, 299, 295, 3, 2, 2, 2, 300, 303, 3, 2, 2, 2, 301, + 299, 3, 2, 2, 2, 301, 302, 3, 2, 2, 2, 302, 304, 3, 2, 2, 2, 303, 301, + 3, 2, 2, 2, 304, 306, 5, 50, 26, 2, 305, 307, 7, 127, 2, 2, 306, 305, 3, + 2, 2, 2, 306, 307, 3, 2, 2, 2, 307, 309, 3, 2, 2, 2, 308, 292, 3, 2, 2, + 2, 309, 310, 3, 2, 2, 2, 310, 308, 3, 2, 2, 2, 310, 311, 3, 2, 2, 2, 311, + 312, 3, 2, 2, 2, 312, 313, 5, 14, 8, 2, 313, 17, 3, 2, 2, 2, 314, 320, + 5, 30, 16, 2, 315, 320, 5, 26, 14, 2, 316, 320, 5, 36, 19, 2, 317, 320, + 5, 32, 17, 2, 318, 320, 5, 38, 20, 2, 319, 314, 3, 2, 2, 2, 319, 315, 3, + 2, 2, 2, 319, 316, 3, 2, 2, 2, 319, 317, 3, 2, 2, 2, 319, 318, 3, 2, 2, + 2, 320, 19, 3, 2, 2, 2, 321, 325, 5, 22, 12, 2, 322, 325, 5, 24, 13, 2, + 323, 325, 5, 42, 22, 2, 324, 321, 3, 2, 2, 2, 324, 322, 3, 2, 2, 2, 324, + 323, 3, 2, 2, 2, 325, 21, 3, 2, 2, 2, 326, 327, 7, 50, 2, 2, 327, 329, + 7, 127, 2, 2, 328, 326, 3, 2, 2, 2, 328, 329, 3, 2, 2, 2, 329, 330, 3, + 2, 2, 2, 330, 332, 7, 51, 2, 2, 331, 333, 7, 127, 2, 2, 332, 331, 3, 2, + 2, 2, 332, 333, 3, 2, 2, 2, 333, 334, 3, 2, 2, 2, 334, 339, 5, 70, 36, + 2, 335, 337, 7, 127, 2, 2, 336, 335, 3, 2, 2, 2, 336, 337, 3, 2, 2, 2, + 337, 338, 3, 2, 2, 2, 338, 340, 5, 68, 35, 2, 339, 336, 3, 2, 2, 2, 339, + 340, 3, 2, 2, 2, 340, 23, 3, 2, 2, 2, 341, 343, 7, 52, 2, 2, 342, 344, + 7, 127, 2, 2, 343, 342, 3, 2, 2, 2, 343, 344, 3, 2, 2, 2, 344, 345, 3, + 2, 2, 2, 345, 346, 5, 100, 51, 2, 346, 347, 7, 127, 2, 2, 347, 348, 7, + 53, 2, 2, 348, 349, 7, 127, 2, 2, 349, 350, 5, 172, 87, 2, 350, 25, 3, + 2, 2, 2, 351, 353, 7, 54, 2, 2, 352, 354, 7, 127, 2, 2, 353, 352, 3, 2, + 2, 2, 353, 354, 3, 2, 2, 2, 354, 355, 3, 2, 2, 2, 355, 360, 5, 72, 37, + 2, 356, 357, 7, 127, 2, 2, 357, 359, 5, 28, 15, 2, 358, 356, 3, 2, 2, 2, + 359, 362, 3, 2, 2, 2, 360, 358, 3, 2, 2, 2, 360, 361, 3, 2, 2, 2, 361, + 27, 3, 2, 2, 2, 362, 360, 3, 2, 2, 2, 363, 364, 7, 55, 2, 2, 364, 365, + 7, 127, 2, 2, 365, 366, 7, 51, 2, 2, 366, 367, 7, 127, 2, 2, 367, 374, + 5, 32, 17, 2, 368, 369, 7, 55, 2, 2, 369, 370, 7, 127, 2, 2, 370, 371, + 7, 56, 2, 2, 371, 372, 7, 127, 2, 2, 372, 374, 5, 32, 17, 2, 373, 363, + 3, 2, 2, 2, 373, 368, 3, 2, 2, 2, 374, 29, 3, 2, 2, 2, 375, 377, 7, 56, + 2, 2, 376, 378, 7, 127, 2, 2, 377, 376, 3, 2, 2, 2, 377, 378, 3, 2, 2, + 2, 378, 379, 3, 2, 2, 2, 379, 380, 5, 70, 36, 2, 380, 31, 3, 2, 2, 2, 381, + 383, 7, 57, 2, 2, 382, 384, 7, 127, 2, 2, 383, 382, 3, 2, 2, 2, 383, 384, + 3, 2, 2, 2, 384, 385, 3, 2, 2, 2, 385, 396, 5, 34, 18, 2, 386, 388, 7, + 127, 2, 2, 387, 386, 3, 2, 2, 2, 387, 388, 3, 2, 2, 2, 388, 389, 3, 2, + 2, 2, 389, 391, 7, 4, 2, 2, 390, 392, 7, 127, 2, 2, 391, 390, 3, 2, 2, + 2, 391, 392, 3, 2, 2, 2, 392, 393, 3, 2, 2, 2, 393, 395, 5, 34, 18, 2, + 394, 387, 3, 2, 2, 2, 395, 398, 3, 2, 2, 2, 396, 394, 3, 2, 2, 2, 396, + 397, 3, 2, 2, 2, 397, 33, 3, 2, 2, 2, 398, 396, 3, 2, 2, 2, 399, 401, 5, + 180, 91, 2, 400, 402, 7, 127, 2, 2, 401, 400, 3, 2, 2, 2, 401, 402, 3, + 2, 2, 2, 402, 403, 3, 2, 2, 2, 403, 405, 7, 5, 2, 2, 404, 406, 7, 127, + 2, 2, 405, 404, 3, 2, 2, 2, 405, 406, 3, 2, 2, 2, 406, 407, 3, 2, 2, 2, + 407, 408, 5, 100, 51, 2, 408, 436, 3, 2, 2, 2, 409, 411, 5, 172, 87, 2, + 410, 412, 7, 127, 2, 2, 411, 410, 3, 2, 2, 2, 411, 412, 3, 2, 2, 2, 412, + 413, 3, 2, 2, 2, 413, 415, 7, 5, 2, 2, 414, 416, 7, 127, 2, 2, 415, 414, + 3, 2, 2, 2, 415, 416, 3, 2, 2, 2, 416, 417, 3, 2, 2, 2, 417, 418, 5, 100, + 51, 2, 418, 436, 3, 2, 2, 2, 419, 421, 5, 172, 87, 2, 420, 422, 7, 127, + 2, 2, 421, 420, 3, 2, 2, 2, 421, 422, 3, 2, 2, 2, 422, 423, 3, 2, 2, 2, + 423, 425, 7, 6, 2, 2, 424, 426, 7, 127, 2, 2, 425, 424, 3, 2, 2, 2, 425, + 426, 3, 2, 2, 2, 426, 427, 3, 2, 2, 2, 427, 428, 5, 100, 51, 2, 428, 436, + 3, 2, 2, 2, 429, 431, 5, 172, 87, 2, 430, 432, 7, 127, 2, 2, 431, 430, + 3, 2, 2, 2, 431, 432, 3, 2, 2, 2, 432, 433, 3, 2, 2, 2, 433, 434, 5, 90, + 46, 2, 434, 436, 3, 2, 2, 2, 435, 399, 3, 2, 2, 2, 435, 409, 3, 2, 2, 2, + 435, 419, 3, 2, 2, 2, 435, 429, 3, 2, 2, 2, 436, 35, 3, 2, 2, 2, 437, 438, + 7, 58, 2, 2, 438, 440, 7, 127, 2, 2, 439, 437, 3, 2, 2, 2, 439, 440, 3, + 2, 2, 2, 440, 441, 3, 2, 2, 2, 441, 443, 7, 59, 2, 2, 442, 444, 7, 127, + 2, 2, 443, 442, 3, 2, 2, 2, 443, 444, 3, 2, 2, 2, 444, 445, 3, 2, 2, 2, + 445, 456, 5, 100, 51, 2, 446, 448, 7, 127, 2, 2, 447, 446, 3, 2, 2, 2, + 447, 448, 3, 2, 2, 2, 448, 449, 3, 2, 2, 2, 449, 451, 7, 4, 2, 2, 450, + 452, 7, 127, 2, 2, 451, 450, 3, 2, 2, 2, 451, 452, 3, 2, 2, 2, 452, 453, + 3, 2, 2, 2, 453, 455, 5, 100, 51, 2, 454, 447, 3, 2, 2, 2, 455, 458, 3, + 2, 2, 2, 456, 454, 3, 2, 2, 2, 456, 457, 3, 2, 2, 2, 457, 37, 3, 2, 2, + 2, 458, 456, 3, 2, 2, 2, 459, 460, 7, 60, 2, 2, 460, 461, 7, 127, 2, 2, + 461, 472, 5, 40, 21, 2, 462, 464, 7, 127, 2, 2, 463, 462, 3, 2, 2, 2, 463, + 464, 3, 2, 2, 2, 464, 465, 3, 2, 2, 2, 465, 467, 7, 4, 2, 2, 466, 468, + 7, 127, 2, 2, 467, 466, 3, 2, 2, 2, 467, 468, 3, 2, 2, 2, 468, 469, 3, + 2, 2, 2, 469, 471, 5, 40, 21, 2, 470, 463, 3, 2, 2, 2, 471, 474, 3, 2, + 2, 2, 472, 470, 3, 2, 2, 2, 472, 473, 3, 2, 2, 2, 473, 39, 3, 2, 2, 2, + 474, 472, 3, 2, 2, 2, 475, 476, 5, 172, 87, 2, 476, 477, 5, 90, 46, 2, + 477, 480, 3, 2, 2, 2, 478, 480, 5, 180, 91, 2, 479, 475, 3, 2, 2, 2, 479, + 478, 3, 2, 2, 2, 480, 41, 3, 2, 2, 2, 481, 482, 7, 61, 2, 2, 482, 483, + 7, 127, 2, 2, 483, 490, 5, 152, 77, 2, 484, 486, 7, 127, 2, 2, 485, 484, + 3, 2, 2, 2, 485, 486, 3, 2, 2, 2, 486, 487, 3, 2, 2, 2, 487, 488, 7, 62, + 2, 2, 488, 489, 7, 127, 2, 2, 489, 491, 5, 46, 24, 2, 490, 485, 3, 2, 2, + 2, 490, 491, 3, 2, 2, 2, 491, 43, 3, 2, 2, 2, 492, 493, 7, 61, 2, 2, 493, + 496, 7, 127, 2, 2, 494, 497, 5, 152, 77, 2, 495, 497, 5, 154, 78, 2, 496, + 494, 3, 2, 2, 2, 496, 495, 3, 2, 2, 2, 497, 502, 3, 2, 2, 2, 498, 499, + 7, 127, 2, 2, 499, 500, 7, 62, 2, 2, 500, 501, 7, 127, 2, 2, 501, 503, + 5, 46, 24, 2, 502, 498, 3, 2, 2, 2, 502, 503, 3, 2, 2, 2, 503, 45, 3, 2, + 2, 2, 504, 520, 7, 7, 2, 2, 505, 516, 5, 48, 25, 2, 506, 508, 7, 127, 2, + 2, 507, 506, 3, 2, 2, 2, 507, 508, 3, 2, 2, 2, 508, 509, 3, 2, 2, 2, 509, + 511, 7, 4, 2, 2, 510, 512, 7, 127, 2, 2, 511, 510, 3, 2, 2, 2, 511, 512, + 3, 2, 2, 2, 512, 513, 3, 2, 2, 2, 513, 515, 5, 48, 25, 2, 514, 507, 3, + 2, 2, 2, 515, 518, 3, 2, 2, 2, 516, 514, 3, 2, 2, 2, 516, 517, 3, 2, 2, + 2, 517, 520, 3, 2, 2, 2, 518, 516, 3, 2, 2, 2, 519, 504, 3, 2, 2, 2, 519, + 505, 3, 2, 2, 2, 520, 525, 3, 2, 2, 2, 521, 523, 7, 127, 2, 2, 522, 521, + 3, 2, 2, 2, 522, 523, 3, 2, 2, 2, 523, 524, 3, 2, 2, 2, 524, 526, 5, 68, + 35, 2, 525, 522, 3, 2, 2, 2, 525, 526, 3, 2, 2, 2, 526, 47, 3, 2, 2, 2, + 527, 528, 5, 156, 79, 2, 528, 529, 7, 127, 2, 2, 529, 530, 7, 53, 2, 2, + 530, 531, 7, 127, 2, 2, 531, 533, 3, 2, 2, 2, 532, 527, 3, 2, 2, 2, 532, + 533, 3, 2, 2, 2, 533, 534, 3, 2, 2, 2, 534, 535, 5, 172, 87, 2, 535, 49, + 3, 2, 2, 2, 536, 537, 7, 63, 2, 2, 537, 542, 5, 54, 28, 2, 538, 540, 7, + 127, 2, 2, 539, 538, 3, 2, 2, 2, 539, 540, 3, 2, 2, 2, 540, 541, 3, 2, + 2, 2, 541, 543, 5, 68, 35, 2, 542, 539, 3, 2, 2, 2, 542, 543, 3, 2, 2, + 2, 543, 51, 3, 2, 2, 2, 544, 545, 7, 64, 2, 2, 545, 546, 5, 54, 28, 2, + 546, 53, 3, 2, 2, 2, 547, 549, 7, 127, 2, 2, 548, 547, 3, 2, 2, 2, 548, + 549, 3, 2, 2, 2, 549, 550, 3, 2, 2, 2, 550, 552, 7, 65, 2, 2, 551, 548, + 3, 2, 2, 2, 551, 552, 3, 2, 2, 2, 552, 553, 3, 2, 2, 2, 553, 554, 7, 127, + 2, 2, 554, 557, 5, 56, 29, 2, 555, 556, 7, 127, 2, 2, 556, 558, 5, 60, + 31, 2, 557, 555, 3, 2, 2, 2, 557, 558, 3, 2, 2, 2, 558, 561, 3, 2, 2, 2, + 559, 560, 7, 127, 2, 2, 560, 562, 5, 62, 32, 2, 561, 559, 3, 2, 2, 2, 561, + 562, 3, 2, 2, 2, 562, 565, 3, 2, 2, 2, 563, 564, 7, 127, 2, 2, 564, 566, + 5, 64, 33, 2, 565, 563, 3, 2, 2, 2, 565, 566, 3, 2, 2, 2, 566, 55, 3, 2, + 2, 2, 567, 578, 7, 7, 2, 2, 568, 570, 7, 127, 2, 2, 569, 568, 3, 2, 2, + 2, 569, 570, 3, 2, 2, 2, 570, 571, 3, 2, 2, 2, 571, 573, 7, 4, 2, 2, 572, + 574, 7, 127, 2, 2, 573, 572, 3, 2, 2, 2, 573, 574, 3, 2, 2, 2, 574, 575, + 3, 2, 2, 2, 575, 577, 5, 58, 30, 2, 576, 569, 3, 2, 2, 2, 577, 580, 3, + 2, 2, 2, 578, 576, 3, 2, 2, 2, 578, 579, 3, 2, 2, 2, 579, 596, 3, 2, 2, + 2, 580, 578, 3, 2, 2, 2, 581, 592, 5, 58, 30, 2, 582, 584, 7, 127, 2, 2, + 583, 582, 3, 2, 2, 2, 583, 584, 3, 2, 2, 2, 584, 585, 3, 2, 2, 2, 585, + 587, 7, 4, 2, 2, 586, 588, 7, 127, 2, 2, 587, 586, 3, 2, 2, 2, 587, 588, + 3, 2, 2, 2, 588, 589, 3, 2, 2, 2, 589, 591, 5, 58, 30, 2, 590, 583, 3, + 2, 2, 2, 591, 594, 3, 2, 2, 2, 592, 590, 3, 2, 2, 2, 592, 593, 3, 2, 2, + 2, 593, 596, 3, 2, 2, 2, 594, 592, 3, 2, 2, 2, 595, 567, 3, 2, 2, 2, 595, + 581, 3, 2, 2, 2, 596, 57, 3, 2, 2, 2, 597, 598, 5, 100, 51, 2, 598, 599, + 7, 127, 2, 2, 599, 600, 7, 53, 2, 2, 600, 601, 7, 127, 2, 2, 601, 602, + 5, 172, 87, 2, 602, 605, 3, 2, 2, 2, 603, 605, 5, 100, 51, 2, 604, 597, + 3, 2, 2, 2, 604, 603, 3, 2, 2, 2, 605, 59, 3, 2, 2, 2, 606, 607, 7, 66, + 2, 2, 607, 608, 7, 127, 2, 2, 608, 609, 7, 67, 2, 2, 609, 610, 7, 127, + 2, 2, 610, 618, 5, 66, 34, 2, 611, 613, 7, 4, 2, 2, 612, 614, 7, 127, 2, + 2, 613, 612, 3, 2, 2, 2, 613, 614, 3, 2, 2, 2, 614, 615, 3, 2, 2, 2, 615, + 617, 5, 66, 34, 2, 616, 611, 3, 2, 2, 2, 617, 620, 3, 2, 2, 2, 618, 616, + 3, 2, 2, 2, 618, 619, 3, 2, 2, 2, 619, 61, 3, 2, 2, 2, 620, 618, 3, 2, + 2, 2, 621, 622, 7, 68, 2, 2, 622, 623, 7, 127, 2, 2, 623, 624, 5, 100, + 51, 2, 624, 63, 3, 2, 2, 2, 625, 626, 7, 69, 2, 2, 626, 627, 7, 127, 2, + 2, 627, 628, 5, 100, 51, 2, 628, 65, 3, 2, 2, 2, 629, 634, 5, 100, 51, + 2, 630, 632, 7, 127, 2, 2, 631, 630, 3, 2, 2, 2, 631, 632, 3, 2, 2, 2, + 632, 633, 3, 2, 2, 2, 633, 635, 9, 2, 2, 2, 634, 631, 3, 2, 2, 2, 634, + 635, 3, 2, 2, 2, 635, 67, 3, 2, 2, 2, 636, 637, 7, 74, 2, 2, 637, 638, + 7, 127, 2, 2, 638, 639, 5, 100, 51, 2, 639, 69, 3, 2, 2, 2, 640, 651, 5, + 72, 37, 2, 641, 643, 7, 127, 2, 2, 642, 641, 3, 2, 2, 2, 642, 643, 3, 2, + 2, 2, 643, 644, 3, 2, 2, 2, 644, 646, 7, 4, 2, 2, 645, 647, 7, 127, 2, + 2, 646, 645, 3, 2, 2, 2, 646, 647, 3, 2, 2, 2, 647, 648, 3, 2, 2, 2, 648, + 650, 5, 72, 37, 2, 649, 642, 3, 2, 2, 2, 650, 653, 3, 2, 2, 2, 651, 649, + 3, 2, 2, 2, 651, 652, 3, 2, 2, 2, 652, 71, 3, 2, 2, 2, 653, 651, 3, 2, + 2, 2, 654, 656, 5, 172, 87, 2, 655, 657, 7, 127, 2, 2, 656, 655, 3, 2, + 2, 2, 656, 657, 3, 2, 2, 2, 657, 658, 3, 2, 2, 2, 658, 660, 7, 5, 2, 2, + 659, 661, 7, 127, 2, 2, 660, 659, 3, 2, 2, 2, 660, 661, 3, 2, 2, 2, 661, + 662, 3, 2, 2, 2, 662, 663, 5, 74, 38, 2, 663, 666, 3, 2, 2, 2, 664, 666, + 5, 74, 38, 2, 665, 654, 3, 2, 2, 2, 665, 664, 3, 2, 2, 2, 666, 73, 3, 2, + 2, 2, 667, 668, 5, 76, 39, 2, 668, 75, 3, 2, 2, 2, 669, 676, 5, 78, 40, + 2, 670, 672, 7, 127, 2, 2, 671, 670, 3, 2, 2, 2, 671, 672, 3, 2, 2, 2, + 672, 673, 3, 2, 2, 2, 673, 675, 5, 80, 41, 2, 674, 671, 3, 2, 2, 2, 675, + 678, 3, 2, 2, 2, 676, 674, 3, 2, 2, 2, 676, 677, 3, 2, 2, 2, 677, 684, + 3, 2, 2, 2, 678, 676, 3, 2, 2, 2, 679, 680, 7, 8, 2, 2, 680, 681, 5, 76, + 39, 2, 681, 682, 7, 9, 2, 2, 682, 684, 3, 2, 2, 2, 683, 669, 3, 2, 2, 2, + 683, 679, 3, 2, 2, 2, 684, 77, 3, 2, 2, 2, 685, 687, 7, 8, 2, 2, 686, 688, + 7, 127, 2, 2, 687, 686, 3, 2, 2, 2, 687, 688, 3, 2, 2, 2, 688, 693, 3, + 2, 2, 2, 689, 691, 5, 172, 87, 2, 690, 692, 7, 127, 2, 2, 691, 690, 3, + 2, 2, 2, 691, 692, 3, 2, 2, 2, 692, 694, 3, 2, 2, 2, 693, 689, 3, 2, 2, + 2, 693, 694, 3, 2, 2, 2, 694, 699, 3, 2, 2, 2, 695, 697, 5, 90, 46, 2, + 696, 698, 7, 127, 2, 2, 697, 696, 3, 2, 2, 2, 697, 698, 3, 2, 2, 2, 698, + 700, 3, 2, 2, 2, 699, 695, 3, 2, 2, 2, 699, 700, 3, 2, 2, 2, 700, 705, + 3, 2, 2, 2, 701, 703, 5, 86, 44, 2, 702, 704, 7, 127, 2, 2, 703, 702, 3, + 2, 2, 2, 703, 704, 3, 2, 2, 2, 704, 706, 3, 2, 2, 2, 705, 701, 3, 2, 2, + 2, 705, 706, 3, 2, 2, 2, 706, 707, 3, 2, 2, 2, 707, 708, 7, 9, 2, 2, 708, + 79, 3, 2, 2, 2, 709, 711, 5, 82, 42, 2, 710, 712, 7, 127, 2, 2, 711, 710, + 3, 2, 2, 2, 711, 712, 3, 2, 2, 2, 712, 713, 3, 2, 2, 2, 713, 714, 5, 78, + 40, 2, 714, 81, 3, 2, 2, 2, 715, 717, 5, 194, 98, 2, 716, 718, 7, 127, + 2, 2, 717, 716, 3, 2, 2, 2, 717, 718, 3, 2, 2, 2, 718, 719, 3, 2, 2, 2, + 719, 721, 5, 198, 100, 2, 720, 722, 7, 127, 2, 2, 721, 720, 3, 2, 2, 2, + 721, 722, 3, 2, 2, 2, 722, 724, 3, 2, 2, 2, 723, 725, 5, 84, 43, 2, 724, + 723, 3, 2, 2, 2, 724, 725, 3, 2, 2, 2, 725, 727, 3, 2, 2, 2, 726, 728, + 7, 127, 2, 2, 727, 726, 3, 2, 2, 2, 727, 728, 3, 2, 2, 2, 728, 729, 3, + 2, 2, 2, 729, 731, 5, 198, 100, 2, 730, 732, 7, 127, 2, 2, 731, 730, 3, + 2, 2, 2, 731, 732, 3, 2, 2, 2, 732, 733, 3, 2, 2, 2, 733, 734, 5, 196, + 99, 2, 734, 780, 3, 2, 2, 2, 735, 737, 5, 194, 98, 2, 736, 738, 7, 127, + 2, 2, 737, 736, 3, 2, 2, 2, 737, 738, 3, 2, 2, 2, 738, 739, 3, 2, 2, 2, + 739, 741, 5, 198, 100, 2, 740, 742, 7, 127, 2, 2, 741, 740, 3, 2, 2, 2, + 741, 742, 3, 2, 2, 2, 742, 744, 3, 2, 2, 2, 743, 745, 5, 84, 43, 2, 744, + 743, 3, 2, 2, 2, 744, 745, 3, 2, 2, 2, 745, 747, 3, 2, 2, 2, 746, 748, + 7, 127, 2, 2, 747, 746, 3, 2, 2, 2, 747, 748, 3, 2, 2, 2, 748, 749, 3, + 2, 2, 2, 749, 750, 5, 198, 100, 2, 750, 780, 3, 2, 2, 2, 751, 753, 5, 198, + 100, 2, 752, 754, 7, 127, 2, 2, 753, 752, 3, 2, 2, 2, 753, 754, 3, 2, 2, + 2, 754, 756, 3, 2, 2, 2, 755, 757, 5, 84, 43, 2, 756, 755, 3, 2, 2, 2, + 756, 757, 3, 2, 2, 2, 757, 759, 3, 2, 2, 2, 758, 760, 7, 127, 2, 2, 759, + 758, 3, 2, 2, 2, 759, 760, 3, 2, 2, 2, 760, 761, 3, 2, 2, 2, 761, 763, + 5, 198, 100, 2, 762, 764, 7, 127, 2, 2, 763, 762, 3, 2, 2, 2, 763, 764, + 3, 2, 2, 2, 764, 765, 3, 2, 2, 2, 765, 766, 5, 196, 99, 2, 766, 780, 3, + 2, 2, 2, 767, 769, 5, 198, 100, 2, 768, 770, 7, 127, 2, 2, 769, 768, 3, + 2, 2, 2, 769, 770, 3, 2, 2, 2, 770, 772, 3, 2, 2, 2, 771, 773, 5, 84, 43, + 2, 772, 771, 3, 2, 2, 2, 772, 773, 3, 2, 2, 2, 773, 775, 3, 2, 2, 2, 774, + 776, 7, 127, 2, 2, 775, 774, 3, 2, 2, 2, 775, 776, 3, 2, 2, 2, 776, 777, + 3, 2, 2, 2, 777, 778, 5, 198, 100, 2, 778, 780, 3, 2, 2, 2, 779, 715, 3, + 2, 2, 2, 779, 735, 3, 2, 2, 2, 779, 751, 3, 2, 2, 2, 779, 767, 3, 2, 2, + 2, 780, 83, 3, 2, 2, 2, 781, 783, 7, 10, 2, 2, 782, 784, 7, 127, 2, 2, + 783, 782, 3, 2, 2, 2, 783, 784, 3, 2, 2, 2, 784, 789, 3, 2, 2, 2, 785, + 787, 5, 172, 87, 2, 786, 788, 7, 127, 2, 2, 787, 786, 3, 2, 2, 2, 787, + 788, 3, 2, 2, 2, 788, 790, 3, 2, 2, 2, 789, 785, 3, 2, 2, 2, 789, 790, + 3, 2, 2, 2, 790, 795, 3, 2, 2, 2, 791, 793, 5, 88, 45, 2, 792, 794, 7, + 127, 2, 2, 793, 792, 3, 2, 2, 2, 793, 794, 3, 2, 2, 2, 794, 796, 3, 2, + 2, 2, 795, 791, 3, 2, 2, 2, 795, 796, 3, 2, 2, 2, 796, 798, 3, 2, 2, 2, + 797, 799, 5, 94, 48, 2, 798, 797, 3, 2, 2, 2, 798, 799, 3, 2, 2, 2, 799, + 804, 3, 2, 2, 2, 800, 802, 5, 86, 44, 2, 801, 803, 7, 127, 2, 2, 802, 801, + 3, 2, 2, 2, 802, 803, 3, 2, 2, 2, 803, 805, 3, 2, 2, 2, 804, 800, 3, 2, + 2, 2, 804, 805, 3, 2, 2, 2, 805, 806, 3, 2, 2, 2, 806, 807, 7, 11, 2, 2, + 807, 85, 3, 2, 2, 2, 808, 811, 5, 176, 89, 2, 809, 811, 5, 178, 90, 2, + 810, 808, 3, 2, 2, 2, 810, 809, 3, 2, 2, 2, 811, 87, 3, 2, 2, 2, 812, 814, + 7, 12, 2, 2, 813, 815, 7, 127, 2, 2, 814, 813, 3, 2, 2, 2, 814, 815, 3, + 2, 2, 2, 815, 816, 3, 2, 2, 2, 816, 830, 5, 98, 50, 2, 817, 819, 7, 127, + 2, 2, 818, 817, 3, 2, 2, 2, 818, 819, 3, 2, 2, 2, 819, 820, 3, 2, 2, 2, + 820, 822, 7, 13, 2, 2, 821, 823, 7, 12, 2, 2, 822, 821, 3, 2, 2, 2, 822, + 823, 3, 2, 2, 2, 823, 825, 3, 2, 2, 2, 824, 826, 7, 127, 2, 2, 825, 824, + 3, 2, 2, 2, 825, 826, 3, 2, 2, 2, 826, 827, 3, 2, 2, 2, 827, 829, 5, 98, + 50, 2, 828, 818, 3, 2, 2, 2, 829, 832, 3, 2, 2, 2, 830, 828, 3, 2, 2, 2, + 830, 831, 3, 2, 2, 2, 831, 89, 3, 2, 2, 2, 832, 830, 3, 2, 2, 2, 833, 840, + 5, 92, 47, 2, 834, 836, 7, 127, 2, 2, 835, 834, 3, 2, 2, 2, 835, 836, 3, + 2, 2, 2, 836, 837, 3, 2, 2, 2, 837, 839, 5, 92, 47, 2, 838, 835, 3, 2, + 2, 2, 839, 842, 3, 2, 2, 2, 840, 838, 3, 2, 2, 2, 840, 841, 3, 2, 2, 2, + 841, 91, 3, 2, 2, 2, 842, 840, 3, 2, 2, 2, 843, 845, 7, 12, 2, 2, 844, + 846, 7, 127, 2, 2, 845, 844, 3, 2, 2, 2, 845, 846, 3, 2, 2, 2, 846, 847, + 3, 2, 2, 2, 847, 848, 5, 96, 49, 2, 848, 93, 3, 2, 2, 2, 849, 851, 7, 7, + 2, 2, 850, 852, 7, 127, 2, 2, 851, 850, 3, 2, 2, 2, 851, 852, 3, 2, 2, + 2, 852, 857, 3, 2, 2, 2, 853, 855, 5, 184, 93, 2, 854, 856, 7, 127, 2, + 2, 855, 854, 3, 2, 2, 2, 855, 856, 3, 2, 2, 2, 856, 858, 3, 2, 2, 2, 857, + 853, 3, 2, 2, 2, 857, 858, 3, 2, 2, 2, 858, 869, 3, 2, 2, 2, 859, 861, + 7, 14, 2, 2, 860, 862, 7, 127, 2, 2, 861, 860, 3, 2, 2, 2, 861, 862, 3, + 2, 2, 2, 862, 867, 3, 2, 2, 2, 863, 865, 5, 184, 93, 2, 864, 866, 7, 127, + 2, 2, 865, 864, 3, 2, 2, 2, 865, 866, 3, 2, 2, 2, 866, 868, 3, 2, 2, 2, + 867, 863, 3, 2, 2, 2, 867, 868, 3, 2, 2, 2, 868, 870, 3, 2, 2, 2, 869, + 859, 3, 2, 2, 2, 869, 870, 3, 2, 2, 2, 870, 95, 3, 2, 2, 2, 871, 872, 5, + 188, 95, 2, 872, 97, 3, 2, 2, 2, 873, 874, 5, 188, 95, 2, 874, 99, 3, 2, + 2, 2, 875, 876, 5, 102, 52, 2, 876, 101, 3, 2, 2, 2, 877, 884, 5, 104, + 53, 2, 878, 879, 7, 127, 2, 2, 879, 880, 7, 75, 2, 2, 880, 881, 7, 127, + 2, 2, 881, 883, 5, 104, 53, 2, 882, 878, 3, 2, 2, 2, 883, 886, 3, 2, 2, + 2, 884, 882, 3, 2, 2, 2, 884, 885, 3, 2, 2, 2, 885, 103, 3, 2, 2, 2, 886, + 884, 3, 2, 2, 2, 887, 894, 5, 106, 54, 2, 888, 889, 7, 127, 2, 2, 889, + 890, 7, 76, 2, 2, 890, 891, 7, 127, 2, 2, 891, 893, 5, 106, 54, 2, 892, + 888, 3, 2, 2, 2, 893, 896, 3, 2, 2, 2, 894, 892, 3, 2, 2, 2, 894, 895, + 3, 2, 2, 2, 895, 105, 3, 2, 2, 2, 896, 894, 3, 2, 2, 2, 897, 904, 5, 108, + 55, 2, 898, 899, 7, 127, 2, 2, 899, 900, 7, 77, 2, 2, 900, 901, 7, 127, + 2, 2, 901, 903, 5, 108, 55, 2, 902, 898, 3, 2, 2, 2, 903, 906, 3, 2, 2, + 2, 904, 902, 3, 2, 2, 2, 904, 905, 3, 2, 2, 2, 905, 107, 3, 2, 2, 2, 906, + 904, 3, 2, 2, 2, 907, 909, 7, 78, 2, 2, 908, 910, 7, 127, 2, 2, 909, 908, + 3, 2, 2, 2, 909, 910, 3, 2, 2, 2, 910, 912, 3, 2, 2, 2, 911, 907, 3, 2, + 2, 2, 912, 915, 3, 2, 2, 2, 913, 911, 3, 2, 2, 2, 913, 914, 3, 2, 2, 2, + 914, 916, 3, 2, 2, 2, 915, 913, 3, 2, 2, 2, 916, 917, 5, 110, 56, 2, 917, + 109, 3, 2, 2, 2, 918, 925, 5, 112, 57, 2, 919, 921, 7, 127, 2, 2, 920, + 919, 3, 2, 2, 2, 920, 921, 3, 2, 2, 2, 921, 922, 3, 2, 2, 2, 922, 924, + 5, 138, 70, 2, 923, 920, 3, 2, 2, 2, 924, 927, 3, 2, 2, 2, 925, 923, 3, + 2, 2, 2, 925, 926, 3, 2, 2, 2, 926, 111, 3, 2, 2, 2, 927, 925, 3, 2, 2, + 2, 928, 947, 5, 114, 58, 2, 929, 931, 7, 127, 2, 2, 930, 929, 3, 2, 2, + 2, 930, 931, 3, 2, 2, 2, 931, 932, 3, 2, 2, 2, 932, 934, 7, 15, 2, 2, 933, + 935, 7, 127, 2, 2, 934, 933, 3, 2, 2, 2, 934, 935, 3, 2, 2, 2, 935, 936, + 3, 2, 2, 2, 936, 946, 5, 114, 58, 2, 937, 939, 7, 127, 2, 2, 938, 937, + 3, 2, 2, 2, 938, 939, 3, 2, 2, 2, 939, 940, 3, 2, 2, 2, 940, 942, 7, 16, + 2, 2, 941, 943, 7, 127, 2, 2, 942, 941, 3, 2, 2, 2, 942, 943, 3, 2, 2, + 2, 943, 944, 3, 2, 2, 2, 944, 946, 5, 114, 58, 2, 945, 930, 3, 2, 2, 2, + 945, 938, 3, 2, 2, 2, 946, 949, 3, 2, 2, 2, 947, 945, 3, 2, 2, 2, 947, + 948, 3, 2, 2, 2, 948, 113, 3, 2, 2, 2, 949, 947, 3, 2, 2, 2, 950, 977, + 5, 116, 59, 2, 951, 953, 7, 127, 2, 2, 952, 951, 3, 2, 2, 2, 952, 953, + 3, 2, 2, 2, 953, 954, 3, 2, 2, 2, 954, 956, 7, 7, 2, 2, 955, 957, 7, 127, + 2, 2, 956, 955, 3, 2, 2, 2, 956, 957, 3, 2, 2, 2, 957, 958, 3, 2, 2, 2, + 958, 976, 5, 116, 59, 2, 959, 961, 7, 127, 2, 2, 960, 959, 3, 2, 2, 2, + 960, 961, 3, 2, 2, 2, 961, 962, 3, 2, 2, 2, 962, 964, 7, 17, 2, 2, 963, + 965, 7, 127, 2, 2, 964, 963, 3, 2, 2, 2, 964, 965, 3, 2, 2, 2, 965, 966, + 3, 2, 2, 2, 966, 976, 5, 116, 59, 2, 967, 969, 7, 127, 2, 2, 968, 967, + 3, 2, 2, 2, 968, 969, 3, 2, 2, 2, 969, 970, 3, 2, 2, 2, 970, 972, 7, 18, + 2, 2, 971, 973, 7, 127, 2, 2, 972, 971, 3, 2, 2, 2, 972, 973, 3, 2, 2, + 2, 973, 974, 3, 2, 2, 2, 974, 976, 5, 116, 59, 2, 975, 952, 3, 2, 2, 2, + 975, 960, 3, 2, 2, 2, 975, 968, 3, 2, 2, 2, 976, 979, 3, 2, 2, 2, 977, + 975, 3, 2, 2, 2, 977, 978, 3, 2, 2, 2, 978, 115, 3, 2, 2, 2, 979, 977, + 3, 2, 2, 2, 980, 991, 5, 118, 60, 2, 981, 983, 7, 127, 2, 2, 982, 981, + 3, 2, 2, 2, 982, 983, 3, 2, 2, 2, 983, 984, 3, 2, 2, 2, 984, 986, 7, 19, + 2, 2, 985, 987, 7, 127, 2, 2, 986, 985, 3, 2, 2, 2, 986, 987, 3, 2, 2, + 2, 987, 988, 3, 2, 2, 2, 988, 990, 5, 118, 60, 2, 989, 982, 3, 2, 2, 2, + 990, 993, 3, 2, 2, 2, 991, 989, 3, 2, 2, 2, 991, 992, 3, 2, 2, 2, 992, + 117, 3, 2, 2, 2, 993, 991, 3, 2, 2, 2, 994, 996, 9, 3, 2, 2, 995, 997, + 7, 127, 2, 2, 996, 995, 3, 2, 2, 2, 996, 997, 3, 2, 2, 2, 997, 999, 3, + 2, 2, 2, 998, 994, 3, 2, 2, 2, 999, 1002, 3, 2, 2, 2, 1000, 998, 3, 2, + 2, 2, 1000, 1001, 3, 2, 2, 2, 1001, 1003, 3, 2, 2, 2, 1002, 1000, 3, 2, + 2, 2, 1003, 1004, 5, 120, 61, 2, 1004, 119, 3, 2, 2, 2, 1005, 1011, 5, + 128, 65, 2, 1006, 1010, 5, 124, 63, 2, 1007, 1010, 5, 122, 62, 2, 1008, + 1010, 5, 126, 64, 2, 1009, 1006, 3, 2, 2, 2, 1009, 1007, 3, 2, 2, 2, 1009, + 1008, 3, 2, 2, 2, 1010, 1013, 3, 2, 2, 2, 1011, 1009, 3, 2, 2, 2, 1011, + 1012, 3, 2, 2, 2, 1012, 121, 3, 2, 2, 2, 1013, 1011, 3, 2, 2, 2, 1014, + 1015, 7, 127, 2, 2, 1015, 1017, 7, 79, 2, 2, 1016, 1018, 7, 127, 2, 2, + 1017, 1016, 3, 2, 2, 2, 1017, 1018, 3, 2, 2, 2, 1018, 1019, 3, 2, 2, 2, + 1019, 1040, 5, 128, 65, 2, 1020, 1022, 7, 127, 2, 2, 1021, 1020, 3, 2, + 2, 2, 1021, 1022, 3, 2, 2, 2, 1022, 1023, 3, 2, 2, 2, 1023, 1024, 7, 10, + 2, 2, 1024, 1025, 5, 100, 51, 2, 1025, 1026, 7, 11, 2, 2, 1026, 1040, 3, + 2, 2, 2, 1027, 1029, 7, 127, 2, 2, 1028, 1027, 3, 2, 2, 2, 1028, 1029, + 3, 2, 2, 2, 1029, 1030, 3, 2, 2, 2, 1030, 1032, 7, 10, 2, 2, 1031, 1033, + 5, 100, 51, 2, 1032, 1031, 3, 2, 2, 2, 1032, 1033, 3, 2, 2, 2, 1033, 1034, + 3, 2, 2, 2, 1034, 1036, 7, 14, 2, 2, 1035, 1037, 5, 100, 51, 2, 1036, 1035, + 3, 2, 2, 2, 1036, 1037, 3, 2, 2, 2, 1037, 1038, 3, 2, 2, 2, 1038, 1040, + 7, 11, 2, 2, 1039, 1014, 3, 2, 2, 2, 1039, 1021, 3, 2, 2, 2, 1039, 1028, + 3, 2, 2, 2, 1040, 123, 3, 2, 2, 2, 1041, 1042, 7, 127, 2, 2, 1042, 1043, + 7, 80, 2, 2, 1043, 1044, 7, 127, 2, 2, 1044, 1052, 7, 63, 2, 2, 1045, 1046, + 7, 127, 2, 2, 1046, 1047, 7, 81, 2, 2, 1047, 1048, 7, 127, 2, 2, 1048, + 1052, 7, 63, 2, 2, 1049, 1050, 7, 127, 2, 2, 1050, 1052, 7, 82, 2, 2, 1051, + 1041, 3, 2, 2, 2, 1051, 1045, 3, 2, 2, 2, 1051, 1049, 3, 2, 2, 2, 1052, + 1054, 3, 2, 2, 2, 1053, 1055, 7, 127, 2, 2, 1054, 1053, 3, 2, 2, 2, 1054, + 1055, 3, 2, 2, 2, 1055, 1056, 3, 2, 2, 2, 1056, 1057, 5, 128, 65, 2, 1057, + 125, 3, 2, 2, 2, 1058, 1059, 7, 127, 2, 2, 1059, 1060, 7, 83, 2, 2, 1060, + 1061, 7, 127, 2, 2, 1061, 1069, 7, 84, 2, 2, 1062, 1063, 7, 127, 2, 2, + 1063, 1064, 7, 83, 2, 2, 1064, 1065, 7, 127, 2, 2, 1065, 1066, 7, 78, 2, + 2, 1066, 1067, 7, 127, 2, 2, 1067, 1069, 7, 84, 2, 2, 1068, 1058, 3, 2, + 2, 2, 1068, 1062, 3, 2, 2, 2, 1069, 127, 3, 2, 2, 2, 1070, 1077, 5, 130, + 66, 2, 1071, 1073, 7, 127, 2, 2, 1072, 1071, 3, 2, 2, 2, 1072, 1073, 3, + 2, 2, 2, 1073, 1074, 3, 2, 2, 2, 1074, 1076, 5, 166, 84, 2, 1075, 1072, + 3, 2, 2, 2, 1076, 1079, 3, 2, 2, 2, 1077, 1075, 3, 2, 2, 2, 1077, 1078, + 3, 2, 2, 2, 1078, 1084, 3, 2, 2, 2, 1079, 1077, 3, 2, 2, 2, 1080, 1082, + 7, 127, 2, 2, 1081, 1080, 3, 2, 2, 2, 1081, 1082, 3, 2, 2, 2, 1082, 1083, + 3, 2, 2, 2, 1083, 1085, 5, 90, 46, 2, 1084, 1081, 3, 2, 2, 2, 1084, 1085, + 3, 2, 2, 2, 1085, 129, 3, 2, 2, 2, 1086, 1165, 5, 132, 67, 2, 1087, 1165, + 5, 178, 90, 2, 1088, 1165, 5, 168, 85, 2, 1089, 1091, 7, 85, 2, 2, 1090, + 1092, 7, 127, 2, 2, 1091, 1090, 3, 2, 2, 2, 1091, 1092, 3, 2, 2, 2, 1092, + 1093, 3, 2, 2, 2, 1093, 1095, 7, 8, 2, 2, 1094, 1096, 7, 127, 2, 2, 1095, + 1094, 3, 2, 2, 2, 1095, 1096, 3, 2, 2, 2, 1096, 1097, 3, 2, 2, 2, 1097, + 1099, 7, 7, 2, 2, 1098, 1100, 7, 127, 2, 2, 1099, 1098, 3, 2, 2, 2, 1099, + 1100, 3, 2, 2, 2, 1100, 1101, 3, 2, 2, 2, 1101, 1165, 7, 9, 2, 2, 1102, + 1165, 5, 162, 82, 2, 1103, 1165, 5, 164, 83, 2, 1104, 1106, 7, 49, 2, 2, + 1105, 1107, 7, 127, 2, 2, 1106, 1105, 3, 2, 2, 2, 1106, 1107, 3, 2, 2, + 2, 1107, 1108, 3, 2, 2, 2, 1108, 1110, 7, 8, 2, 2, 1109, 1111, 7, 127, + 2, 2, 1110, 1109, 3, 2, 2, 2, 1110, 1111, 3, 2, 2, 2, 1111, 1112, 3, 2, + 2, 2, 1112, 1114, 5, 144, 73, 2, 1113, 1115, 7, 127, 2, 2, 1114, 1113, + 3, 2, 2, 2, 1114, 1115, 3, 2, 2, 2, 1115, 1116, 3, 2, 2, 2, 1116, 1117, + 7, 9, 2, 2, 1117, 1165, 3, 2, 2, 2, 1118, 1120, 7, 86, 2, 2, 1119, 1121, + 7, 127, 2, 2, 1120, 1119, 3, 2, 2, 2, 1120, 1121, 3, 2, 2, 2, 1121, 1122, + 3, 2, 2, 2, 1122, 1124, 7, 8, 2, 2, 1123, 1125, 7, 127, 2, 2, 1124, 1123, + 3, 2, 2, 2, 1124, 1125, 3, 2, 2, 2, 1125, 1126, 3, 2, 2, 2, 1126, 1128, + 5, 144, 73, 2, 1127, 1129, 7, 127, 2, 2, 1128, 1127, 3, 2, 2, 2, 1128, + 1129, 3, 2, 2, 2, 1129, 1130, 3, 2, 2, 2, 1130, 1131, 7, 9, 2, 2, 1131, + 1165, 3, 2, 2, 2, 1132, 1134, 7, 87, 2, 2, 1133, 1135, 7, 127, 2, 2, 1134, + 1133, 3, 2, 2, 2, 1134, 1135, 3, 2, 2, 2, 1135, 1136, 3, 2, 2, 2, 1136, + 1138, 7, 8, 2, 2, 1137, 1139, 7, 127, 2, 2, 1138, 1137, 3, 2, 2, 2, 1138, + 1139, 3, 2, 2, 2, 1139, 1140, 3, 2, 2, 2, 1140, 1142, 5, 144, 73, 2, 1141, + 1143, 7, 127, 2, 2, 1142, 1141, 3, 2, 2, 2, 1142, 1143, 3, 2, 2, 2, 1143, + 1144, 3, 2, 2, 2, 1144, 1145, 7, 9, 2, 2, 1145, 1165, 3, 2, 2, 2, 1146, + 1148, 7, 88, 2, 2, 1147, 1149, 7, 127, 2, 2, 1148, 1147, 3, 2, 2, 2, 1148, + 1149, 3, 2, 2, 2, 1149, 1150, 3, 2, 2, 2, 1150, 1152, 7, 8, 2, 2, 1151, + 1153, 7, 127, 2, 2, 1152, 1151, 3, 2, 2, 2, 1152, 1153, 3, 2, 2, 2, 1153, + 1154, 3, 2, 2, 2, 1154, 1156, 5, 144, 73, 2, 1155, 1157, 7, 127, 2, 2, + 1156, 1155, 3, 2, 2, 2, 1156, 1157, 3, 2, 2, 2, 1157, 1158, 3, 2, 2, 2, + 1158, 1159, 7, 9, 2, 2, 1159, 1165, 3, 2, 2, 2, 1160, 1165, 5, 142, 72, + 2, 1161, 1165, 5, 140, 71, 2, 1162, 1165, 5, 148, 75, 2, 1163, 1165, 5, + 172, 87, 2, 1164, 1086, 3, 2, 2, 2, 1164, 1087, 3, 2, 2, 2, 1164, 1088, + 3, 2, 2, 2, 1164, 1089, 3, 2, 2, 2, 1164, 1102, 3, 2, 2, 2, 1164, 1103, + 3, 2, 2, 2, 1164, 1104, 3, 2, 2, 2, 1164, 1118, 3, 2, 2, 2, 1164, 1132, + 3, 2, 2, 2, 1164, 1146, 3, 2, 2, 2, 1164, 1160, 3, 2, 2, 2, 1164, 1161, + 3, 2, 2, 2, 1164, 1162, 3, 2, 2, 2, 1164, 1163, 3, 2, 2, 2, 1165, 131, + 3, 2, 2, 2, 1166, 1173, 5, 174, 88, 2, 1167, 1173, 7, 97, 2, 2, 1168, 1173, + 5, 134, 68, 2, 1169, 1173, 7, 84, 2, 2, 1170, 1173, 5, 176, 89, 2, 1171, + 1173, 5, 136, 69, 2, 1172, 1166, 3, 2, 2, 2, 1172, 1167, 3, 2, 2, 2, 1172, + 1168, 3, 2, 2, 2, 1172, 1169, 3, 2, 2, 2, 1172, 1170, 3, 2, 2, 2, 1172, + 1171, 3, 2, 2, 2, 1173, 133, 3, 2, 2, 2, 1174, 1175, 9, 4, 2, 2, 1175, + 135, 3, 2, 2, 2, 1176, 1178, 7, 10, 2, 2, 1177, 1179, 7, 127, 2, 2, 1178, + 1177, 3, 2, 2, 2, 1178, 1179, 3, 2, 2, 2, 1179, 1197, 3, 2, 2, 2, 1180, + 1182, 5, 100, 51, 2, 1181, 1183, 7, 127, 2, 2, 1182, 1181, 3, 2, 2, 2, + 1182, 1183, 3, 2, 2, 2, 1183, 1194, 3, 2, 2, 2, 1184, 1186, 7, 4, 2, 2, + 1185, 1187, 7, 127, 2, 2, 1186, 1185, 3, 2, 2, 2, 1186, 1187, 3, 2, 2, + 2, 1187, 1188, 3, 2, 2, 2, 1188, 1190, 5, 100, 51, 2, 1189, 1191, 7, 127, + 2, 2, 1190, 1189, 3, 2, 2, 2, 1190, 1191, 3, 2, 2, 2, 1191, 1193, 3, 2, + 2, 2, 1192, 1184, 3, 2, 2, 2, 1193, 1196, 3, 2, 2, 2, 1194, 1192, 3, 2, + 2, 2, 1194, 1195, 3, 2, 2, 2, 1195, 1198, 3, 2, 2, 2, 1196, 1194, 3, 2, + 2, 2, 1197, 1180, 3, 2, 2, 2, 1197, 1198, 3, 2, 2, 2, 1198, 1199, 3, 2, + 2, 2, 1199, 1200, 7, 11, 2, 2, 1200, 137, 3, 2, 2, 2, 1201, 1203, 7, 5, + 2, 2, 1202, 1204, 7, 127, 2, 2, 1203, 1202, 3, 2, 2, 2, 1203, 1204, 3, + 2, 2, 2, 1204, 1205, 3, 2, 2, 2, 1205, 1232, 5, 112, 57, 2, 1206, 1208, + 7, 20, 2, 2, 1207, 1209, 7, 127, 2, 2, 1208, 1207, 3, 2, 2, 2, 1208, 1209, + 3, 2, 2, 2, 1209, 1210, 3, 2, 2, 2, 1210, 1232, 5, 112, 57, 2, 1211, 1213, + 7, 21, 2, 2, 1212, 1214, 7, 127, 2, 2, 1213, 1212, 3, 2, 2, 2, 1213, 1214, + 3, 2, 2, 2, 1214, 1215, 3, 2, 2, 2, 1215, 1232, 5, 112, 57, 2, 1216, 1218, + 7, 22, 2, 2, 1217, 1219, 7, 127, 2, 2, 1218, 1217, 3, 2, 2, 2, 1218, 1219, + 3, 2, 2, 2, 1219, 1220, 3, 2, 2, 2, 1220, 1232, 5, 112, 57, 2, 1221, 1223, + 7, 23, 2, 2, 1222, 1224, 7, 127, 2, 2, 1223, 1222, 3, 2, 2, 2, 1223, 1224, + 3, 2, 2, 2, 1224, 1225, 3, 2, 2, 2, 1225, 1232, 5, 112, 57, 2, 1226, 1228, + 7, 24, 2, 2, 1227, 1229, 7, 127, 2, 2, 1228, 1227, 3, 2, 2, 2, 1228, 1229, + 3, 2, 2, 2, 1229, 1230, 3, 2, 2, 2, 1230, 1232, 5, 112, 57, 2, 1231, 1201, + 3, 2, 2, 2, 1231, 1206, 3, 2, 2, 2, 1231, 1211, 3, 2, 2, 2, 1231, 1216, + 3, 2, 2, 2, 1231, 1221, 3, 2, 2, 2, 1231, 1226, 3, 2, 2, 2, 1232, 139, + 3, 2, 2, 2, 1233, 1235, 7, 8, 2, 2, 1234, 1236, 7, 127, 2, 2, 1235, 1234, + 3, 2, 2, 2, 1235, 1236, 3, 2, 2, 2, 1236, 1237, 3, 2, 2, 2, 1237, 1239, + 5, 100, 51, 2, 1238, 1240, 7, 127, 2, 2, 1239, 1238, 3, 2, 2, 2, 1239, + 1240, 3, 2, 2, 2, 1240, 1241, 3, 2, 2, 2, 1241, 1242, 7, 9, 2, 2, 1242, + 141, 3, 2, 2, 2, 1243, 1248, 5, 78, 40, 2, 1244, 1246, 7, 127, 2, 2, 1245, + 1244, 3, 2, 2, 2, 1245, 1246, 3, 2, 2, 2, 1246, 1247, 3, 2, 2, 2, 1247, + 1249, 5, 80, 41, 2, 1248, 1245, 3, 2, 2, 2, 1249, 1250, 3, 2, 2, 2, 1250, + 1248, 3, 2, 2, 2, 1250, 1251, 3, 2, 2, 2, 1251, 143, 3, 2, 2, 2, 1252, + 1257, 5, 146, 74, 2, 1253, 1255, 7, 127, 2, 2, 1254, 1253, 3, 2, 2, 2, + 1254, 1255, 3, 2, 2, 2, 1255, 1256, 3, 2, 2, 2, 1256, 1258, 5, 68, 35, + 2, 1257, 1254, 3, 2, 2, 2, 1257, 1258, 3, 2, 2, 2, 1258, 145, 3, 2, 2, + 2, 1259, 1260, 5, 172, 87, 2, 1260, 1261, 7, 127, 2, 2, 1261, 1262, 7, + 79, 2, 2, 1262, 1263, 7, 127, 2, 2, 1263, 1264, 5, 100, 51, 2, 1264, 147, + 3, 2, 2, 2, 1265, 1267, 5, 150, 76, 2, 1266, 1268, 7, 127, 2, 2, 1267, + 1266, 3, 2, 2, 2, 1267, 1268, 3, 2, 2, 2, 1268, 1269, 3, 2, 2, 2, 1269, + 1271, 7, 8, 2, 2, 1270, 1272, 7, 127, 2, 2, 1271, 1270, 3, 2, 2, 2, 1271, + 1272, 3, 2, 2, 2, 1272, 1277, 3, 2, 2, 2, 1273, 1275, 7, 65, 2, 2, 1274, + 1276, 7, 127, 2, 2, 1275, 1274, 3, 2, 2, 2, 1275, 1276, 3, 2, 2, 2, 1276, + 1278, 3, 2, 2, 2, 1277, 1273, 3, 2, 2, 2, 1277, 1278, 3, 2, 2, 2, 1278, + 1296, 3, 2, 2, 2, 1279, 1281, 5, 100, 51, 2, 1280, 1282, 7, 127, 2, 2, + 1281, 1280, 3, 2, 2, 2, 1281, 1282, 3, 2, 2, 2, 1282, 1293, 3, 2, 2, 2, + 1283, 1285, 7, 4, 2, 2, 1284, 1286, 7, 127, 2, 2, 1285, 1284, 3, 2, 2, + 2, 1285, 1286, 3, 2, 2, 2, 1286, 1287, 3, 2, 2, 2, 1287, 1289, 5, 100, + 51, 2, 1288, 1290, 7, 127, 2, 2, 1289, 1288, 3, 2, 2, 2, 1289, 1290, 3, + 2, 2, 2, 1290, 1292, 3, 2, 2, 2, 1291, 1283, 3, 2, 2, 2, 1292, 1295, 3, + 2, 2, 2, 1293, 1291, 3, 2, 2, 2, 1293, 1294, 3, 2, 2, 2, 1294, 1297, 3, + 2, 2, 2, 1295, 1293, 3, 2, 2, 2, 1296, 1279, 3, 2, 2, 2, 1296, 1297, 3, + 2, 2, 2, 1297, 1298, 3, 2, 2, 2, 1298, 1299, 7, 9, 2, 2, 1299, 149, 3, + 2, 2, 2, 1300, 1301, 5, 160, 81, 2, 1301, 1302, 5, 192, 97, 2, 1302, 1305, + 3, 2, 2, 2, 1303, 1305, 7, 91, 2, 2, 1304, 1300, 3, 2, 2, 2, 1304, 1303, + 3, 2, 2, 2, 1305, 151, 3, 2, 2, 2, 1306, 1308, 5, 158, 80, 2, 1307, 1309, + 7, 127, 2, 2, 1308, 1307, 3, 2, 2, 2, 1308, 1309, 3, 2, 2, 2, 1309, 1310, + 3, 2, 2, 2, 1310, 1312, 7, 8, 2, 2, 1311, 1313, 7, 127, 2, 2, 1312, 1311, + 3, 2, 2, 2, 1312, 1313, 3, 2, 2, 2, 1313, 1331, 3, 2, 2, 2, 1314, 1316, + 5, 100, 51, 2, 1315, 1317, 7, 127, 2, 2, 1316, 1315, 3, 2, 2, 2, 1316, + 1317, 3, 2, 2, 2, 1317, 1328, 3, 2, 2, 2, 1318, 1320, 7, 4, 2, 2, 1319, + 1321, 7, 127, 2, 2, 1320, 1319, 3, 2, 2, 2, 1320, 1321, 3, 2, 2, 2, 1321, + 1322, 3, 2, 2, 2, 1322, 1324, 5, 100, 51, 2, 1323, 1325, 7, 127, 2, 2, + 1324, 1323, 3, 2, 2, 2, 1324, 1325, 3, 2, 2, 2, 1325, 1327, 3, 2, 2, 2, + 1326, 1318, 3, 2, 2, 2, 1327, 1330, 3, 2, 2, 2, 1328, 1326, 3, 2, 2, 2, + 1328, 1329, 3, 2, 2, 2, 1329, 1332, 3, 2, 2, 2, 1330, 1328, 3, 2, 2, 2, + 1331, 1314, 3, 2, 2, 2, 1331, 1332, 3, 2, 2, 2, 1332, 1333, 3, 2, 2, 2, + 1333, 1334, 7, 9, 2, 2, 1334, 153, 3, 2, 2, 2, 1335, 1336, 5, 158, 80, + 2, 1336, 155, 3, 2, 2, 2, 1337, 1338, 5, 192, 97, 2, 1338, 157, 3, 2, 2, + 2, 1339, 1340, 5, 160, 81, 2, 1340, 1341, 5, 192, 97, 2, 1341, 159, 3, + 2, 2, 2, 1342, 1343, 5, 192, 97, 2, 1343, 1344, 7, 25, 2, 2, 1344, 1346, + 3, 2, 2, 2, 1345, 1342, 3, 2, 2, 2, 1346, 1349, 3, 2, 2, 2, 1347, 1345, + 3, 2, 2, 2, 1347, 1348, 3, 2, 2, 2, 1348, 161, 3, 2, 2, 2, 1349, 1347, + 3, 2, 2, 2, 1350, 1352, 7, 10, 2, 2, 1351, 1353, 7, 127, 2, 2, 1352, 1351, + 3, 2, 2, 2, 1352, 1353, 3, 2, 2, 2, 1353, 1354, 3, 2, 2, 2, 1354, 1363, + 5, 144, 73, 2, 1355, 1357, 7, 127, 2, 2, 1356, 1355, 3, 2, 2, 2, 1356, + 1357, 3, 2, 2, 2, 1357, 1358, 3, 2, 2, 2, 1358, 1360, 7, 13, 2, 2, 1359, + 1361, 7, 127, 2, 2, 1360, 1359, 3, 2, 2, 2, 1360, 1361, 3, 2, 2, 2, 1361, + 1362, 3, 2, 2, 2, 1362, 1364, 5, 100, 51, 2, 1363, 1356, 3, 2, 2, 2, 1363, + 1364, 3, 2, 2, 2, 1364, 1366, 3, 2, 2, 2, 1365, 1367, 7, 127, 2, 2, 1366, + 1365, 3, 2, 2, 2, 1366, 1367, 3, 2, 2, 2, 1367, 1368, 3, 2, 2, 2, 1368, + 1369, 7, 11, 2, 2, 1369, 163, 3, 2, 2, 2, 1370, 1372, 7, 10, 2, 2, 1371, + 1373, 7, 127, 2, 2, 1372, 1371, 3, 2, 2, 2, 1372, 1373, 3, 2, 2, 2, 1373, + 1382, 3, 2, 2, 2, 1374, 1376, 5, 172, 87, 2, 1375, 1377, 7, 127, 2, 2, + 1376, 1375, 3, 2, 2, 2, 1376, 1377, 3, 2, 2, 2, 1377, 1378, 3, 2, 2, 2, + 1378, 1380, 7, 5, 2, 2, 1379, 1381, 7, 127, 2, 2, 1380, 1379, 3, 2, 2, + 2, 1380, 1381, 3, 2, 2, 2, 1381, 1383, 3, 2, 2, 2, 1382, 1374, 3, 2, 2, + 2, 1382, 1383, 3, 2, 2, 2, 1383, 1384, 3, 2, 2, 2, 1384, 1386, 5, 142, + 72, 2, 1385, 1387, 7, 127, 2, 2, 1386, 1385, 3, 2, 2, 2, 1386, 1387, 3, + 2, 2, 2, 1387, 1396, 3, 2, 2, 2, 1388, 1390, 7, 74, 2, 2, 1389, 1391, 7, + 127, 2, 2, 1390, 1389, 3, 2, 2, 2, 1390, 1391, 3, 2, 2, 2, 1391, 1392, + 3, 2, 2, 2, 1392, 1394, 5, 100, 51, 2, 1393, 1395, 7, 127, 2, 2, 1394, + 1393, 3, 2, 2, 2, 1394, 1395, 3, 2, 2, 2, 1395, 1397, 3, 2, 2, 2, 1396, + 1388, 3, 2, 2, 2, 1396, 1397, 3, 2, 2, 2, 1397, 1398, 3, 2, 2, 2, 1398, + 1400, 7, 13, 2, 2, 1399, 1401, 7, 127, 2, 2, 1400, 1399, 3, 2, 2, 2, 1400, + 1401, 3, 2, 2, 2, 1401, 1402, 3, 2, 2, 2, 1402, 1404, 5, 100, 51, 2, 1403, + 1405, 7, 127, 2, 2, 1404, 1403, 3, 2, 2, 2, 1404, 1405, 3, 2, 2, 2, 1405, + 1406, 3, 2, 2, 2, 1406, 1407, 7, 11, 2, 2, 1407, 165, 3, 2, 2, 2, 1408, + 1410, 7, 25, 2, 2, 1409, 1411, 7, 127, 2, 2, 1410, 1409, 3, 2, 2, 2, 1410, + 1411, 3, 2, 2, 2, 1411, 1412, 3, 2, 2, 2, 1412, 1413, 5, 182, 92, 2, 1413, + 167, 3, 2, 2, 2, 1414, 1419, 7, 92, 2, 2, 1415, 1417, 7, 127, 2, 2, 1416, + 1415, 3, 2, 2, 2, 1416, 1417, 3, 2, 2, 2, 1417, 1418, 3, 2, 2, 2, 1418, + 1420, 5, 170, 86, 2, 1419, 1416, 3, 2, 2, 2, 1420, 1421, 3, 2, 2, 2, 1421, + 1419, 3, 2, 2, 2, 1421, 1422, 3, 2, 2, 2, 1422, 1437, 3, 2, 2, 2, 1423, + 1425, 7, 92, 2, 2, 1424, 1426, 7, 127, 2, 2, 1425, 1424, 3, 2, 2, 2, 1425, + 1426, 3, 2, 2, 2, 1426, 1427, 3, 2, 2, 2, 1427, 1432, 5, 100, 51, 2, 1428, + 1430, 7, 127, 2, 2, 1429, 1428, 3, 2, 2, 2, 1429, 1430, 3, 2, 2, 2, 1430, + 1431, 3, 2, 2, 2, 1431, 1433, 5, 170, 86, 2, 1432, 1429, 3, 2, 2, 2, 1433, + 1434, 3, 2, 2, 2, 1434, 1432, 3, 2, 2, 2, 1434, 1435, 3, 2, 2, 2, 1435, + 1437, 3, 2, 2, 2, 1436, 1414, 3, 2, 2, 2, 1436, 1423, 3, 2, 2, 2, 1437, + 1446, 3, 2, 2, 2, 1438, 1440, 7, 127, 2, 2, 1439, 1438, 3, 2, 2, 2, 1439, + 1440, 3, 2, 2, 2, 1440, 1441, 3, 2, 2, 2, 1441, 1443, 7, 93, 2, 2, 1442, + 1444, 7, 127, 2, 2, 1443, 1442, 3, 2, 2, 2, 1443, 1444, 3, 2, 2, 2, 1444, + 1445, 3, 2, 2, 2, 1445, 1447, 5, 100, 51, 2, 1446, 1439, 3, 2, 2, 2, 1446, + 1447, 3, 2, 2, 2, 1447, 1449, 3, 2, 2, 2, 1448, 1450, 7, 127, 2, 2, 1449, + 1448, 3, 2, 2, 2, 1449, 1450, 3, 2, 2, 2, 1450, 1451, 3, 2, 2, 2, 1451, + 1452, 7, 94, 2, 2, 1452, 169, 3, 2, 2, 2, 1453, 1455, 7, 95, 2, 2, 1454, + 1456, 7, 127, 2, 2, 1455, 1454, 3, 2, 2, 2, 1455, 1456, 3, 2, 2, 2, 1456, + 1457, 3, 2, 2, 2, 1457, 1459, 5, 100, 51, 2, 1458, 1460, 7, 127, 2, 2, + 1459, 1458, 3, 2, 2, 2, 1459, 1460, 3, 2, 2, 2, 1460, 1461, 3, 2, 2, 2, + 1461, 1463, 7, 96, 2, 2, 1462, 1464, 7, 127, 2, 2, 1463, 1462, 3, 2, 2, + 2, 1463, 1464, 3, 2, 2, 2, 1464, 1465, 3, 2, 2, 2, 1465, 1466, 5, 100, + 51, 2, 1466, 171, 3, 2, 2, 2, 1467, 1468, 5, 192, 97, 2, 1468, 173, 3, + 2, 2, 2, 1469, 1472, 5, 186, 94, 2, 1470, 1472, 5, 184, 93, 2, 1471, 1469, + 3, 2, 2, 2, 1471, 1470, 3, 2, 2, 2, 1472, 175, 3, 2, 2, 2, 1473, 1475, + 7, 26, 2, 2, 1474, 1476, 7, 127, 2, 2, 1475, 1474, 3, 2, 2, 2, 1475, 1476, + 3, 2, 2, 2, 1476, 1510, 3, 2, 2, 2, 1477, 1479, 5, 182, 92, 2, 1478, 1480, + 7, 127, 2, 2, 1479, 1478, 3, 2, 2, 2, 1479, 1480, 3, 2, 2, 2, 1480, 1481, + 3, 2, 2, 2, 1481, 1483, 7, 12, 2, 2, 1482, 1484, 7, 127, 2, 2, 1483, 1482, + 3, 2, 2, 2, 1483, 1484, 3, 2, 2, 2, 1484, 1485, 3, 2, 2, 2, 1485, 1487, + 5, 100, 51, 2, 1486, 1488, 7, 127, 2, 2, 1487, 1486, 3, 2, 2, 2, 1487, + 1488, 3, 2, 2, 2, 1488, 1507, 3, 2, 2, 2, 1489, 1491, 7, 4, 2, 2, 1490, + 1492, 7, 127, 2, 2, 1491, 1490, 3, 2, 2, 2, 1491, 1492, 3, 2, 2, 2, 1492, + 1493, 3, 2, 2, 2, 1493, 1495, 5, 182, 92, 2, 1494, 1496, 7, 127, 2, 2, + 1495, 1494, 3, 2, 2, 2, 1495, 1496, 3, 2, 2, 2, 1496, 1497, 3, 2, 2, 2, + 1497, 1499, 7, 12, 2, 2, 1498, 1500, 7, 127, 2, 2, 1499, 1498, 3, 2, 2, + 2, 1499, 1500, 3, 2, 2, 2, 1500, 1501, 3, 2, 2, 2, 1501, 1503, 5, 100, + 51, 2, 1502, 1504, 7, 127, 2, 2, 1503, 1502, 3, 2, 2, 2, 1503, 1504, 3, + 2, 2, 2, 1504, 1506, 3, 2, 2, 2, 1505, 1489, 3, 2, 2, 2, 1506, 1509, 3, + 2, 2, 2, 1507, 1505, 3, 2, 2, 2, 1507, 1508, 3, 2, 2, 2, 1508, 1511, 3, + 2, 2, 2, 1509, 1507, 3, 2, 2, 2, 1510, 1477, 3, 2, 2, 2, 1510, 1511, 3, + 2, 2, 2, 1511, 1512, 3, 2, 2, 2, 1512, 1513, 7, 27, 2, 2, 1513, 177, 3, + 2, 2, 2, 1514, 1517, 7, 28, 2, 2, 1515, 1518, 5, 192, 97, 2, 1516, 1518, + 7, 100, 2, 2, 1517, 1515, 3, 2, 2, 2, 1517, 1516, 3, 2, 2, 2, 1518, 179, + 3, 2, 2, 2, 1519, 1524, 5, 130, 66, 2, 1520, 1522, 7, 127, 2, 2, 1521, + 1520, 3, 2, 2, 2, 1521, 1522, 3, 2, 2, 2, 1522, 1523, 3, 2, 2, 2, 1523, + 1525, 5, 166, 84, 2, 1524, 1521, 3, 2, 2, 2, 1525, 1526, 3, 2, 2, 2, 1526, + 1524, 3, 2, 2, 2, 1526, 1527, 3, 2, 2, 2, 1527, 181, 3, 2, 2, 2, 1528, + 1529, 5, 188, 95, 2, 1529, 183, 3, 2, 2, 2, 1530, 1531, 9, 5, 2, 2, 1531, + 185, 3, 2, 2, 2, 1532, 1533, 9, 6, 2, 2, 1533, 187, 3, 2, 2, 2, 1534, 1537, + 5, 192, 97, 2, 1535, 1537, 5, 190, 96, 2, 1536, 1534, 3, 2, 2, 2, 1536, + 1535, 3, 2, 2, 2, 1537, 189, 3, 2, 2, 2, 1538, 1539, 9, 7, 2, 2, 1539, + 191, 3, 2, 2, 2, 1540, 1541, 9, 8, 2, 2, 1541, 193, 3, 2, 2, 2, 1542, 1543, + 9, 9, 2, 2, 1543, 195, 3, 2, 2, 2, 1544, 1545, 9, 10, 2, 2, 1545, 197, + 3, 2, 2, 2, 1546, 1547, 9, 11, 2, 2, 1547, 199, 3, 2, 2, 2, 287, 201, 205, + 208, 211, 219, 223, 228, 235, 240, 243, 247, 251, 255, 261, 265, 270, 275, + 279, 282, 284, 288, 292, 297, 301, 306, 310, 319, 324, 328, 332, 336, 339, + 343, 353, 360, 373, 377, 383, 387, 391, 396, 401, 405, 411, 415, 421, 425, + 431, 435, 439, 443, 447, 451, 456, 463, 467, 472, 479, 485, 490, 496, 502, + 507, 511, 516, 519, 522, 525, 532, 539, 542, 548, 551, 557, 561, 565, 569, + 573, 578, 583, 587, 592, 595, 604, 613, 618, 631, 634, 642, 646, 651, 656, + 660, 665, 671, 676, 683, 687, 691, 693, 697, 699, 703, 705, 711, 717, 721, + 724, 727, 731, 737, 741, 744, 747, 753, 756, 759, 763, 769, 772, 775, 779, + 783, 787, 789, 793, 795, 798, 802, 804, 810, 814, 818, 822, 825, 830, 835, + 840, 845, 851, 855, 857, 861, 865, 867, 869, 884, 894, 904, 909, 913, 920, + 925, 930, 934, 938, 942, 945, 947, 952, 956, 960, 964, 968, 972, 975, 977, + 982, 986, 991, 996, 1000, 1009, 1011, 1017, 1021, 1028, 1032, 1036, 1039, + 1051, 1054, 1068, 1072, 1077, 1081, 1084, 1091, 1095, 1099, 1106, 1110, + 1114, 1120, 1124, 1128, 1134, 1138, 1142, 1148, 1152, 1156, 1164, 1172, + 1178, 1182, 1186, 1190, 1194, 1197, 1203, 1208, 1213, 1218, 1223, 1228, + 1231, 1235, 1239, 1245, 1250, 1254, 1257, 1267, 1271, 1275, 1277, 1281, + 1285, 1289, 1293, 1296, 1304, 1308, 1312, 1316, 1320, 1324, 1328, 1331, + 1347, 1352, 1356, 1360, 1363, 1366, 1372, 1376, 1380, 1382, 1386, 1390, + 1394, 1396, 1400, 1404, 1410, 1416, 1421, 1425, 1429, 1434, 1436, 1439, + 1443, 1446, 1449, 1455, 1459, 1463, 1471, 1475, 1479, 1483, 1487, 1491, + 1495, 1499, 1503, 1507, 1510, 1517, 1521, 1526, 1536, +} +var literalNames = []string{ + "", "';'", "','", "'='", "'+='", "'*'", "'('", "')'", "'['", "']'", "':'", + "'|'", "'..'", "'+'", "'-'", "'/'", "'%'", "'^'", "'<>'", "'<'", "'>'", + "'<='", "'>='", "'.'", "'{'", "'}'", "'$'", "'\u27E8'", "'\u3008'", "'\uFE64'", + "'\uFF1C'", "'\u27E9'", "'\u3009'", "'\uFE65'", "'\uFF1E'", "'\u00AD'", + "'\u2010'", "'\u2011'", "'\u2012'", "'\u2013'", "'\u2014'", "'\u2015'", + "'\u2212'", "'\uFE58'", "'\uFE63'", "'\uFF0D'", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", + "'0'", +} +var symbolicNames = []string{ + "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", "UNION", "ALL", "OPTIONAL", "MATCH", + "UNWIND", "AS", "MERGE", "ON", "CREATE", "SET", "DETACH", "DELETE", "REMOVE", + "CALL", "YIELD", "WITH", "RETURN", "DISTINCT", "ORDER", "BY", "L_SKIP", + "LIMIT", "ASCENDING", "ASC", "DESCENDING", "DESC", "WHERE", "OR", "XOR", + "AND", "NOT", "IN", "STARTS", "ENDS", "CONTAINS", "IS", "NULL", "COUNT", + "ANY", "NONE", "SINGLE", "TRUE", "FALSE", "EXISTS", "CASE", "ELSE", "END", + "WHEN", "THEN", "StringLiteral", "EscapedChar", "HexInteger", "DecimalInteger", + "OctalInteger", "HexLetter", "HexDigit", "Digit", "NonZeroDigit", "NonZeroOctDigit", + "OctDigit", "ZeroDigit", "ExponentDecimalReal", "RegularDecimalReal", "CONSTRAINT", + "DO", "FOR", "REQUIRE", "UNIQUE", "MANDATORY", "SCALAR", "OF", "ADD", "DROP", + "FILTER", "EXTRACT", "UnescapedSymbolicName", "IdentifierStart", "IdentifierPart", + "EscapedSymbolicName", "SP", "WHITESPACE", "Comment", +} + +var ruleNames = []string{ + "oC_Cypher", "oC_Statement", "oC_Query", "oC_RegularQuery", "oC_Union", + "oC_SingleQuery", "oC_SinglePartQuery", "oC_MultiPartQuery", "oC_UpdatingClause", + "oC_ReadingClause", "oC_Match", "oC_Unwind", "oC_Merge", "oC_MergeAction", + "oC_Create", "oC_Set", "oC_SetItem", "oC_Delete", "oC_Remove", "oC_RemoveItem", + "oC_InQueryCall", "oC_StandaloneCall", "oC_YieldItems", "oC_YieldItem", + "oC_With", "oC_Return", "oC_ProjectionBody", "oC_ProjectionItems", "oC_ProjectionItem", + "oC_Order", "oC_Skip", "oC_Limit", "oC_SortItem", "oC_Where", "oC_Pattern", + "oC_PatternPart", "oC_AnonymousPatternPart", "oC_PatternElement", "oC_NodePattern", + "oC_PatternElementChain", "oC_RelationshipPattern", "oC_RelationshipDetail", + "oC_Properties", "oC_RelationshipTypes", "oC_NodeLabels", "oC_NodeLabel", + "oC_RangeLiteral", "oC_LabelName", "oC_RelTypeName", "oC_Expression", "oC_OrExpression", + "oC_XorExpression", "oC_AndExpression", "oC_NotExpression", "oC_ComparisonExpression", + "oC_AddOrSubtractExpression", "oC_MultiplyDivideModuloExpression", "oC_PowerOfExpression", + "oC_UnaryAddOrSubtractExpression", "oC_StringListNullOperatorExpression", + "oC_ListOperatorExpression", "oC_StringOperatorExpression", "oC_NullOperatorExpression", + "oC_PropertyOrLabelsExpression", "oC_Atom", "oC_Literal", "oC_BooleanLiteral", + "oC_ListLiteral", "oC_PartialComparisonExpression", "oC_ParenthesizedExpression", + "oC_RelationshipsPattern", "oC_FilterExpression", "oC_IdInColl", "oC_FunctionInvocation", + "oC_FunctionName", "oC_ExplicitProcedureInvocation", "oC_ImplicitProcedureInvocation", + "oC_ProcedureResultField", "oC_ProcedureName", "oC_Namespace", "oC_ListComprehension", + "oC_PatternComprehension", "oC_PropertyLookup", "oC_CaseExpression", "oC_CaseAlternatives", + "oC_Variable", "oC_NumberLiteral", "oC_MapLiteral", "oC_Parameter", "oC_PropertyExpression", + "oC_PropertyKeyName", "oC_IntegerLiteral", "oC_DoubleLiteral", "oC_SchemaName", + "oC_ReservedWord", "oC_SymbolicName", "oC_LeftArrowHead", "oC_RightArrowHead", + "oC_Dash", +} + +type CypherParser struct { + *antlr.BaseParser +} + +// NewCypherParser produces a new parser instance for the optional input antlr.TokenStream. +// +// The *CypherParser instance produced may be reused by calling the SetInputStream method. +// The initial parser configuration is expensive to construct, and the object is not thread-safe; +// however, if used within a Golang sync.Pool, the construction cost amortizes well and the +// objects can be used in a thread-safe manner. +func NewCypherParser(input antlr.TokenStream) *CypherParser { + this := new(CypherParser) + deserializer := antlr.NewATNDeserializer(nil) + deserializedATN := deserializer.DeserializeFromUInt16(parserATN) + decisionToDFA := make([]*antlr.DFA, len(deserializedATN.DecisionToState)) + for index, ds := range deserializedATN.DecisionToState { + decisionToDFA[index] = antlr.NewDFA(ds, index) + } + this.BaseParser = antlr.NewBaseParser(input) + + this.Interpreter = antlr.NewParserATNSimulator(this, deserializedATN, decisionToDFA, antlr.NewPredictionContextCache()) + this.RuleNames = ruleNames + this.LiteralNames = literalNames + this.SymbolicNames = symbolicNames + this.GrammarFileName = "Cypher.g4" + + return this +} + +// CypherParser tokens. +const ( + CypherParserEOF = antlr.TokenEOF + CypherParserT__0 = 1 + CypherParserT__1 = 2 + CypherParserT__2 = 3 + CypherParserT__3 = 4 + CypherParserT__4 = 5 + CypherParserT__5 = 6 + CypherParserT__6 = 7 + CypherParserT__7 = 8 + CypherParserT__8 = 9 + CypherParserT__9 = 10 + CypherParserT__10 = 11 + CypherParserT__11 = 12 + CypherParserT__12 = 13 + CypherParserT__13 = 14 + CypherParserT__14 = 15 + CypherParserT__15 = 16 + CypherParserT__16 = 17 + CypherParserT__17 = 18 + CypherParserT__18 = 19 + CypherParserT__19 = 20 + CypherParserT__20 = 21 + CypherParserT__21 = 22 + CypherParserT__22 = 23 + CypherParserT__23 = 24 + CypherParserT__24 = 25 + CypherParserT__25 = 26 + CypherParserT__26 = 27 + CypherParserT__27 = 28 + CypherParserT__28 = 29 + CypherParserT__29 = 30 + CypherParserT__30 = 31 + CypherParserT__31 = 32 + CypherParserT__32 = 33 + CypherParserT__33 = 34 + CypherParserT__34 = 35 + CypherParserT__35 = 36 + CypherParserT__36 = 37 + CypherParserT__37 = 38 + CypherParserT__38 = 39 + CypherParserT__39 = 40 + CypherParserT__40 = 41 + CypherParserT__41 = 42 + CypherParserT__42 = 43 + CypherParserT__43 = 44 + CypherParserT__44 = 45 + CypherParserUNION = 46 + CypherParserALL = 47 + CypherParserOPTIONAL = 48 + CypherParserMATCH = 49 + CypherParserUNWIND = 50 + CypherParserAS = 51 + CypherParserMERGE = 52 + CypherParserON = 53 + CypherParserCREATE = 54 + CypherParserSET = 55 + CypherParserDETACH = 56 + CypherParserDELETE = 57 + CypherParserREMOVE = 58 + CypherParserCALL = 59 + CypherParserYIELD = 60 + CypherParserWITH = 61 + CypherParserRETURN = 62 + CypherParserDISTINCT = 63 + CypherParserORDER = 64 + CypherParserBY = 65 + CypherParserL_SKIP = 66 + CypherParserLIMIT = 67 + CypherParserASCENDING = 68 + CypherParserASC = 69 + CypherParserDESCENDING = 70 + CypherParserDESC = 71 + CypherParserWHERE = 72 + CypherParserOR = 73 + CypherParserXOR = 74 + CypherParserAND = 75 + CypherParserNOT = 76 + CypherParserIN = 77 + CypherParserSTARTS = 78 + CypherParserENDS = 79 + CypherParserCONTAINS = 80 + CypherParserIS = 81 + CypherParserNULL = 82 + CypherParserCOUNT = 83 + CypherParserANY = 84 + CypherParserNONE = 85 + CypherParserSINGLE = 86 + CypherParserTRUE = 87 + CypherParserFALSE = 88 + CypherParserEXISTS = 89 + CypherParserCASE = 90 + CypherParserELSE = 91 + CypherParserEND = 92 + CypherParserWHEN = 93 + CypherParserTHEN = 94 + CypherParserStringLiteral = 95 + CypherParserEscapedChar = 96 + CypherParserHexInteger = 97 + CypherParserDecimalInteger = 98 + CypherParserOctalInteger = 99 + CypherParserHexLetter = 100 + CypherParserHexDigit = 101 + CypherParserDigit = 102 + CypherParserNonZeroDigit = 103 + CypherParserNonZeroOctDigit = 104 + CypherParserOctDigit = 105 + CypherParserZeroDigit = 106 + CypherParserExponentDecimalReal = 107 + CypherParserRegularDecimalReal = 108 + CypherParserCONSTRAINT = 109 + CypherParserDO = 110 + CypherParserFOR = 111 + CypherParserREQUIRE = 112 + CypherParserUNIQUE = 113 + CypherParserMANDATORY = 114 + CypherParserSCALAR = 115 + CypherParserOF = 116 + CypherParserADD = 117 + CypherParserDROP = 118 + CypherParserFILTER = 119 + CypherParserEXTRACT = 120 + CypherParserUnescapedSymbolicName = 121 + CypherParserIdentifierStart = 122 + CypherParserIdentifierPart = 123 + CypherParserEscapedSymbolicName = 124 + CypherParserSP = 125 + CypherParserWHITESPACE = 126 + CypherParserComment = 127 +) + +// CypherParser rules. +const ( + CypherParserRULE_oC_Cypher = 0 + CypherParserRULE_oC_Statement = 1 + CypherParserRULE_oC_Query = 2 + CypherParserRULE_oC_RegularQuery = 3 + CypherParserRULE_oC_Union = 4 + CypherParserRULE_oC_SingleQuery = 5 + CypherParserRULE_oC_SinglePartQuery = 6 + CypherParserRULE_oC_MultiPartQuery = 7 + CypherParserRULE_oC_UpdatingClause = 8 + CypherParserRULE_oC_ReadingClause = 9 + CypherParserRULE_oC_Match = 10 + CypherParserRULE_oC_Unwind = 11 + CypherParserRULE_oC_Merge = 12 + CypherParserRULE_oC_MergeAction = 13 + CypherParserRULE_oC_Create = 14 + CypherParserRULE_oC_Set = 15 + CypherParserRULE_oC_SetItem = 16 + CypherParserRULE_oC_Delete = 17 + CypherParserRULE_oC_Remove = 18 + CypherParserRULE_oC_RemoveItem = 19 + CypherParserRULE_oC_InQueryCall = 20 + CypherParserRULE_oC_StandaloneCall = 21 + CypherParserRULE_oC_YieldItems = 22 + CypherParserRULE_oC_YieldItem = 23 + CypherParserRULE_oC_With = 24 + CypherParserRULE_oC_Return = 25 + CypherParserRULE_oC_ProjectionBody = 26 + CypherParserRULE_oC_ProjectionItems = 27 + CypherParserRULE_oC_ProjectionItem = 28 + CypherParserRULE_oC_Order = 29 + CypherParserRULE_oC_Skip = 30 + CypherParserRULE_oC_Limit = 31 + CypherParserRULE_oC_SortItem = 32 + CypherParserRULE_oC_Where = 33 + CypherParserRULE_oC_Pattern = 34 + CypherParserRULE_oC_PatternPart = 35 + CypherParserRULE_oC_AnonymousPatternPart = 36 + CypherParserRULE_oC_PatternElement = 37 + CypherParserRULE_oC_NodePattern = 38 + CypherParserRULE_oC_PatternElementChain = 39 + CypherParserRULE_oC_RelationshipPattern = 40 + CypherParserRULE_oC_RelationshipDetail = 41 + CypherParserRULE_oC_Properties = 42 + CypherParserRULE_oC_RelationshipTypes = 43 + CypherParserRULE_oC_NodeLabels = 44 + CypherParserRULE_oC_NodeLabel = 45 + CypherParserRULE_oC_RangeLiteral = 46 + CypherParserRULE_oC_LabelName = 47 + CypherParserRULE_oC_RelTypeName = 48 + CypherParserRULE_oC_Expression = 49 + CypherParserRULE_oC_OrExpression = 50 + CypherParserRULE_oC_XorExpression = 51 + CypherParserRULE_oC_AndExpression = 52 + CypherParserRULE_oC_NotExpression = 53 + CypherParserRULE_oC_ComparisonExpression = 54 + CypherParserRULE_oC_AddOrSubtractExpression = 55 + CypherParserRULE_oC_MultiplyDivideModuloExpression = 56 + CypherParserRULE_oC_PowerOfExpression = 57 + CypherParserRULE_oC_UnaryAddOrSubtractExpression = 58 + CypherParserRULE_oC_StringListNullOperatorExpression = 59 + CypherParserRULE_oC_ListOperatorExpression = 60 + CypherParserRULE_oC_StringOperatorExpression = 61 + CypherParserRULE_oC_NullOperatorExpression = 62 + CypherParserRULE_oC_PropertyOrLabelsExpression = 63 + CypherParserRULE_oC_Atom = 64 + CypherParserRULE_oC_Literal = 65 + CypherParserRULE_oC_BooleanLiteral = 66 + CypherParserRULE_oC_ListLiteral = 67 + CypherParserRULE_oC_PartialComparisonExpression = 68 + CypherParserRULE_oC_ParenthesizedExpression = 69 + CypherParserRULE_oC_RelationshipsPattern = 70 + CypherParserRULE_oC_FilterExpression = 71 + CypherParserRULE_oC_IdInColl = 72 + CypherParserRULE_oC_FunctionInvocation = 73 + CypherParserRULE_oC_FunctionName = 74 + CypherParserRULE_oC_ExplicitProcedureInvocation = 75 + CypherParserRULE_oC_ImplicitProcedureInvocation = 76 + CypherParserRULE_oC_ProcedureResultField = 77 + CypherParserRULE_oC_ProcedureName = 78 + CypherParserRULE_oC_Namespace = 79 + CypherParserRULE_oC_ListComprehension = 80 + CypherParserRULE_oC_PatternComprehension = 81 + CypherParserRULE_oC_PropertyLookup = 82 + CypherParserRULE_oC_CaseExpression = 83 + CypherParserRULE_oC_CaseAlternatives = 84 + CypherParserRULE_oC_Variable = 85 + CypherParserRULE_oC_NumberLiteral = 86 + CypherParserRULE_oC_MapLiteral = 87 + CypherParserRULE_oC_Parameter = 88 + CypherParserRULE_oC_PropertyExpression = 89 + CypherParserRULE_oC_PropertyKeyName = 90 + CypherParserRULE_oC_IntegerLiteral = 91 + CypherParserRULE_oC_DoubleLiteral = 92 + CypherParserRULE_oC_SchemaName = 93 + CypherParserRULE_oC_ReservedWord = 94 + CypherParserRULE_oC_SymbolicName = 95 + CypherParserRULE_oC_LeftArrowHead = 96 + CypherParserRULE_oC_RightArrowHead = 97 + CypherParserRULE_oC_Dash = 98 +) + +// IOC_CypherContext is an interface to support dynamic dispatch. +type IOC_CypherContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // IsOC_CypherContext differentiates from other interfaces. + IsOC_CypherContext() +} + +type OC_CypherContext struct { + *antlr.BaseParserRuleContext + parser antlr.Parser +} + +func NewEmptyOC_CypherContext() *OC_CypherContext { + var p = new(OC_CypherContext) + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + p.RuleIndex = CypherParserRULE_oC_Cypher + return p +} + +func (*OC_CypherContext) IsOC_CypherContext() {} + +func NewOC_CypherContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *OC_CypherContext { + var p = new(OC_CypherContext) + + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + + p.parser = parser + p.RuleIndex = CypherParserRULE_oC_Cypher + + return p +} + +func (s *OC_CypherContext) GetParser() antlr.Parser { return s.parser } + +func (s *OC_CypherContext) OC_Statement() IOC_StatementContext { + var t = s.GetTypedRuleContext(reflect.TypeOf((*IOC_StatementContext)(nil)).Elem(), 0) + + if t == nil { + return nil + } + + return t.(IOC_StatementContext) +} + +func (s *OC_CypherContext) EOF() antlr.TerminalNode { + return s.GetToken(CypherParserEOF, 0) +} + +func (s *OC_CypherContext) AllSP() []antlr.TerminalNode { + return s.GetTokens(CypherParserSP) +} + +func (s *OC_CypherContext) SP(i int) antlr.TerminalNode { + return s.GetToken(CypherParserSP, i) +} + +func (s *OC_CypherContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *OC_CypherContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *OC_CypherContext) EnterRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CypherListener); ok { + listenerT.EnterOC_Cypher(s) + } +} + +func (s *OC_CypherContext) ExitRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CypherListener); ok { + listenerT.ExitOC_Cypher(s) + } +} + +func (p *CypherParser) OC_Cypher() (localctx IOC_CypherContext) { + localctx = NewOC_CypherContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 0, CypherParserRULE_oC_Cypher) + var _la int + + defer func() { + p.ExitRule() + }() + + defer func() { + if err := recover(); err != nil { + if v, ok := err.(antlr.RecognitionException); ok { + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + } else { + panic(err) + } + } + }() + + p.EnterOuterAlt(localctx, 1) + p.SetState(199) + p.GetErrorHandler().Sync(p) + _la = p.GetTokenStream().LA(1) + + if _la == CypherParserSP { + { + p.SetState(198) + p.Match(CypherParserSP) + } + + } + { + p.SetState(201) + p.OC_Statement() + } + p.SetState(206) + p.GetErrorHandler().Sync(p) + + if p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 2, p.GetParserRuleContext()) == 1 { + p.SetState(203) + p.GetErrorHandler().Sync(p) + _la = p.GetTokenStream().LA(1) + + if _la == CypherParserSP { + { + p.SetState(202) + p.Match(CypherParserSP) + } + + } + { + p.SetState(205) + p.Match(CypherParserT__0) + } + + } + p.SetState(209) + p.GetErrorHandler().Sync(p) + _la = p.GetTokenStream().LA(1) + + if _la == CypherParserSP { + { + p.SetState(208) + p.Match(CypherParserSP) + } + + } + { + p.SetState(211) + p.Match(CypherParserEOF) + } + + return localctx +} + +// IOC_StatementContext is an interface to support dynamic dispatch. +type IOC_StatementContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // IsOC_StatementContext differentiates from other interfaces. + IsOC_StatementContext() +} + +type OC_StatementContext struct { + *antlr.BaseParserRuleContext + parser antlr.Parser +} + +func NewEmptyOC_StatementContext() *OC_StatementContext { + var p = new(OC_StatementContext) + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + p.RuleIndex = CypherParserRULE_oC_Statement + return p +} + +func (*OC_StatementContext) IsOC_StatementContext() {} + +func NewOC_StatementContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *OC_StatementContext { + var p = new(OC_StatementContext) + + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + + p.parser = parser + p.RuleIndex = CypherParserRULE_oC_Statement + + return p +} + +func (s *OC_StatementContext) GetParser() antlr.Parser { return s.parser } + +func (s *OC_StatementContext) OC_Query() IOC_QueryContext { + var t = s.GetTypedRuleContext(reflect.TypeOf((*IOC_QueryContext)(nil)).Elem(), 0) + + if t == nil { + return nil + } + + return t.(IOC_QueryContext) +} + +func (s *OC_StatementContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *OC_StatementContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *OC_StatementContext) EnterRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CypherListener); ok { + listenerT.EnterOC_Statement(s) + } +} + +func (s *OC_StatementContext) ExitRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CypherListener); ok { + listenerT.ExitOC_Statement(s) + } +} + +func (p *CypherParser) OC_Statement() (localctx IOC_StatementContext) { + localctx = NewOC_StatementContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 2, CypherParserRULE_oC_Statement) + + defer func() { + p.ExitRule() + }() + + defer func() { + if err := recover(); err != nil { + if v, ok := err.(antlr.RecognitionException); ok { + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + } else { + panic(err) + } + } + }() + + p.EnterOuterAlt(localctx, 1) + { + p.SetState(213) + p.OC_Query() + } + + return localctx +} + +// IOC_QueryContext is an interface to support dynamic dispatch. +type IOC_QueryContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // IsOC_QueryContext differentiates from other interfaces. + IsOC_QueryContext() +} + +type OC_QueryContext struct { + *antlr.BaseParserRuleContext + parser antlr.Parser +} + +func NewEmptyOC_QueryContext() *OC_QueryContext { + var p = new(OC_QueryContext) + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + p.RuleIndex = CypherParserRULE_oC_Query + return p +} + +func (*OC_QueryContext) IsOC_QueryContext() {} + +func NewOC_QueryContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *OC_QueryContext { + var p = new(OC_QueryContext) + + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + + p.parser = parser + p.RuleIndex = CypherParserRULE_oC_Query + + return p +} + +func (s *OC_QueryContext) GetParser() antlr.Parser { return s.parser } + +func (s *OC_QueryContext) OC_RegularQuery() IOC_RegularQueryContext { + var t = s.GetTypedRuleContext(reflect.TypeOf((*IOC_RegularQueryContext)(nil)).Elem(), 0) + + if t == nil { + return nil + } + + return t.(IOC_RegularQueryContext) +} + +func (s *OC_QueryContext) OC_StandaloneCall() IOC_StandaloneCallContext { + var t = s.GetTypedRuleContext(reflect.TypeOf((*IOC_StandaloneCallContext)(nil)).Elem(), 0) + + if t == nil { + return nil + } + + return t.(IOC_StandaloneCallContext) +} + +func (s *OC_QueryContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *OC_QueryContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *OC_QueryContext) EnterRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CypherListener); ok { + listenerT.EnterOC_Query(s) + } +} + +func (s *OC_QueryContext) ExitRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CypherListener); ok { + listenerT.ExitOC_Query(s) + } +} + +func (p *CypherParser) OC_Query() (localctx IOC_QueryContext) { + localctx = NewOC_QueryContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 4, CypherParserRULE_oC_Query) + + defer func() { + p.ExitRule() + }() + + defer func() { + if err := recover(); err != nil { + if v, ok := err.(antlr.RecognitionException); ok { + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + } else { + panic(err) + } + } + }() + + p.SetState(217) + p.GetErrorHandler().Sync(p) + switch p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 4, p.GetParserRuleContext()) { + case 1: + p.EnterOuterAlt(localctx, 1) + { + p.SetState(215) + p.OC_RegularQuery() + } + + case 2: + p.EnterOuterAlt(localctx, 2) + { + p.SetState(216) + p.OC_StandaloneCall() + } + + } + + return localctx +} + +// IOC_RegularQueryContext is an interface to support dynamic dispatch. +type IOC_RegularQueryContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // IsOC_RegularQueryContext differentiates from other interfaces. + IsOC_RegularQueryContext() +} + +type OC_RegularQueryContext struct { + *antlr.BaseParserRuleContext + parser antlr.Parser +} + +func NewEmptyOC_RegularQueryContext() *OC_RegularQueryContext { + var p = new(OC_RegularQueryContext) + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + p.RuleIndex = CypherParserRULE_oC_RegularQuery + return p +} + +func (*OC_RegularQueryContext) IsOC_RegularQueryContext() {} + +func NewOC_RegularQueryContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *OC_RegularQueryContext { + var p = new(OC_RegularQueryContext) + + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + + p.parser = parser + p.RuleIndex = CypherParserRULE_oC_RegularQuery + + return p +} + +func (s *OC_RegularQueryContext) GetParser() antlr.Parser { return s.parser } + +func (s *OC_RegularQueryContext) OC_SingleQuery() IOC_SingleQueryContext { + var t = s.GetTypedRuleContext(reflect.TypeOf((*IOC_SingleQueryContext)(nil)).Elem(), 0) + + if t == nil { + return nil + } + + return t.(IOC_SingleQueryContext) +} + +func (s *OC_RegularQueryContext) AllOC_Union() []IOC_UnionContext { + var ts = s.GetTypedRuleContexts(reflect.TypeOf((*IOC_UnionContext)(nil)).Elem()) + var tst = make([]IOC_UnionContext, len(ts)) + + for i, t := range ts { + if t != nil { + tst[i] = t.(IOC_UnionContext) + } + } + + return tst +} + +func (s *OC_RegularQueryContext) OC_Union(i int) IOC_UnionContext { + var t = s.GetTypedRuleContext(reflect.TypeOf((*IOC_UnionContext)(nil)).Elem(), i) + + if t == nil { + return nil + } + + return t.(IOC_UnionContext) +} + +func (s *OC_RegularQueryContext) AllSP() []antlr.TerminalNode { + return s.GetTokens(CypherParserSP) +} + +func (s *OC_RegularQueryContext) SP(i int) antlr.TerminalNode { + return s.GetToken(CypherParserSP, i) +} + +func (s *OC_RegularQueryContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *OC_RegularQueryContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *OC_RegularQueryContext) EnterRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CypherListener); ok { + listenerT.EnterOC_RegularQuery(s) + } +} + +func (s *OC_RegularQueryContext) ExitRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CypherListener); ok { + listenerT.ExitOC_RegularQuery(s) + } +} + +func (p *CypherParser) OC_RegularQuery() (localctx IOC_RegularQueryContext) { + localctx = NewOC_RegularQueryContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 6, CypherParserRULE_oC_RegularQuery) + var _la int + + defer func() { + p.ExitRule() + }() + + defer func() { + if err := recover(); err != nil { + if v, ok := err.(antlr.RecognitionException); ok { + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + } else { + panic(err) + } + } + }() + + var _alt int + + p.EnterOuterAlt(localctx, 1) + { + p.SetState(219) + p.OC_SingleQuery() + } + p.SetState(226) + p.GetErrorHandler().Sync(p) + _alt = p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 6, p.GetParserRuleContext()) + + for _alt != 2 && _alt != antlr.ATNInvalidAltNumber { + if _alt == 1 { + p.SetState(221) + p.GetErrorHandler().Sync(p) + _la = p.GetTokenStream().LA(1) + + if _la == CypherParserSP { + { + p.SetState(220) + p.Match(CypherParserSP) + } + + } + { + p.SetState(223) + p.OC_Union() + } + + } + p.SetState(228) + p.GetErrorHandler().Sync(p) + _alt = p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 6, p.GetParserRuleContext()) + } + + return localctx +} + +// IOC_UnionContext is an interface to support dynamic dispatch. +type IOC_UnionContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // IsOC_UnionContext differentiates from other interfaces. + IsOC_UnionContext() +} + +type OC_UnionContext struct { + *antlr.BaseParserRuleContext + parser antlr.Parser +} + +func NewEmptyOC_UnionContext() *OC_UnionContext { + var p = new(OC_UnionContext) + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + p.RuleIndex = CypherParserRULE_oC_Union + return p +} + +func (*OC_UnionContext) IsOC_UnionContext() {} + +func NewOC_UnionContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *OC_UnionContext { + var p = new(OC_UnionContext) + + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + + p.parser = parser + p.RuleIndex = CypherParserRULE_oC_Union + + return p +} + +func (s *OC_UnionContext) GetParser() antlr.Parser { return s.parser } + +func (s *OC_UnionContext) UNION() antlr.TerminalNode { + return s.GetToken(CypherParserUNION, 0) +} + +func (s *OC_UnionContext) AllSP() []antlr.TerminalNode { + return s.GetTokens(CypherParserSP) +} + +func (s *OC_UnionContext) SP(i int) antlr.TerminalNode { + return s.GetToken(CypherParserSP, i) +} + +func (s *OC_UnionContext) ALL() antlr.TerminalNode { + return s.GetToken(CypherParserALL, 0) +} + +func (s *OC_UnionContext) OC_SingleQuery() IOC_SingleQueryContext { + var t = s.GetTypedRuleContext(reflect.TypeOf((*IOC_SingleQueryContext)(nil)).Elem(), 0) + + if t == nil { + return nil + } + + return t.(IOC_SingleQueryContext) +} + +func (s *OC_UnionContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *OC_UnionContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *OC_UnionContext) EnterRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CypherListener); ok { + listenerT.EnterOC_Union(s) + } +} + +func (s *OC_UnionContext) ExitRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CypherListener); ok { + listenerT.ExitOC_Union(s) + } +} + +func (p *CypherParser) OC_Union() (localctx IOC_UnionContext) { + localctx = NewOC_UnionContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 8, CypherParserRULE_oC_Union) + var _la int + + defer func() { + p.ExitRule() + }() + + defer func() { + if err := recover(); err != nil { + if v, ok := err.(antlr.RecognitionException); ok { + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + } else { + panic(err) + } + } + }() + + p.SetState(241) + p.GetErrorHandler().Sync(p) + switch p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 9, p.GetParserRuleContext()) { + case 1: + p.EnterOuterAlt(localctx, 1) + { + p.SetState(229) + p.Match(CypherParserUNION) + } + { + p.SetState(230) + p.Match(CypherParserSP) + } + { + p.SetState(231) + p.Match(CypherParserALL) + } + p.SetState(233) + p.GetErrorHandler().Sync(p) + _la = p.GetTokenStream().LA(1) + + if _la == CypherParserSP { + { + p.SetState(232) + p.Match(CypherParserSP) + } + + } + { + p.SetState(235) + p.OC_SingleQuery() + } + + case 2: + p.EnterOuterAlt(localctx, 2) + { + p.SetState(236) + p.Match(CypherParserUNION) + } + p.SetState(238) + p.GetErrorHandler().Sync(p) + _la = p.GetTokenStream().LA(1) + + if _la == CypherParserSP { + { + p.SetState(237) + p.Match(CypherParserSP) + } + + } + { + p.SetState(240) + p.OC_SingleQuery() + } + + } + + return localctx +} + +// IOC_SingleQueryContext is an interface to support dynamic dispatch. +type IOC_SingleQueryContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // IsOC_SingleQueryContext differentiates from other interfaces. + IsOC_SingleQueryContext() +} + +type OC_SingleQueryContext struct { + *antlr.BaseParserRuleContext + parser antlr.Parser +} + +func NewEmptyOC_SingleQueryContext() *OC_SingleQueryContext { + var p = new(OC_SingleQueryContext) + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + p.RuleIndex = CypherParserRULE_oC_SingleQuery + return p +} + +func (*OC_SingleQueryContext) IsOC_SingleQueryContext() {} + +func NewOC_SingleQueryContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *OC_SingleQueryContext { + var p = new(OC_SingleQueryContext) + + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + + p.parser = parser + p.RuleIndex = CypherParserRULE_oC_SingleQuery + + return p +} + +func (s *OC_SingleQueryContext) GetParser() antlr.Parser { return s.parser } + +func (s *OC_SingleQueryContext) OC_SinglePartQuery() IOC_SinglePartQueryContext { + var t = s.GetTypedRuleContext(reflect.TypeOf((*IOC_SinglePartQueryContext)(nil)).Elem(), 0) + + if t == nil { + return nil + } + + return t.(IOC_SinglePartQueryContext) +} + +func (s *OC_SingleQueryContext) OC_MultiPartQuery() IOC_MultiPartQueryContext { + var t = s.GetTypedRuleContext(reflect.TypeOf((*IOC_MultiPartQueryContext)(nil)).Elem(), 0) + + if t == nil { + return nil + } + + return t.(IOC_MultiPartQueryContext) +} + +func (s *OC_SingleQueryContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *OC_SingleQueryContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *OC_SingleQueryContext) EnterRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CypherListener); ok { + listenerT.EnterOC_SingleQuery(s) + } +} + +func (s *OC_SingleQueryContext) ExitRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CypherListener); ok { + listenerT.ExitOC_SingleQuery(s) + } +} + +func (p *CypherParser) OC_SingleQuery() (localctx IOC_SingleQueryContext) { + localctx = NewOC_SingleQueryContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 10, CypherParserRULE_oC_SingleQuery) + + defer func() { + p.ExitRule() + }() + + defer func() { + if err := recover(); err != nil { + if v, ok := err.(antlr.RecognitionException); ok { + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + } else { + panic(err) + } + } + }() + + p.SetState(245) + p.GetErrorHandler().Sync(p) + switch p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 10, p.GetParserRuleContext()) { + case 1: + p.EnterOuterAlt(localctx, 1) + { + p.SetState(243) + p.OC_SinglePartQuery() + } + + case 2: + p.EnterOuterAlt(localctx, 2) + { + p.SetState(244) + p.OC_MultiPartQuery() + } + + } + + return localctx +} + +// IOC_SinglePartQueryContext is an interface to support dynamic dispatch. +type IOC_SinglePartQueryContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // IsOC_SinglePartQueryContext differentiates from other interfaces. + IsOC_SinglePartQueryContext() +} + +type OC_SinglePartQueryContext struct { + *antlr.BaseParserRuleContext + parser antlr.Parser +} + +func NewEmptyOC_SinglePartQueryContext() *OC_SinglePartQueryContext { + var p = new(OC_SinglePartQueryContext) + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + p.RuleIndex = CypherParserRULE_oC_SinglePartQuery + return p +} + +func (*OC_SinglePartQueryContext) IsOC_SinglePartQueryContext() {} + +func NewOC_SinglePartQueryContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *OC_SinglePartQueryContext { + var p = new(OC_SinglePartQueryContext) + + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + + p.parser = parser + p.RuleIndex = CypherParserRULE_oC_SinglePartQuery + + return p +} + +func (s *OC_SinglePartQueryContext) GetParser() antlr.Parser { return s.parser } + +func (s *OC_SinglePartQueryContext) OC_Return() IOC_ReturnContext { + var t = s.GetTypedRuleContext(reflect.TypeOf((*IOC_ReturnContext)(nil)).Elem(), 0) + + if t == nil { + return nil + } + + return t.(IOC_ReturnContext) +} + +func (s *OC_SinglePartQueryContext) AllOC_ReadingClause() []IOC_ReadingClauseContext { + var ts = s.GetTypedRuleContexts(reflect.TypeOf((*IOC_ReadingClauseContext)(nil)).Elem()) + var tst = make([]IOC_ReadingClauseContext, len(ts)) + + for i, t := range ts { + if t != nil { + tst[i] = t.(IOC_ReadingClauseContext) + } + } + + return tst +} + +func (s *OC_SinglePartQueryContext) OC_ReadingClause(i int) IOC_ReadingClauseContext { + var t = s.GetTypedRuleContext(reflect.TypeOf((*IOC_ReadingClauseContext)(nil)).Elem(), i) + + if t == nil { + return nil + } + + return t.(IOC_ReadingClauseContext) +} + +func (s *OC_SinglePartQueryContext) AllSP() []antlr.TerminalNode { + return s.GetTokens(CypherParserSP) +} + +func (s *OC_SinglePartQueryContext) SP(i int) antlr.TerminalNode { + return s.GetToken(CypherParserSP, i) +} + +func (s *OC_SinglePartQueryContext) AllOC_UpdatingClause() []IOC_UpdatingClauseContext { + var ts = s.GetTypedRuleContexts(reflect.TypeOf((*IOC_UpdatingClauseContext)(nil)).Elem()) + var tst = make([]IOC_UpdatingClauseContext, len(ts)) + + for i, t := range ts { + if t != nil { + tst[i] = t.(IOC_UpdatingClauseContext) + } + } + + return tst +} + +func (s *OC_SinglePartQueryContext) OC_UpdatingClause(i int) IOC_UpdatingClauseContext { + var t = s.GetTypedRuleContext(reflect.TypeOf((*IOC_UpdatingClauseContext)(nil)).Elem(), i) + + if t == nil { + return nil + } + + return t.(IOC_UpdatingClauseContext) +} + +func (s *OC_SinglePartQueryContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *OC_SinglePartQueryContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *OC_SinglePartQueryContext) EnterRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CypherListener); ok { + listenerT.EnterOC_SinglePartQuery(s) + } +} + +func (s *OC_SinglePartQueryContext) ExitRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CypherListener); ok { + listenerT.ExitOC_SinglePartQuery(s) + } +} + +func (p *CypherParser) OC_SinglePartQuery() (localctx IOC_SinglePartQueryContext) { + localctx = NewOC_SinglePartQueryContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 12, CypherParserRULE_oC_SinglePartQuery) + var _la int + + defer func() { + p.ExitRule() + }() + + defer func() { + if err := recover(); err != nil { + if v, ok := err.(antlr.RecognitionException); ok { + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + } else { + panic(err) + } + } + }() + + var _alt int + + p.SetState(282) + p.GetErrorHandler().Sync(p) + switch p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 19, p.GetParserRuleContext()) { + case 1: + p.EnterOuterAlt(localctx, 1) + p.SetState(253) + p.GetErrorHandler().Sync(p) + _la = p.GetTokenStream().LA(1) + + for ((_la-48)&-(0x1f+1)) == 0 && ((1< 1 { + panic("Multiple match patterns are not implemented") + } + pattern, err := match.Pattern.Parts[0].getPattern(ctx) + if err != nil { + return ResultSet{}, err + } + + newContext := ctx.SubContext() + + symbols, err := BuildPatternSymbols(ctx, pattern) + if err != nil { + return ResultSet{}, err + } + + resultAccumulator := matchResultAccumulator{ + where: match.Where, + evalCtx: newContext, + } + + err = pattern.Run(ctx.graph, symbols, &resultAccumulator) + if err != nil { + return ResultSet{}, err + } + + return resultAccumulator.result, nil +} + +// BuildPatternSymbols copies all the symbols referenced in the +// pattern from the context, and puts them in a map +func BuildPatternSymbols(ctx *EvalContext, pattern graph.Pattern) (map[string]*graph.PatternSymbol, error) { + symbols := make(map[string]*graph.PatternSymbol) + for symbol := range pattern.GetSymbolNames() { + // If a symbol is in the context, then get its value. Otherwise, it is a local symbol. Add to context + value, err := ctx.GetVar(symbol) + if err != nil { + continue + } + ps := &graph.PatternSymbol{} + // A variable with the same name exists + // Must be a Node, or []Edge + switch val := value.Value.(type) { + case graph.Node: + ps.AddNode(val) + case []graph.Edge: + ps.AddPath(val) + default: + return nil, ErrInvalidValueReferenceInPattern{Symbol: symbol} + } + symbols[symbol] = ps + } + return symbols, nil +} + +func (part PatternPart) getPattern(ctx *EvalContext) (graph.Pattern, error) { + pattern := make([]graph.PatternItem, 0, len(part.Path)*2+1) + np, err := part.Start.getPattern(ctx) + if err != nil { + return nil, err + } + pattern = append(pattern, np) + for _, pathItem := range part.Path { + pi, err := pathItem.Rel.getPattern(ctx) + if err != nil { + return nil, err + } + pattern = append(pattern, pi) + + pi, err = pathItem.Node.getPattern(ctx) + if err != nil { + return nil, err + } + pattern = append(pattern, pi) + } + return pattern, nil +} + +func (np NodePattern) getPattern(ctx *EvalContext) (graph.PatternItem, error) { + ret := graph.PatternItem{} + if np.Var != nil { + ret.Name = string(*np.Var) + } + ret.Labels = np.Labels.getPattern() + var err error + props, err := np.Properties.getPattern(ctx) + if err != nil { + return graph.PatternItem{}, err + } + if len(props) > 0 { + ret.Properties = make(map[string]interface{}) + for k, v := range props { + ret.Properties[k] = v.Value + } + } + return ret, nil +} + +func (rp RelationshipPattern) getPattern(ctx *EvalContext) (graph.PatternItem, error) { + ret := graph.PatternItem{} + if rp.Var != nil { + ret.Name = string(*rp.Var) + } + ret.Labels = rp.RelTypes.getPattern() + if rp.Range != nil { + from, to, err := rp.Range.Evaluate(ctx) + if err != nil { + return graph.PatternItem{}, err + } + if from != nil { + ret.Min = *from + } else { + ret.Min = -1 + } + if to != nil { + ret.Max = *to + } else { + ret.Max = -1 + } + } else { + ret.Min, ret.Max = 1, 1 + } + if rp.Backwards { + ret.Backwards = true + } + var err error + props, err := rp.Properties.getPattern(ctx) + if err != nil { + return graph.PatternItem{}, err + } + if len(props) > 0 { + ret.Properties = make(map[string]interface{}) + for k, v := range props { + ret.Properties[k] = v.Value + } + } + return ret, nil +} + +func (rt *RelationshipTypes) getPattern() graph.StringSet { + if rt == nil { + return nil + } + if len(rt.Rel) == 0 { + return nil + } + ret := graph.NewStringSet() + for _, r := range rt.Rel { + s := r.String() + if len(s) > 0 { + ret.Add(s) + } + } + if len(ret) == 0 { + return nil + } + return ret +} + +func (nl *NodeLabels) getPattern() graph.StringSet { + if nl == nil { + return nil + } + ret := graph.NewStringSet() + for _, l := range *nl { + s := l.String() + if len(s) > 0 { + ret.Add(s) + } + } + if len(ret) == 0 { + return nil + } + return ret +} + +func (p *Properties) getPattern(ctx *EvalContext) (map[string]Value, error) { + if p == nil { + return nil, nil + } + if p.Param != nil { + value, err := ctx.GetParameter(string(*p.Param)) + if err != nil { + return nil, err + } + m, ok := value.Value.(map[string]Value) + if !ok { + return nil, ErrPropertiesParameterExpected + } + return m, nil + } + if p.Map != nil { + value, err := p.Map.Evaluate(ctx) + if err != nil { + return nil, err + } + m, ok := value.Value.(map[string]Value) + if !ok { + return nil, ErrPropertiesExpected + } + return m, nil + } + + return nil, nil +} diff --git a/patternexpr_test.go b/patternexpr_test.go new file mode 100644 index 0000000..6854987 --- /dev/null +++ b/patternexpr_test.go @@ -0,0 +1,54 @@ +package opencypher + +import ( + "testing" + + "github.com/cloudprivacylabs/opencypher/graph" +) + +func TestPatternExpr(t *testing.T) { + g := graph.NewOCGraph() + n1 := g.NewNode([]string{"root"}, nil) + n2 := g.NewNode([]string{"c1"}, nil) + n3 := g.NewNode([]string{"c2"}, nil) + n4 := g.NewNode([]string{"c3"}, nil) + + g.NewEdge(n1, n2, "n1n2", nil) + g.NewEdge(n1, n3, "n1n3", nil) + g.NewEdge(n3, n4, "n3n4", nil) + + pe, err := ParsePatternExpr(`(this)<-[]-()-[]->(target:c2)`) + if err != nil { + t.Error(err) + return + } + nodes, err := pe.FindRelative(n2) + if err != nil { + t.Error(err) + } + if len(nodes) != 1 { + t.Errorf("Expecting 1, got %d", len(nodes)) + return + } + if nodes[0] != n3 { + t.Errorf("Expecting n3, got %s", nodes[0]) + } + + pe, err = ParsePatternExpr(`(this)<-[]-()-[]->(target)`) + if err != nil { + t.Error(err) + return + } + nodes, err = pe.FindRelative(n2) + if err != nil { + t.Error(err) + } + if len(nodes) != 2 { + t.Errorf("Expecting 2, got %d", len(nodes)) + return + } + if (nodes[0] != n3 && nodes[0] != n2) || (nodes[1] != n3 && nodes[1] != n2) { + t.Errorf("Expecting n2 n3, got %v", nodes) + } + +} diff --git a/relationaleval.go b/relationaleval.go new file mode 100644 index 0000000..826fc69 --- /dev/null +++ b/relationaleval.go @@ -0,0 +1,269 @@ +package opencypher + +import ( + "github.com/neo4j/neo4j-go-driver/neo4j" +) + +func comparePrimitiveValues(v1, v2 interface{}) (int, error) { + if v1 == nil || v2 == nil { + return 0, ErrOperationWithNull + } + switch value1 := v1.(type) { + case bool: + switch value2 := v2.(type) { + case bool: + if value1 == value2 { + return 0, nil + } + if value1 { + return 1, nil + } + return -1, nil + } + case int: + switch value2 := v2.(type) { + case int: + return value1 - value2, nil + case float64: + if float64(value1) == value2 { + return 0, nil + } + if float64(value1) < value2 { + return -1, nil + } + return 1, nil + } + case float64: + switch value2 := v2.(type) { + case int: + if value1 == float64(value2) { + return 0, nil + } + if value1 < float64(value2) { + return -1, nil + } + return 1, nil + case float64: + if value1 == value2 { + return 0, nil + } + if value1 < value2 { + return -1, nil + } + return 1, nil + } + case string: + if str, ok := v2.(string); ok { + if value1 == str { + return 0, nil + } + if value1 < str { + return -1, nil + } + return 1, nil + } + case neo4j.Duration: + if dur, ok := v2.(neo4j.Duration); ok { + if value1.Days() == dur.Days() && value1.Months() == dur.Months() && value1.Seconds() == dur.Seconds() && value1.Nanos() == dur.Nanos() { + return 0, nil + } + if value1.Days() < dur.Days() { + return -1, nil + } + if value1.Months() < dur.Months() { + return -1, nil + } + if value1.Seconds() < dur.Seconds() { + return -1, nil + } + if value1.Nanos() < dur.Nanos() { + return -1, nil + } + return 1, nil + } + case neo4j.Date: + if date, ok := v2.(neo4j.Date); ok { + t1 := value1.Time() + t2 := date.Time() + if t1.Equal(t2) { + return 0, nil + } + if t1.Before(t2) { + return -1, nil + } + return 0, nil + } + case neo4j.LocalTime: + if date, ok := v2.(neo4j.LocalTime); ok { + t1 := value1.Time() + t2 := date.Time() + if t1.Equal(t2) { + return 0, nil + } + if t1.Before(t2) { + return -1, nil + } + return 0, nil + } + case neo4j.LocalDateTime: + if date, ok := v2.(neo4j.LocalDateTime); ok { + t1 := value1.Time() + t2 := date.Time() + if t1.Equal(t2) { + return 0, nil + } + if t1.Before(t2) { + return -1, nil + } + return 0, nil + } + } + return 0, ErrInvalidComparison + +} + +func (expr ComparisonExpression) Evaluate(ctx *EvalContext) (Value, error) { + val, err := expr.First.Evaluate(ctx) + if err != nil { + return Value{}, err + } + + if val.Value == nil { + return Value{}, nil + } + for i := range expr.Second { + second, err := expr.Second[i].Expr.Evaluate(ctx) + if err != nil { + return Value{}, err + } + if second.Value == nil { + return Value{}, nil + } + result, err := comparePrimitiveValues(val.Value, second.Value) + if err != nil { + return Value{}, err + } + switch expr.Second[i].Op { + case "=": + val.Value = result == 0 + case "<>": + val.Value = result != 0 + case "<": + val.Value = result < 0 + case "<=": + val.Value = result <= 0 + case ">": + val.Value = result > 0 + case ">=": + val.Value = result >= 0 + } + val.Constant = val.Constant && second.Constant + } + return val, nil +} + +func (expr NotExpression) Evaluate(ctx *EvalContext) (Value, error) { + val, err := expr.Part.Evaluate(ctx) + if err != nil { + return Value{}, err + } + if val.Value == nil { + return Value{}, nil + } + value, ok := val.Value.(bool) + if !ok { + return Value{}, ErrNotABooleanExpression + } + val.Value = !value + return val, nil +} + +func (expr AndExpression) Evaluate(ctx *EvalContext) (Value, error) { + var ret Value + for i := range expr.Parts { + val, err := expr.Parts[i].Evaluate(ctx) + if err != nil { + return Value{}, err + } + if val.Value == nil { + return Value{}, nil + } + if i == 0 { + ret = val + } else { + bval, ok := ret.Value.(bool) + if !ok { + return Value{}, ErrNotABooleanExpression + } + vval, ok := val.Value.(bool) + if !ok { + return Value{}, ErrNotABooleanExpression + } + ret.Constant = ret.Constant && val.Constant + ret.Value = bval && vval + if !bval || !vval { + break + } + } + } + return ret, nil +} + +func (expr XorExpression) Evaluate(ctx *EvalContext) (Value, error) { + var ret Value + for i := range expr.Parts { + val, err := expr.Parts[i].Evaluate(ctx) + if err != nil { + return Value{}, err + } + if val.Value == nil { + return Value{}, nil + } + if i == 0 { + ret = val + } else { + bval, ok := ret.Value.(bool) + if !ok { + return Value{}, ErrNotABooleanExpression + } + vval, ok := val.Value.(bool) + if !ok { + return Value{}, ErrNotABooleanExpression + } + ret.Constant = ret.Constant && val.Constant + ret.Value = bval != vval + } + } + return ret, nil +} + +func (expr OrExpression) Evaluate(ctx *EvalContext) (Value, error) { + var ret Value + for i := range expr.Parts { + val, err := expr.Parts[i].Evaluate(ctx) + if err != nil { + return Value{}, err + } + if val.Value == nil { + return Value{}, nil + } + if i == 0 { + ret = val + } else { + bval, ok := ret.Value.(bool) + if !ok { + return Value{}, ErrNotABooleanExpression + } + vval, ok := val.Value.(bool) + if !ok { + return Value{}, ErrNotABooleanExpression + } + ret.Constant = ret.Constant && val.Constant + ret.Value = bval || vval + if bval || vval { + break + } + } + } + return ret, nil +} diff --git a/resultset.go b/resultset.go new file mode 100644 index 0000000..a4005ff --- /dev/null +++ b/resultset.go @@ -0,0 +1,131 @@ +package opencypher + +import ( + "bytes" + "errors" + "fmt" + "io" + "reflect" + + "github.com/cloudprivacylabs/opencypher/graph" +) + +var ErrRowsHaveDifferentSizes = errors.New("Rows have different sizes") +var ErrIncompatibleCells = errors.New("Incompatible result set cells") + +// ResultSet is a table of values +type ResultSet struct { + Nodes graph.NodeSet + Edges graph.EdgeSet + + Rows []map[string]Value +} + +func isCompatibleValue(v1, v2 Value) bool { + if v1.Value == nil { + if v2.Value == nil { + return true + } + return false + } + if v2.Value == nil { + return false + } + return reflect.TypeOf(v1.Value) == reflect.TypeOf(v2.Value) +} + +// Check if all row cells are compatible +func isCompatibleRow(row1, row2 map[string]Value) error { + if len(row1) != len(row2) { + return ErrRowsHaveDifferentSizes + } + for k := range row1 { + if !isCompatibleValue(row1[k], row2[k]) { + return ErrIncompatibleCells + } + } + return nil +} + +func (r *ResultSet) find(row map[string]Value) int { + for index, r := range r.Rows { + if len(r) != len(row) { + break + } + found := true + for i := range r { + if !r[i].IsSame(row[i]) { + found = false + break + } + } + if found { + return index + } + } + return -1 +} + +// Append the row to the resultset. +func (r *ResultSet) Append(row map[string]Value) error { + r.Rows = append(r.Rows, row) + for _, v := range row { + switch val := v.Value.(type) { + case graph.Node: + r.Nodes.Add(val.(*graph.OCNode)) + case []graph.Edge: + for _, edge := range val { + r.Edges.Add(edge.(*graph.OCEdge)) + } + case graph.Edge: + r.Edges.Add(val.(*graph.OCEdge)) + } + } + return nil +} + +func (r *ResultSet) AddPath(node graph.Node, edges []graph.Edge) { + if node != nil { + r.Nodes.Add(node.(*graph.OCNode)) + } + for _, e := range edges { + r.Edges.Add(e.(*graph.OCEdge)) + } +} + +func (r *ResultSet) Add(rs ResultSet) { + r.Rows = append(r.Rows, rs.Rows...) + for itr := rs.Nodes.Iterator(); itr.Next(); { + r.Nodes.Add(itr.Node().(*graph.OCNode)) + } + for itr := rs.Edges.Iterator(); itr.Next(); { + r.Edges.Add(itr.Edge().(*graph.OCEdge)) + } +} + +// Union adds the src resultset to this. If all is set, it adds all rows, otherwise, it adds unique rows +func (r *ResultSet) Union(src ResultSet, all bool) error { + for _, sourceRow := range src.Rows { + appnd := all + if !appnd && r.find(sourceRow) != -1 { + appnd = true + } + if appnd { + if err := r.Append(sourceRow); err != nil { + return err + } + } + } + return nil +} + +func (r ResultSet) String() string { + out := bytes.Buffer{} + for _, row := range r.Rows { + for k, v := range row { + io.WriteString(&out, fmt.Sprintf("%s: %s ", k, v)) + } + io.WriteString(&out, "\n") + } + return out.String() +} diff --git a/value.go b/value.go new file mode 100644 index 0000000..d65cb08 --- /dev/null +++ b/value.go @@ -0,0 +1,209 @@ +package opencypher + +import ( + "fmt" + "strings" + + "github.com/neo4j/neo4j-go-driver/neo4j" + + "github.com/cloudprivacylabs/opencypher/graph" +) + +// Value represents a computer value. Possible data types it can contain are: +// +// primitives: +// int +// float64 +// bool +// string +// neo4j.Duration +// neo4j.Date +// neo4j.LocalDateTime +// neo4j.LocalTime +// +// composites: +// []Value +// map[string]Value +// graph.StringSet +// Node +// []Edge +// ResultSet +type Value struct { + Value interface{} + Constant bool +} + +// IsPrimitive returns true if the value is int, float64, bool, +// string, duration, date, datetime, localDateTime, or localTime +func (v Value) IsPrimitive() bool { + switch v.Value.(type) { + case int, float64, bool, string, neo4j.Duration, neo4j.Date, neo4j.LocalDateTime, neo4j.LocalTime: + return true + } + return false +} + +// AsBool returns the bool value, or if it is not bool, false,false +func (v Value) AsBool() (bool, bool) { + if b, ok := v.Value.(bool); ok { + return b, true + } + return false, false +} + +func ValueOf(in interface{}) Value { + switch v := in.(type) { + case Value: + return v + case int8: + return Value{Value: int(v)} + case int16: + return Value{Value: int(v)} + case int32: + return Value{Value: int(v)} + case int64: + return Value{Value: int(v)} + case int: + return Value{Value: v} + case uint8: + return Value{Value: int(v)} + case uint16: + return Value{Value: int(v)} + case uint32: + return Value{Value: int(v)} + case string: + return Value{Value: v} + case bool: + return Value{Value: v} + case float64: + return Value{Value: v} + case float32: + return Value{Value: float64(v)} + case neo4j.Duration: + return Value{Value: v} + case neo4j.Date: + return Value{Value: v} + case neo4j.LocalDateTime: + return Value{Value: v} + case neo4j.LocalTime: + return Value{Value: v} + case graph.Node: + return Value{Value: v} + case []graph.Edge: + return Value{Value: v} + case []Value: + return Value{Value: v} + case map[string]Value: + return Value{Value: v} + case graph.StringSet: + return Value{Value: v} + } + panic(fmt.Sprintf("Invalid value: %v %T", in, in)) +} + +// IsSame compares two values and decides if the two are the same +func (v Value) IsSame(v2 Value) bool { + if v.IsPrimitive() { + if v2.IsPrimitive() { + eq, err := comparePrimitiveValues(v.Value, v2.Value) + return err != nil && eq == 0 + } + return false + } + + switch val1 := v.Value.(type) { + case []Value: + val2, ok := v2.Value.([]Value) + if !ok { + return false + } + if len(val1) != len(val2) { + return false + } + for i := range val1 { + if !val1[i].IsSame(val2[i]) { + return false + } + } + return true + + case map[string]Value: + val2, ok := v2.Value.(map[string]Value) + if !ok { + return false + } + if len(val1) != len(val2) { + return false + } + for k, v := range val1 { + v2, ok := val2[k] + if !ok { + return false + } + if !v.IsSame(v2) { + return false + } + } + return true + + case graph.StringSet: + val2, ok := v2.Value.(graph.StringSet) + if !ok { + return false + } + if len(val1) != len(val2) { + return false + } + for k := range val1 { + if !val2.Has(k) { + return false + } + } + return true + + case graph.Node: + val2, ok := v2.Value.(graph.Node) + if !ok { + return false + } + return val1 == val2 + + case []graph.Edge: + val2, ok := v2.Value.([]graph.Edge) + if !ok { + return false + } + if len(val1) != len(val2) { + return false + } + for i, x := range val1 { + if x != val2[i] { + return false + } + } + return true + } + return false +} + +func (v Value) Evaluate(ctx *EvalContext) (Value, error) { return v, nil } + +func (v Value) String() string { + if v.Value == nil { + return "null" + } + if v.IsPrimitive() { + return fmt.Sprint(v.Value) + } + switch val := v.Value.(type) { + case []Value: + return fmt.Sprint(val) + case map[string]Value: + result := make([]string, 0) + for k, v := range val { + result = append(result, fmt.Sprintf("%s: %s", k, v)) + } + return fmt.Sprintf("{%s}", strings.Join(result, " ")) + } + return fmt.Sprint(v.Value) +}