opencypher / openCypher

Specification of the Cypher property graph query language
http://www.opencypher.org
Apache License 2.0
841 stars 149 forks source link

missing children from `OC_ComparisonExpressionContext` in cpp-runtime of ANTLR #529

Open chakpongchung opened 2 years ago

chakpongchung commented 2 years ago

How can we solve this missing-children problem?

I am trying to use the antlr4 c++ runtime for the openCypher grammar.

When I tried to parse the following query,

MATCH (p1:Person)-->(p2:Person)
WHERE p1.id < p2.id
RETURN p1.id, p2.id

I see a child missing for the parent node OC_ComparisonExpressionContext in the visitor pattern:

    antlrcpp::Any visitOC_ComparisonExpression(CypherParser::OC_ComparisonExpressionContext *ctx) override {
        cout<<ctx->children.size()<<endl;
        return visitChildren(ctx);
    }

    antlrcpp::Any
    visitOC_PartialComparisonExpression(CypherParser::OC_PartialComparisonExpressionContext *ctx) override {
        return visitChildren(ctx);
    }

Here the ctx->children.size() shows 1 but it indeed has 3 children from the parse tree generated which one of them is oC_PartialComparisonExpression. With this problem, visitOC_PartialComparisonExpression is not called because visitChildren(ctx) from visitOC_ComparisonExpression() will not get to this missing child.

(oC_Cypher 
        (oC_Statement 
            (oC_Query 
                (oC_RegularQuery 
                    (oC_SingleQuery 
                        (oC_SinglePartQuery 
                            (oC_ReadingClause 
                                (oC_Match MATCH   
                                    (oC_Pattern 
                                        (oC_PatternPart 
                                            (oC_AnonymousPatternPart 
                                                (oC_PatternElement 
                                                    (oC_NodePattern ( 
                                                        (oC_Variable 
                                                            (oC_SymbolicName p1)) 
                                                        (oC_NodeLabels 
                                                            (oC_NodeLabel : 
                                                                (oC_LabelName 
                                                                    (oC_SchemaName 
                                                                        (oC_SymbolicName Person))))) )) 
                                                    (oC_PatternElementChain 
                                                        (oC_RelationshipPattern 
                                                            (oC_Dash -) 
                                                            (oC_Dash -) 
                                                            (oC_RightArrowHead >)) 
                                                        (oC_NodePattern ( 
                                                            (oC_Variable 
                                                                (oC_SymbolicName p2)) 
                                                            (oC_NodeLabels 
                                                                (oC_NodeLabel : 
                                                                    (oC_LabelName 
                                                                        (oC_SchemaName 
                                                                            (oC_SymbolicName Person))))) ))))))) \n 
                                    (oC_Where WHERE   
                                        (oC_Expression 
                                            (oC_OrExpression 
                                                (oC_XorExpression 
                                                    (oC_AndExpression 
                                                        (oC_NotExpression 
                                                            (oC_ComparisonExpression 
                                                                (oC_AddOrSubtractExpression 
                                                                    (oC_MultiplyDivideModuloExpression 
                                                                        (oC_PowerOfExpression 
                                                                            (oC_UnaryAddOrSubtractExpression 
                                                                                (oC_StringListNullOperatorExpression 
                                                                                    (oC_PropertyOrLabelsExpression 
                                                                                        (oC_Atom 
                                                                                            (oC_Variable 
                                                                                                (oC_SymbolicName p1))) 
                                                                                        (oC_PropertyLookup . 
                                                                                            (oC_PropertyKeyName 
                                                                                                (oC_SchemaName 
                                                                                                    (oC_SymbolicName id))))))))))   
                                                                (oC_PartialComparisonExpression <   
                                                                    (oC_AddOrSubtractExpression 
                                                                        (oC_MultiplyDivideModuloExpression 
                                                                            (oC_PowerOfExpression 
                                                                                (oC_UnaryAddOrSubtractExpression 
                                                                                    (oC_StringListNullOperatorExpression 
                                                                                        (oC_PropertyOrLabelsExpression 
                                                                                            (oC_Atom 
                                                                                                (oC_Variable 
                                                                                                    (oC_SymbolicName p2))) 
                                                                                            (oC_PropertyLookup . 
                                                                                                (oC_PropertyKeyName 
                                                                                                    (oC_SchemaName 
                                                                                                        (oC_SymbolicName id)))))))))))))))))))) \n 
                            (oC_Return RETURN 
                                (oC_ProjectionBody   
                                    (oC_ProjectionItems 
                                        (oC_ProjectionItem 
                                            (oC_Expression 
                                                (oC_OrExpression 
                                                    (oC_XorExpression 
                                                        (oC_AndExpression 
                                                            (oC_NotExpression 
                                                                (oC_ComparisonExpression 
                                                                    (oC_AddOrSubtractExpression 
                                                                        (oC_MultiplyDivideModuloExpression 
                                                                            (oC_PowerOfExpression 
                                                                                (oC_UnaryAddOrSubtractExpression 
                                                                                    (oC_StringListNullOperatorExpression 
                                                                                        (oC_PropertyOrLabelsExpression 
                                                                                            (oC_Atom 
                                                                                                (oC_Variable 
                                                                                                    (oC_SymbolicName p1))) 
                                                                                            (oC_PropertyLookup . 
                                                                                                (oC_PropertyKeyName 
                                                                                                    (oC_SchemaName 
                                                                                                        (oC_SymbolicName id))))))))))))))))) ,   
                                        (oC_ProjectionItem 
                                            (oC_Expression 
                                                (oC_OrExpression 
                                                    (oC_XorExpression 
                                                        (oC_AndExpression 
                                                            (oC_NotExpression 
                                                                (oC_ComparisonExpression 
                                                                    (oC_AddOrSubtractExpression 
                                                                        (oC_MultiplyDivideModuloExpression 
                                                                            (oC_PowerOfExpression 
                                                                                (oC_UnaryAddOrSubtractExpression 
                                                                                    (oC_StringListNullOperatorExpression 
                                                                                        (oC_PropertyOrLabelsExpression 
                                                                                            (oC_Atom 
                                                                                                (oC_Variable 
                                                                                                    (oC_SymbolicName p2))) 
                                                                                            (oC_PropertyLookup . 
                                                                                                (oC_PropertyKeyName 
                                                                                                    (oC_SchemaName 
                                                                                                        (oC_SymbolicName id))))))))))))))))))))))))) <EOF>)

