-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcore.py
More file actions
119 lines (93 loc) · 2.57 KB
/
Copy pathcore.py
File metadata and controls
119 lines (93 loc) · 2.57 KB
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
from typing import NamedTuple, List
from sly import Lexer, Parser
class SQLFunctionsLexer(Lexer):
literals = {'(', ')', '{', '}', ',', ';'}
tokens = {VAR, WORD, OTHER}
ignore = ' \t'
ignore_comment = r'\-\-.*'
@_(r'\n+')
def ignore_newline(self, t):
self.lineno += len(t.value)
VAR = r'(\$\w+|\'\$\w+\')'
WORD = r'\w+'
OTHER = r'[^\n\(\)\{\}\,\;\$]+'
class QueryVar(NamedTuple):
name: str
is_quoted: bool
class SQLFunction(NamedTuple):
name: str
params: List[str]
body: List[List[str]]
def __repr__(self):
return 'Function(\n\tname: %r\n\tparams: %r\n\tbody: [%s\n\t]\n)' % (
self.name,
self.params,
''.join(f'\n\t\t{stmt!r},' for stmt in self.body),
)
class SQLFunctionsParser(Parser):
tokens = SQLFunctionsLexer.tokens
literals = SQLFunctionsLexer.literals
# root
@_('', 'function', 'function root')
def root(self, p):
root = []
try:
root.append(p.function)
except KeyError:
pass
try:
root += p.root
except KeyError:
pass
return root
# SQL fragment
@_('WORD', 'OTHER', '")"', '"("', '","', 'fragment fragment')
def fragment(self, p):
return ' '.join(p)
# SQL statement (fragment + variables)
@_('VAR')
def statement(self, p):
return [
QueryVar(
p.VAR.strip("'").strip('$'),
p.VAR.startswith("'") and p.VAR.endswith("'"),
)
]
@_('fragment')
def statement(self, p):
return [p.fragment]
@_('statement statement')
def statement(self, p):
total = []
for statement in p:
if isinstance(statement, list):
total += statement
else:
total.append(statement)
return total
# SQL statements
@_('statement ";"', 'statement ";" body')
def body(self, p):
body = [p.statement]
try:
body += p.body
except KeyError:
pass
return body
# function
@_('WORD "(" params ")" "{" body "}"', 'WORD "(" ")" "{" body "}"')
def function(self, p):
try:
params = p.params
except KeyError:
params = []
return SQLFunction(p.WORD, params, p.body)
# params
@_('WORD', 'WORD ","', 'WORD "," params')
def params(self, p):
params = [p.WORD]
try:
params += p.params
except KeyError:
pass
return params