forked from sublhighlight/sublhighlight
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscsast.py
More file actions
129 lines (115 loc) · 2.75 KB
/
scsast.py
File metadata and controls
129 lines (115 loc) · 2.75 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
120
121
122
123
124
125
126
127
128
129
import regex as re
re_token_patt = re.compile(r"([a-zA-Z0-9_\-.]+|\,|\|| - |\(|\))")
OP_OR = "|"
OP_XCL = " - "
OP_INCL = ","
OPERATORS = (OP_OR, OP_XCL, OP_INCL)
def __opgroup(expr, op):
r = None
buf = []
for item in expr:
if item == op:
if len(buf) == 1 and isinstance(buf[0], tuple):
buf = buf[0]
if not r:
r = (op, [buf])
else:
r[1].append(buf)
buf = []
elif isinstance(item, list):
buf.append(__opgroup(item, op))
elif isinstance(item, tuple):
buf.append((item[0], __opgroup(item[1], op)))
else:
buf.append(item)
if buf:
if not r:
return buf
if len(buf) == 1 and isinstance(buf[0], tuple):
buf = buf[0]
r[1].append(buf)
return r
def __splittags(expr):
if isinstance(expr, tuple):
op, subxp = expr
__splittags(subxp)
elif isinstance(expr, list):
for i in range(len(expr)):
if isinstance(expr[i], str):
expr[i] = expr[i].split(".")
else:
__splittags(expr[i])
def parserulescope(string_expression):
toks = re_token_patt.findall(string_expression)
stck = [[]]
tid = 0
for t in toks:
if t == "(":
newxp = []
stck[-1].append(newxp)
stck.append(newxp)
elif t == ")":
if len(stck) <= 1:
raise Exception(f"stray parens, token {repr(t)} ({tid}), in {toks}")
stck.pop()
else:
stck[-1].append(t)
tid += 1
if len(stck) != 1:
raise Exception(f"unblanced parens in {toks}")
expr = stck[0]
for op in OPERATORS:
if isinstance(expr, tuple):
expr = (expr[0], __opgroup(expr[1], op))
else:
expr = __opgroup(expr, op)
__splittags(expr)
return expr
def scorescope(scopedef, scopestack, ss_len):
best_score = 0
sd_len = len(scopedef)
end_i = ss_len - sd_len + 1
i = 0
while i < end_i:
score = 0
j = 0
while j < sd_len:
sstags = scopestack[i+j]
tags = scopedef[j]#.split(".")
for a, b in zip(sstags, tags):
if a != b:
score = 0
break
score += 1
if score <= 0:
break
j += 1
if score > best_score:
best_score = score
i += 1
return best_score
def scorexp(xp, scopestack, ss_len):
if isinstance(xp, tuple):
op, subxp = xp
if op == OP_OR or op == OP_INCL: # is this correct? I don't think so
best_score = 0
for xp in subxp:
score = scorexp(xp, scopestack, ss_len)
best_score = max(best_score, score)
elif op == OP_XCL:
main, *xcl = subxp
best_score = scorexp(main, scopestack, ss_len)
for xp in xcl:
score = scorexp(xp, scopestack, ss_len)
if score > 0:
best_score = 0
break
return best_score
return scorescope(xp, scopestack, ss_len)
if __name__ == "__main__":
import sys
rulescope = parserulescope(sys.argv[1])
print("rulescope", rulescope)
ss = [['source', 'python'], ['keyword', 'control', 'import', 'python']]
print("ss", ss)
print("scorexp", scorexp(rulescope, ss, len(ss)))