-
Notifications
You must be signed in to change notification settings - Fork 2
/
mgdbparse.py
executable file
·96 lines (82 loc) · 3.81 KB
/
mgdbparse.py
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#!/usr/bin/env python3
# Copyright (c) 2016 "Jonathan Yantis"
#
# This file is a part of MiniGraphDB.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License, version 3,
# as published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# As a special exception, the copyright holders give permission to link the
# code of portions of this program with the OpenSSL library under certain
# conditions as described in each individual source file and distribute
# linked combinations including the program with the OpenSSL library. You
# must comply with the GNU Affero General Public License in all respects
# for all of the code used other than as permitted herein. If you modify
# file(s) with this exception, you may extend this exception to your
# version of the file(s), but you are not obligated to do so. If you do not
# wish to do so, delete this exception statement from your version. If you
# delete this exception statement from all source files in the program,
# then also delete it in the license file.
#
"""
MiniGraphDB Query Language
This code is an absolute mess, but is the start of a query language based on
Cypher for MiniGraphDB. This will likely require a major refactoring of the DB
itself to implement.
"""
from pyparsing import Word, Forward, Keyword, oneOf, alphas,\
alphanums, nums, Optional, Group, quotedString, ParseException
def testGrammer(cyp):
""" Test Parsing """
print(cyp, "->")
try:
tokens = simpleCypher.parseString(cyp)
print("tokens=", tokens)
print("tokens.srcNode=", tokens.srcNode)
print("tokens.firstTrOp=", tokens.firstTrOp)
print("tokens.secondTrOp=", tokens.secondTrOp)
print("tokens.dstNode=", tokens.dstNode)
print("tokens.relVar=", tokens.relVar)
print("tokens.relName=", tokens.relName)
print("tokens.whereCond=", tokens.whereCond)
print("tokens.return=", tokens.returnData)
except ParseException as err:
print(*err.loc + "\n" + err.msg)
print(err)
matchStmt = Forward()
relExpr = Forward()
whereExpr = Forward()
matchToken = Keyword("match", caseless=True)
returnToken = Keyword("return", caseless=True)
pathToken = Keyword("path", caseless=True)
whereToken = Keyword("where", caseless=True)
ident = Word(alphas, alphanums).setName("identifier")
prop = Word(alphas, alphanums).setName("property")
binOp = oneOf("== != >= <= > < =~")
trOp = oneOf("- -> -> <- <-")
intNum = Word(nums)
whereVal = quotedString | intNum
whereCondition = Group((ident) + '.'
+ prop + binOp
+ whereVal)
whereExpr << whereToken + whereCondition.setResultsName("whereCond")
relExpr << '[' + Optional((ident).setResultsName("relVar")) + ':' + ident.setResultsName("relName") + ']'
matchStmt << (matchToken + '(' + (ident).setResultsName("srcNode") + ')' +
Optional(trOp.setResultsName("firstTrOp") + Optional(relExpr) + trOp.setResultsName("secondTrOp")
+ '(' + ident.setResultsName("dstNode") + ')')
+ Optional(whereExpr)
+ returnToken + ((ident) + Optional('.' + prop)).setResultsName("returnData") )
simpleCypher = matchStmt
testGrammer('MATCH(A) RETURN A')
testGrammer('MATCH(A)-->(B) RETURN e')
testGrammer('MATCH(A)-[e1:E10G]->(B) RETURN e')
testGrammer('MATCH (A)-[e:TEST]->(B) WHERE A.type=="test" RETURN A.model')