I have tried the listener pattern and it has no this missing-child problem. Also, I have tried the Java runtime and this problem is not there.

To reproduce the problem in C++, I have provided the dependencies needed.

https://s3.amazonaws.com/artifacts.opencypher.org/M18/Cypher.g4

hvub commented 2 years ago

Hi,

Thank you for engaging with the openCypher grammar.

To your problem: Unfortunately, I cannot speak to the C++ specific part of it. If the behavior is indeed different between different host language (Java vs. C++) and different usage patterns, then it seems to be more an Antlr problem to me.

However, let me note something just in case you have miss it by accident.

(naming as in the Java variant)

Maybe you happen to look at the wrong oC_ComparisonExpression?!? Just checking.

Another possibility is that you miss a method in your visitor or a return line in one of the methods, so that the visitor is no fully descending the parse tree under oC_Match and never gets to the oC_ComparisonExpression with three children in the first place. Have you tried to print out the fully parse tree with your visitor? Or checked by other means that is actually walks the whole tree?

Note that I am mostly guessing. You may have double checked all of that already. If so, I am sorry. Hope it helps, anyway.

chakpongchung commented 2 years ago

@hvub

Thanks! the problem is resolved. I work on the openCypher implementation at KatanaGraph. I would like to know whether I can join the openCypher committee so we can officially contribute back to the community. I have implemented a majority part of the openCypher. I found there are several places where improvement of the grammar is needed to simplify the implementation.