csvpath 0.0.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- csvpath/__init__.py +1 -0
- csvpath/csvpath.py +368 -0
- csvpath/matching/__init__.py +1 -0
- csvpath/matching/expression_encoder.py +108 -0
- csvpath/matching/expression_math.py +123 -0
- csvpath/matching/expression_utility.py +29 -0
- csvpath/matching/functions/above.py +36 -0
- csvpath/matching/functions/add.py +24 -0
- csvpath/matching/functions/below.py +36 -0
- csvpath/matching/functions/concat.py +25 -0
- csvpath/matching/functions/count.py +44 -0
- csvpath/matching/functions/count_lines.py +12 -0
- csvpath/matching/functions/count_scans.py +13 -0
- csvpath/matching/functions/divide.py +30 -0
- csvpath/matching/functions/end.py +18 -0
- csvpath/matching/functions/every.py +33 -0
- csvpath/matching/functions/first.py +46 -0
- csvpath/matching/functions/function.py +31 -0
- csvpath/matching/functions/function_factory.py +114 -0
- csvpath/matching/functions/inf.py +38 -0
- csvpath/matching/functions/is_instance.py +95 -0
- csvpath/matching/functions/length.py +33 -0
- csvpath/matching/functions/lower.py +21 -0
- csvpath/matching/functions/minf.py +167 -0
- csvpath/matching/functions/multiply.py +27 -0
- csvpath/matching/functions/no.py +10 -0
- csvpath/matching/functions/notf.py +26 -0
- csvpath/matching/functions/now.py +33 -0
- csvpath/matching/functions/orf.py +28 -0
- csvpath/matching/functions/percent.py +29 -0
- csvpath/matching/functions/random.py +33 -0
- csvpath/matching/functions/regex.py +38 -0
- csvpath/matching/functions/subtract.py +28 -0
- csvpath/matching/functions/tally.py +36 -0
- csvpath/matching/functions/upper.py +21 -0
- csvpath/matching/matcher.py +215 -0
- csvpath/matching/matching_lexer.py +66 -0
- csvpath/matching/parser.out +1287 -0
- csvpath/matching/parsetab.py +1427 -0
- csvpath/matching/productions/equality.py +158 -0
- csvpath/matching/productions/expression.py +16 -0
- csvpath/matching/productions/header.py +30 -0
- csvpath/matching/productions/matchable.py +41 -0
- csvpath/matching/productions/term.py +11 -0
- csvpath/matching/productions/variable.py +15 -0
- csvpath/parser_utility.py +39 -0
- csvpath/scanning/__init__.py +1 -0
- csvpath/scanning/parser.out +1 -0
- csvpath/scanning/parsetab.py +231 -0
- csvpath/scanning/scanner.py +165 -0
- csvpath/scanning/scanning_lexer.py +47 -0
- csvpath-0.0.2.dist-info/METADATA +184 -0
- csvpath-0.0.2.dist-info/RECORD +54 -0
- csvpath-0.0.2.dist-info/WHEEL +4 -0
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
from typing import Any, List
|
|
2
|
+
from csvpath.matching.productions.variable import Variable
|
|
3
|
+
from csvpath.matching.productions.matchable import Matchable
|
|
4
|
+
from csvpath.matching.productions.header import Header
|
|
5
|
+
from csvpath.matching.productions.term import Term
|
|
6
|
+
from csvpath.matching.functions.function import Function
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Equality(Matchable):
|
|
10
|
+
def __init__(self, matcher):
|
|
11
|
+
super().__init__(matcher)
|
|
12
|
+
self.op: str = (
|
|
13
|
+
"=" # we assume = but if a function or other containing production
|
|
14
|
+
)
|
|
15
|
+
# wants to check we might have a different op
|
|
16
|
+
|
|
17
|
+
@property
|
|
18
|
+
def left(self):
|
|
19
|
+
return self.children[0]
|
|
20
|
+
|
|
21
|
+
@left.setter
|
|
22
|
+
def left(self, o):
|
|
23
|
+
if not self.children:
|
|
24
|
+
self.children = [None, None]
|
|
25
|
+
while len(self.children) < 2:
|
|
26
|
+
self.children.append(None)
|
|
27
|
+
else:
|
|
28
|
+
self.children[0] = o
|
|
29
|
+
|
|
30
|
+
@property
|
|
31
|
+
def right(self):
|
|
32
|
+
return self.children[1]
|
|
33
|
+
|
|
34
|
+
@right.setter
|
|
35
|
+
def right(self, o):
|
|
36
|
+
if not self.children:
|
|
37
|
+
self.children = [None, None]
|
|
38
|
+
while len(self.children) < 2:
|
|
39
|
+
self.children.append(None)
|
|
40
|
+
self.children[1] = o
|
|
41
|
+
|
|
42
|
+
def other_child(self, o):
|
|
43
|
+
if self.left == o:
|
|
44
|
+
return (self.right, 1)
|
|
45
|
+
elif self.right == o:
|
|
46
|
+
return (self.left, 0)
|
|
47
|
+
else:
|
|
48
|
+
return None
|
|
49
|
+
|
|
50
|
+
def is_terminal(self, o):
|
|
51
|
+
return (
|
|
52
|
+
isinstance(o, Variable)
|
|
53
|
+
or isinstance(o, Term)
|
|
54
|
+
or isinstance(o, Header)
|
|
55
|
+
or isinstance(o, Function)
|
|
56
|
+
or o is None
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
def both_terminal(self):
|
|
60
|
+
return self.is_terminal(self.left) and self.is_terminal(self.right)
|
|
61
|
+
|
|
62
|
+
def commas_to_list(self) -> List[Any]:
|
|
63
|
+
ls = []
|
|
64
|
+
self._to_list(ls, self)
|
|
65
|
+
return ls
|
|
66
|
+
|
|
67
|
+
def _to_list(self, ls: List, p):
|
|
68
|
+
if isinstance(p, Equality) and p.op == ",":
|
|
69
|
+
self._to_list(ls, p.left)
|
|
70
|
+
self._to_list(ls, p.right)
|
|
71
|
+
else:
|
|
72
|
+
ls.append(p)
|
|
73
|
+
|
|
74
|
+
def set_left(self, left):
|
|
75
|
+
self.left = left
|
|
76
|
+
if self.left:
|
|
77
|
+
self.add_child(self.left)
|
|
78
|
+
|
|
79
|
+
def set_right(self, right):
|
|
80
|
+
self.right = right
|
|
81
|
+
if self.right:
|
|
82
|
+
self.add_child(self.right)
|
|
83
|
+
|
|
84
|
+
def set_operation(self, op):
|
|
85
|
+
self.op = op
|
|
86
|
+
|
|
87
|
+
# ------------------
|
|
88
|
+
|
|
89
|
+
def mathic(self):
|
|
90
|
+
return self.op != ","
|
|
91
|
+
|
|
92
|
+
def perform_math(self):
|
|
93
|
+
if self.op == "," or self.op == "=":
|
|
94
|
+
return
|
|
95
|
+
else:
|
|
96
|
+
if isinstance(self.left, Equality):
|
|
97
|
+
pass
|
|
98
|
+
# self.left.perform_math()
|
|
99
|
+
if isinstance(self.right, Equality) and self.mathic():
|
|
100
|
+
pass
|
|
101
|
+
# self.right.perform_math()
|
|
102
|
+
self.left.value = self.math(self.left.to_value(), self.right.to_value())
|
|
103
|
+
if isinstance(self.left, Variable):
|
|
104
|
+
v = self.left.value
|
|
105
|
+
self.matcher.set_variable(self.left.name, value=v)
|
|
106
|
+
|
|
107
|
+
self.value = None
|
|
108
|
+
self.to_value()
|
|
109
|
+
|
|
110
|
+
def math(self, lv, rv):
|
|
111
|
+
if self.op == "-":
|
|
112
|
+
return lv - rv
|
|
113
|
+
elif self.op == "+":
|
|
114
|
+
return lv + rv
|
|
115
|
+
elif self.op == "*":
|
|
116
|
+
return lv * rv
|
|
117
|
+
elif self.op == "/":
|
|
118
|
+
return lv / rv
|
|
119
|
+
else:
|
|
120
|
+
raise Exception(f"unknown op: {self.op}")
|
|
121
|
+
|
|
122
|
+
# ------------------
|
|
123
|
+
|
|
124
|
+
def __str__(self) -> str:
|
|
125
|
+
return f"""{self.__class__}: {self.left}={self.right}"""
|
|
126
|
+
|
|
127
|
+
def matches(self, *, skip=[]) -> bool:
|
|
128
|
+
if self in skip:
|
|
129
|
+
return True
|
|
130
|
+
if not self.left or not self.right:
|
|
131
|
+
return False
|
|
132
|
+
if not self.value:
|
|
133
|
+
b = None
|
|
134
|
+
if isinstance(self.left, Variable):
|
|
135
|
+
v = self.right.to_value(skip=skip)
|
|
136
|
+
self.matcher.set_variable(self.left.name, value=v)
|
|
137
|
+
b = True
|
|
138
|
+
else:
|
|
139
|
+
left = self.left.to_value(skip=skip)
|
|
140
|
+
right = self.right.to_value(skip=skip)
|
|
141
|
+
if left.__class__ == right.__class__:
|
|
142
|
+
b = self.left.to_value(skip=skip) == self.right.to_value(skip=skip)
|
|
143
|
+
elif (left.__class__ == str and right.__class__ == int) or (
|
|
144
|
+
right.__class__ == str and left.__class__ == int
|
|
145
|
+
):
|
|
146
|
+
b = f"{left}" == f"{right}"
|
|
147
|
+
else:
|
|
148
|
+
b = f"{left}" == f"{right}"
|
|
149
|
+
self.value = b
|
|
150
|
+
return self.value
|
|
151
|
+
|
|
152
|
+
def to_value(self, *, skip=[]) -> Any:
|
|
153
|
+
if self.value is None:
|
|
154
|
+
if self.mathic():
|
|
155
|
+
pass
|
|
156
|
+
# self.perform_math()
|
|
157
|
+
self.value = self.matches(skip=skip)
|
|
158
|
+
return self.value
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from csvpath.matching.productions.matchable import Matchable
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class Expression(Matchable):
|
|
5
|
+
def matches(self, *, skip=[]) -> bool:
|
|
6
|
+
if not skip:
|
|
7
|
+
skip = []
|
|
8
|
+
if self in skip:
|
|
9
|
+
return True
|
|
10
|
+
if not self.value:
|
|
11
|
+
ret = True
|
|
12
|
+
for i, child in enumerate(self.children):
|
|
13
|
+
if not child.matches(skip=skip):
|
|
14
|
+
ret = False
|
|
15
|
+
self.value = ret
|
|
16
|
+
return self.value
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
from csvpath.matching.productions.matchable import Matchable
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class Header(Matchable):
|
|
6
|
+
def __str__(self) -> str:
|
|
7
|
+
return f"""{self.__class__}: {self.name} """
|
|
8
|
+
|
|
9
|
+
def to_value(self, *, skip=[]) -> Any:
|
|
10
|
+
if self in skip:
|
|
11
|
+
return True
|
|
12
|
+
if isinstance(self.name, int):
|
|
13
|
+
if self.name >= len(self.matcher.line):
|
|
14
|
+
return None
|
|
15
|
+
else:
|
|
16
|
+
return self.matcher.line[self.name]
|
|
17
|
+
else:
|
|
18
|
+
n = self.matcher.header_index(self.name)
|
|
19
|
+
# print(f"Header.to_value: n: {n}, a {n.__class__}")
|
|
20
|
+
if n is None:
|
|
21
|
+
# print(f"Header.to_value: no such header {self.name}")
|
|
22
|
+
return None
|
|
23
|
+
# print(f"Header: header index: {self.name} = {n}, line: {self.matcher.line}")
|
|
24
|
+
ret = None
|
|
25
|
+
if self.matcher.line and len(self.matcher.line) > n:
|
|
26
|
+
ret = self.matcher.line[n]
|
|
27
|
+
return ret
|
|
28
|
+
|
|
29
|
+
def matches(self, *, skip=[]) -> bool:
|
|
30
|
+
return not self.to_value(skip=skip) is None
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
from typing import Any, Self
|
|
2
|
+
from csvpath.matching.expression_utility import ExpressionUtility
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class Matchable:
|
|
6
|
+
def __init__(self, matcher, *, value: Any = None, name: str = None):
|
|
7
|
+
self.parent = None
|
|
8
|
+
self.children = []
|
|
9
|
+
self.matcher = matcher
|
|
10
|
+
self.value = value
|
|
11
|
+
self.name = name
|
|
12
|
+
self._id: str = None
|
|
13
|
+
if self.name and self.name.__class__ == str:
|
|
14
|
+
self.name = self.name.strip()
|
|
15
|
+
|
|
16
|
+
def __str__(self) -> str:
|
|
17
|
+
return f"""{self.__class__}"""
|
|
18
|
+
|
|
19
|
+
def matches(self, *, skip=[]) -> bool:
|
|
20
|
+
return True # leave this for now for testing
|
|
21
|
+
|
|
22
|
+
def to_value(self, *, skip=[]) -> Any:
|
|
23
|
+
return None
|
|
24
|
+
|
|
25
|
+
def index_of_child(self, o) -> int:
|
|
26
|
+
return self.children.index(o)
|
|
27
|
+
|
|
28
|
+
def set_parent(self, parent: Self) -> None:
|
|
29
|
+
self.parent = parent
|
|
30
|
+
|
|
31
|
+
def add_child(self, child: Self) -> None:
|
|
32
|
+
if child:
|
|
33
|
+
child.set_parent(self)
|
|
34
|
+
if child not in self.children:
|
|
35
|
+
self.children.append(child)
|
|
36
|
+
|
|
37
|
+
def get_id(self, child: Self = None) -> str:
|
|
38
|
+
if not self._id:
|
|
39
|
+
thing = self if not child else child
|
|
40
|
+
self._id = ExpressionUtility.get_id(thing=thing)
|
|
41
|
+
return self._id
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
from csvpath.matching.productions.matchable import Matchable
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class Term(Matchable):
|
|
6
|
+
def __str__(self) -> str:
|
|
7
|
+
return f"""{self.__class__}: {self.value} """
|
|
8
|
+
|
|
9
|
+
def to_value(self, *, skip=[]) -> Any:
|
|
10
|
+
v = self.value
|
|
11
|
+
return v
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
from csvpath.matching.productions.matchable import Matchable
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class Variable(Matchable):
|
|
6
|
+
def __str__(self) -> str:
|
|
7
|
+
return f"""{self.__class__}: {self.name}"""
|
|
8
|
+
|
|
9
|
+
def matches(self, *, skip=[]) -> bool:
|
|
10
|
+
return self.value is not None
|
|
11
|
+
|
|
12
|
+
def to_value(self, *, skip=[]) -> Any:
|
|
13
|
+
if not self.value:
|
|
14
|
+
self.value = self.matcher.get_variable(self.name)
|
|
15
|
+
return self.value
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
from ply.yacc import YaccProduction
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class ParserUtility:
|
|
5
|
+
def __init__(self, quiet=True):
|
|
6
|
+
self._quiet = quiet
|
|
7
|
+
|
|
8
|
+
def error(self, parser, p: YaccProduction) -> None:
|
|
9
|
+
if self._quiet and False:
|
|
10
|
+
return
|
|
11
|
+
# print(f"ParserUtility.error: {p}")
|
|
12
|
+
if p:
|
|
13
|
+
print(
|
|
14
|
+
f"syntax error at token {p.type}, line {p.lineno}, position {p.lexpos}"
|
|
15
|
+
)
|
|
16
|
+
print(f"unexpected token: {p.value}")
|
|
17
|
+
stack = parser.symstack
|
|
18
|
+
print(f"symbol stack: {stack}")
|
|
19
|
+
else:
|
|
20
|
+
print("syntax error at EOF")
|
|
21
|
+
|
|
22
|
+
def print_production(
|
|
23
|
+
self, p: YaccProduction, label: str = None, override=True
|
|
24
|
+
) -> None:
|
|
25
|
+
if self._quiet and not override:
|
|
26
|
+
return
|
|
27
|
+
if label:
|
|
28
|
+
label = f" at {label}"
|
|
29
|
+
print(f"production array{label} is:")
|
|
30
|
+
for _ in p:
|
|
31
|
+
print(f"\t{_} \t-> {_.__class__}")
|
|
32
|
+
|
|
33
|
+
@classmethod
|
|
34
|
+
def enumerate_p(self, message, p, quiet=True):
|
|
35
|
+
if quiet:
|
|
36
|
+
return
|
|
37
|
+
print(f"Enumerate {p}: {message}:")
|
|
38
|
+
for i, _ in enumerate(p):
|
|
39
|
+
print(f" p[{i}]: {_}")
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Created by PLY version 3.11 (http://www.dabeaz.com/ply)
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
# parsetab.py
|
|
2
|
+
# This file is automatically generated. Do not edit.
|
|
3
|
+
# pylint: disable=W,C,R
|
|
4
|
+
_tabversion = "3.10"
|
|
5
|
+
|
|
6
|
+
_lr_method = "LALR"
|
|
7
|
+
|
|
8
|
+
_lr_signature = "pathALL_LINES ANY FILENAME LEFT_BRACKET MINUS NAME NUMBER PLUS RIGHT_BRACKET ROOTroot : ROOT filenamefilename : FILENAMEpath : root LEFT_BRACKET expression RIGHT_BRACKETexpression : expression PLUS term\n | expression MINUS term\n | termterm : NUMBER\n | NUMBER ALL_LINES\n | ALL_LINES"
|
|
9
|
+
|
|
10
|
+
_lr_action_items = {
|
|
11
|
+
"ROOT": (
|
|
12
|
+
[
|
|
13
|
+
0,
|
|
14
|
+
],
|
|
15
|
+
[
|
|
16
|
+
3,
|
|
17
|
+
],
|
|
18
|
+
),
|
|
19
|
+
"$end": (
|
|
20
|
+
[
|
|
21
|
+
1,
|
|
22
|
+
11,
|
|
23
|
+
],
|
|
24
|
+
[
|
|
25
|
+
0,
|
|
26
|
+
-3,
|
|
27
|
+
],
|
|
28
|
+
),
|
|
29
|
+
"LEFT_BRACKET": (
|
|
30
|
+
[
|
|
31
|
+
2,
|
|
32
|
+
5,
|
|
33
|
+
6,
|
|
34
|
+
],
|
|
35
|
+
[
|
|
36
|
+
4,
|
|
37
|
+
-1,
|
|
38
|
+
-2,
|
|
39
|
+
],
|
|
40
|
+
),
|
|
41
|
+
"FILENAME": (
|
|
42
|
+
[
|
|
43
|
+
3,
|
|
44
|
+
],
|
|
45
|
+
[
|
|
46
|
+
6,
|
|
47
|
+
],
|
|
48
|
+
),
|
|
49
|
+
"NUMBER": (
|
|
50
|
+
[
|
|
51
|
+
4,
|
|
52
|
+
12,
|
|
53
|
+
13,
|
|
54
|
+
],
|
|
55
|
+
[
|
|
56
|
+
9,
|
|
57
|
+
9,
|
|
58
|
+
9,
|
|
59
|
+
],
|
|
60
|
+
),
|
|
61
|
+
"ALL_LINES": (
|
|
62
|
+
[
|
|
63
|
+
4,
|
|
64
|
+
9,
|
|
65
|
+
12,
|
|
66
|
+
13,
|
|
67
|
+
],
|
|
68
|
+
[
|
|
69
|
+
10,
|
|
70
|
+
14,
|
|
71
|
+
10,
|
|
72
|
+
10,
|
|
73
|
+
],
|
|
74
|
+
),
|
|
75
|
+
"RIGHT_BRACKET": (
|
|
76
|
+
[
|
|
77
|
+
7,
|
|
78
|
+
8,
|
|
79
|
+
9,
|
|
80
|
+
10,
|
|
81
|
+
14,
|
|
82
|
+
15,
|
|
83
|
+
16,
|
|
84
|
+
],
|
|
85
|
+
[
|
|
86
|
+
11,
|
|
87
|
+
-6,
|
|
88
|
+
-7,
|
|
89
|
+
-9,
|
|
90
|
+
-8,
|
|
91
|
+
-4,
|
|
92
|
+
-5,
|
|
93
|
+
],
|
|
94
|
+
),
|
|
95
|
+
"PLUS": (
|
|
96
|
+
[
|
|
97
|
+
7,
|
|
98
|
+
8,
|
|
99
|
+
9,
|
|
100
|
+
10,
|
|
101
|
+
14,
|
|
102
|
+
15,
|
|
103
|
+
16,
|
|
104
|
+
],
|
|
105
|
+
[
|
|
106
|
+
12,
|
|
107
|
+
-6,
|
|
108
|
+
-7,
|
|
109
|
+
-9,
|
|
110
|
+
-8,
|
|
111
|
+
-4,
|
|
112
|
+
-5,
|
|
113
|
+
],
|
|
114
|
+
),
|
|
115
|
+
"MINUS": (
|
|
116
|
+
[
|
|
117
|
+
7,
|
|
118
|
+
8,
|
|
119
|
+
9,
|
|
120
|
+
10,
|
|
121
|
+
14,
|
|
122
|
+
15,
|
|
123
|
+
16,
|
|
124
|
+
],
|
|
125
|
+
[
|
|
126
|
+
13,
|
|
127
|
+
-6,
|
|
128
|
+
-7,
|
|
129
|
+
-9,
|
|
130
|
+
-8,
|
|
131
|
+
-4,
|
|
132
|
+
-5,
|
|
133
|
+
],
|
|
134
|
+
),
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
_lr_action = {}
|
|
138
|
+
for _k, _v in _lr_action_items.items():
|
|
139
|
+
for _x, _y in zip(_v[0], _v[1]):
|
|
140
|
+
if not _x in _lr_action:
|
|
141
|
+
_lr_action[_x] = {}
|
|
142
|
+
_lr_action[_x][_k] = _y
|
|
143
|
+
del _lr_action_items
|
|
144
|
+
|
|
145
|
+
_lr_goto_items = {
|
|
146
|
+
"path": (
|
|
147
|
+
[
|
|
148
|
+
0,
|
|
149
|
+
],
|
|
150
|
+
[
|
|
151
|
+
1,
|
|
152
|
+
],
|
|
153
|
+
),
|
|
154
|
+
"root": (
|
|
155
|
+
[
|
|
156
|
+
0,
|
|
157
|
+
],
|
|
158
|
+
[
|
|
159
|
+
2,
|
|
160
|
+
],
|
|
161
|
+
),
|
|
162
|
+
"filename": (
|
|
163
|
+
[
|
|
164
|
+
3,
|
|
165
|
+
],
|
|
166
|
+
[
|
|
167
|
+
5,
|
|
168
|
+
],
|
|
169
|
+
),
|
|
170
|
+
"expression": (
|
|
171
|
+
[
|
|
172
|
+
4,
|
|
173
|
+
],
|
|
174
|
+
[
|
|
175
|
+
7,
|
|
176
|
+
],
|
|
177
|
+
),
|
|
178
|
+
"term": (
|
|
179
|
+
[
|
|
180
|
+
4,
|
|
181
|
+
12,
|
|
182
|
+
13,
|
|
183
|
+
],
|
|
184
|
+
[
|
|
185
|
+
8,
|
|
186
|
+
15,
|
|
187
|
+
16,
|
|
188
|
+
],
|
|
189
|
+
),
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
_lr_goto = {}
|
|
193
|
+
for _k, _v in _lr_goto_items.items():
|
|
194
|
+
for _x, _y in zip(_v[0], _v[1]):
|
|
195
|
+
if not _x in _lr_goto:
|
|
196
|
+
_lr_goto[_x] = {}
|
|
197
|
+
_lr_goto[_x][_k] = _y
|
|
198
|
+
del _lr_goto_items
|
|
199
|
+
_lr_productions = [
|
|
200
|
+
("S' -> path", "S'", 1, None, None, None),
|
|
201
|
+
("root -> ROOT filename", "root", 2, "p_root", "scanner.py", 64),
|
|
202
|
+
("filename -> FILENAME", "filename", 1, "p_filename", "scanner.py", 67),
|
|
203
|
+
(
|
|
204
|
+
"path -> root LEFT_BRACKET expression RIGHT_BRACKET",
|
|
205
|
+
"path",
|
|
206
|
+
4,
|
|
207
|
+
"p_path",
|
|
208
|
+
"scanner.py",
|
|
209
|
+
71,
|
|
210
|
+
),
|
|
211
|
+
(
|
|
212
|
+
"expression -> expression PLUS term",
|
|
213
|
+
"expression",
|
|
214
|
+
3,
|
|
215
|
+
"p_expression",
|
|
216
|
+
"scanner.py",
|
|
217
|
+
77,
|
|
218
|
+
),
|
|
219
|
+
(
|
|
220
|
+
"expression -> expression MINUS term",
|
|
221
|
+
"expression",
|
|
222
|
+
3,
|
|
223
|
+
"p_expression",
|
|
224
|
+
"scanner.py",
|
|
225
|
+
78,
|
|
226
|
+
),
|
|
227
|
+
("expression -> term", "expression", 1, "p_expression", "scanner.py", 79),
|
|
228
|
+
("term -> NUMBER", "term", 1, "p_term", "scanner.py", 90),
|
|
229
|
+
("term -> NUMBER ALL_LINES", "term", 2, "p_term", "scanner.py", 91),
|
|
230
|
+
("term -> ALL_LINES", "term", 1, "p_term", "scanner.py", 92),
|
|
231
|
+
]
|