Skip to content

Commit b125a8b

Browse files
committed
Update
1 parent e7990de commit b125a8b

15 files changed

+298
-685
lines changed

main.py

+15-438
Large diffs are not rendered by default.

pynescript/ast/helpers.py

+18-17
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,23 @@
33
from pynescript.ast.types import AST
44

55

6+
def _dump_value_impl(value, indent: int = 0, depth: int = 0):
7+
indent_step = " " * indent
8+
if isinstance(value, AST):
9+
return _dump_impl(value, indent=indent, depth=depth)
10+
elif isinstance(value, list) and len(value) > 0:
11+
lines = []
12+
lines.append("[")
13+
for subvalue in value:
14+
lines.append(
15+
f"{indent_step * (depth + 1)}{_dump_value_impl(subvalue, indent=indent, depth=depth + 1)},"
16+
)
17+
lines.append(f"{indent_step * depth}]")
18+
return "\n".join(lines)
19+
else:
20+
return f"{value!r}"
21+
22+
623
def _dump_impl(node: AST, indent: int = 0, depth: int = 0):
724
class_name = node.__class__.__name__
825
class_params_except = [
@@ -20,27 +37,11 @@ def _dump_impl(node: AST, indent: int = 0, depth: int = 0):
2037
}
2138
if indent > 0 and len(class_params) > 0:
2239
indent_step = " " * indent
23-
24-
def _dump_value(value, indent=0, depth=0):
25-
if isinstance(value, AST):
26-
return _dump_impl(value, indent=indent, depth=depth)
27-
elif isinstance(value, list) and len(value) > 0:
28-
lines = []
29-
lines.append("[")
30-
for subvalue in value:
31-
lines.append(
32-
f"{indent_step * (depth + 1)}{_dump_value(subvalue, indent=indent, depth=depth + 1)},"
33-
)
34-
lines.append(f"{indent_step * depth}]")
35-
return "\n".join(lines)
36-
else:
37-
return f"{value!r}"
38-
3940
lines = []
4041
lines.append(f"{class_name}(")
4142
for name, value in class_params.items():
4243
lines.append(
43-
f"{indent_step * (depth + 1)}{name}={_dump_value(value, indent=indent, depth=depth + 1)},"
44+
f"{indent_step * (depth + 1)}{name}={_dump_value_impl(value, indent=indent, depth=depth + 1)},"
4445
)
4546
lines.append(f"{indent_step * depth})")
4647
return "\n".join(lines)

pynescript/ast/parser/grammars/__init__.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
if debug:
66
pyparsing.enable_all_warnings()
77
pyparsing.enable_diag(pyparsing.Diagnostics.enable_debug_on_named_expressions)
8-
pyparsing.disable_diag(pyparsing.Diagnostics.warn_name_set_on_empty_Forward)
8+
pyparsing.disable_diag(
9+
pyparsing.Diagnostics.warn_ungrouped_named_tokens_in_collection
10+
)
911

1012
pyparsing.ParserElement.enable_left_recursion()
1113

@@ -30,9 +32,7 @@
3032

3133
assignment_grammars.structure <<= structure_grammars.structure
3234
assignment_grammars.expression <<= expression_grammars.expression
33-
assignment_grammars.atomic_type_name <<= common_grammars.atomic_type_name
34-
assignment_grammars.collection_type_name <<= common_grammars.collection_type_name
35-
assignment_grammars.type_argument <<= common_grammars.type_argument
35+
assignment_grammars.type_specifier <<= common_grammars.type_specifier
3636
assignment_grammars.identifier_declarator <<= common_grammars.identifier_declarator
3737
assignment_grammars.tuple_declarator <<= common_grammars.tuple_declarator
3838
assignment_grammars.function_call <<= common_grammars.function_call
+8-28
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,17 @@
11
from pyparsing import (
22
Forward,
3-
Suppress,
4-
Combine,
53
Opt,
64
)
75

86
from pynescript import ast
97
from pynescript.ast.parser.parser_elements import (
8+
ResultNameableForward as Forward,
109
ConvertToNode,
1110
)
1211
from pynescript.ast.parser.tokens import (
1312
IDENTIFIER,
1413
VAR,
1514
VARIP,
16-
LBRACKET,
17-
RBRACKET,
1815
ASSIGN,
1916
COLON_ASSIGN,
2017
MUL_ASSIGN,
@@ -27,35 +24,13 @@
2724
structure = Forward()
2825
expression = Forward()
2926

30-
atomic_type_name = Forward()
31-
collection_type_name = Forward()
32-
type_argument = Forward()
27+
type_specifier = Forward()
3328
identifier_declarator = Forward()
3429
tuple_declarator = Forward()
3530
function_call = Forward()
3631

37-
3832
declaration_mode = ConvertToNode(ast.Var)(VAR) | ConvertToNode(ast.VarIp)(VARIP)
39-
40-
41-
def handle_array_type_specifier(argument):
42-
node = ast.TypeReference(ast.Subscript(argument))
43-
return node
44-
45-
46-
array_type_specifier = ConvertToNode(handle_array_type_specifier)(
47-
Combine(atomic_type_name("value") + Suppress(Combine(LBRACKET + RBRACKET)))
48-
)
49-
50-
collection_type_specifier = ConvertToNode(ast.TypeReference)(
51-
collection_type_name("name") + type_argument("argument")
52-
)
53-
54-
atomic_type_specifier = ConvertToNode(ast.TypeReference)(atomic_type_name("name"))
55-
56-
type_specifier = (
57-
collection_type_specifier | array_type_specifier | atomic_type_specifier
58-
)
33+
declaration_mode.set_name("declaration_mode")
5934

6035
assignment_operator = ConvertToNode(ast.Assign)(ASSIGN)
6136

@@ -66,14 +41,17 @@ def handle_array_type_specifier(argument):
6641
+ assignment_operator("operator")
6742
+ (structure | expression)("value")
6843
)
44+
identifier_declarator_declaration.set_name("identifier_declarator_declaration")
6945

7046
tuple_declarator_declaration = ConvertToNode(ast.Assignment)(
7147
tuple_declarator("target")
7248
+ assignment_operator("operator")
7349
+ (structure | function_call)("value")
7450
)
51+
tuple_declarator_declaration.set_name("tuple_declarator_declaration")
7552

7653
variable_declaration = identifier_declarator_declaration | tuple_declarator_declaration
54+
variable_declaration.set_name("variable_declaration")
7755

7856
reassignment_operator = (
7957
ConvertToNode(ast.ColonAssign)(COLON_ASSIGN)
@@ -89,5 +67,7 @@ def handle_array_type_specifier(argument):
8967
+ reassignment_operator("operator")
9068
+ (structure | expression)("value")
9169
)
70+
variable_reassignment.set_name("variable_reassignment")
9271

9372
assignment = variable_declaration | variable_reassignment
73+
assignment.set_name("assignment")

pynescript/ast/parser/grammars/common.py

+71-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from pyparsing import (
22
Forward,
33
Suppress,
4+
Combine,
45
Group,
56
Opt,
67
Empty,
@@ -10,6 +11,8 @@
1011

1112
from pynescript import ast
1213
from pynescript.ast.parser.parser_elements import (
14+
ResultNameableForward as Forward,
15+
IndentedBlockWithTabs as IndentedBlock,
1316
ConvertToNode,
1417
)
1518
from pynescript.ast.parser.tokens import (
@@ -40,6 +43,9 @@
4043
expression = Forward()
4144
local_statement = Forward()
4245

46+
type_specifier = Forward()
47+
type_specifier.set_name("type_specifier")
48+
4349
atomic_type_name = (
4450
ConvertToNode(ast.Int)(INT)
4551
| ConvertToNode(ast.Float)(FLOAT)
@@ -53,18 +59,74 @@
5359
| ConvertToNode(ast.Table)(TABLE)
5460
)
5561

62+
atomic_type_name.set_name("atomic_type_name")
63+
5664
array_type_name = ConvertToNode(ast.Array)(ARRAY)
65+
array_type_name.set_name("array_type_name")
66+
5767
matrix_type_name = ConvertToNode(ast.Matrix)(MATRIX)
68+
matrix_type_name.set_name("matrix_type_name")
5869

5970
collection_type_name = array_type_name | matrix_type_name
71+
collection_type_name.set_name("collection_type_name")
72+
73+
type_name = collection_type_name | atomic_type_name
74+
type_name.set_name("type_name")
75+
76+
type_argument = Suppress(LCHEVRON) + type_specifier + Suppress(RCHEVRON)
77+
type_argument.set_name("type_argument")
78+
79+
collection_type_specifier = ConvertToNode(ast.CollectionType)(
80+
collection_type_name("type_name") + type_argument("type_argument")
81+
)
82+
collection_type_specifier.set_name("collection_type_specifier")
83+
84+
array_type_suffix = Combine(LBRACKET + RBRACKET)
85+
array_type_suffix.set_name("array_type_suffix")
86+
87+
array_type_specifier = ConvertToNode(ast.ArrayType)(
88+
Combine(type_specifier("element_type") + Suppress(array_type_suffix))
89+
)
90+
array_type_specifier.set_name("array_type_specifier")
91+
92+
atomic_type_specifier = atomic_type_name
93+
atomic_type_specifier.set_name("atomic_type_specifier")
94+
95+
# this gives "ParseException raised: Forward recursion without base case, found '?' ..." error
96+
type_specifier <<= (
97+
collection_type_specifier | array_type_specifier | atomic_type_specifier
98+
)
99+
100+
# this solves the recursion problem above, but requires extra effort on parser action
101+
type_specifier_trailing = Forward()
102+
type_specifier_trailing <<= Opt(
103+
(array_type_suffix | type_argument) + type_specifier_trailing
104+
)
105+
106+
107+
def handle_type_specifier(results):
108+
last_token = results[-1]
109+
if len(results) == 1:
110+
return last_token
111+
else:
112+
results_except_last_token = results[:-1]
113+
if last_token == "[]":
114+
element_type_token = handle_type_specifier(results_except_last_token)
115+
return ast.ArrayType(element_type_token)
116+
else:
117+
type_name_token = handle_type_specifier(results_except_last_token)
118+
type_argument_token = last_token
119+
return ast.CollectionType(type_name_token, type_argument_token)
120+
121+
122+
type_specifier <<= ConvertToNode(handle_type_specifier)(
123+
Group(type_name + type_specifier_trailing)
124+
)
60125

61-
type_argument = Suppress(LCHEVRON) + atomic_type_name + Suppress(RCHEVRON)
62126

63127
name = ConvertToNode(ast.Name)(IDENTIFIER)
64-
attributed_name = Empty() + delimited_list(name, DOT).leave_whitespace()
65128

66129

67-
@attributed_name.set_parse_action
68130
def handle_attributed_name(results):
69131
node = results[0]
70132
for attr in results[1:]:
@@ -82,6 +144,11 @@ def handle_attributed_name(results):
82144
return node
83145

84146

147+
attributed_name = ConvertToNode(handle_attributed_name)(
148+
Group(Empty() + delimited_list(name, DOT).leave_whitespace())
149+
)
150+
151+
85152
full_argument = IDENTIFIER("name") + Suppress(ASSIGN) + expression("value")
86153
value_only_argument = expression("value")
87154

@@ -91,7 +158,7 @@ def handle_attributed_name(results):
91158

92159
function_call = ConvertToNode(ast.Call)(
93160
attributed_name("name")
94-
+ Opt(type_argument)
161+
+ Opt(type_argument("type_argument"))
95162
+ Suppress(LPAREN)
96163
+ Opt(argument_list("arguments"))
97164
+ Suppress(RPAREN)

pynescript/ast/parser/grammars/expression.py

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
from pynescript import ast
99
from pynescript.ast.parser.parser_elements import (
10+
ResultNameableForward as Forward,
1011
ConvertToNode,
1112
)
1213
from pynescript.ast.parser.tokens import (

pynescript/ast/parser/grammars/module.py

+6-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
Forward,
33
Literal,
44
Keyword,
5+
SkipTo,
56
FollowedBy,
7+
Suppress,
68
LineEnd,
79
Group,
810
ZeroOrMore,
@@ -11,12 +13,15 @@
1113

1214
from pynescript import ast
1315
from pynescript.ast.parser.parser_elements import (
16+
ResultNameableForward as Forward,
1417
ConvertToNode,
1518
)
1619

1720
global_statement = Forward()
1821

19-
comment = Literal("//") + ... + FollowedBy(LineEnd())
22+
comment = Literal("//") + SkipTo(LineEnd())("comment")
23+
24+
comment_suppressed = Suppress(comment)
2025

2126
version_comment = (
2227
Literal("//")
@@ -28,5 +33,3 @@
2833
)
2934

3035
script = ConvertToNode(ast.Script)(Group(ZeroOrMore(global_statement)))
31-
32-
script.ignore(comment)

pynescript/ast/parser/grammars/statement.py

+11
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
ASSIGN,
2121
)
2222
from pynescript.ast.parser.parser_elements import (
23+
ResultNameableForward as Forward,
2324
ConvertToNode,
2425
)
2526

@@ -29,6 +30,7 @@
2930
local_body = Forward()
3031

3132
common_statement = assignment | structure | expression
33+
common_statement.set_name("common_statement")
3234

3335
import_statement = (
3436
Suppress(IMPORT)
@@ -40,6 +42,7 @@
4042
+ Suppress(AS)
4143
+ IDENTIFIER
4244
)
45+
import_statement.set_name("import_statement")
4346

4447
default_value = expression
4548

@@ -65,6 +68,7 @@
6568
+ Suppress(RIGHT_DOUBLE_ARROW)
6669
+ local_body("body")
6770
)
71+
function_declaration.set_name("function_declaration")
6872

6973
global_only_statement = import_statement | function_declaration
7074

@@ -78,9 +82,15 @@
7882
global_atomic_statement = global_only_statement | common_statement
7983
local_atomic_statement = local_only_statement | common_statement
8084

85+
global_atomic_statement.set_name("global_atomic_statement")
86+
local_atomic_statement.set_name("local_atomic_statement")
87+
8188
global_statement = delimited_list(global_atomic_statement, COMMA)
8289
local_statement = delimited_list(local_atomic_statement, COMMA)
8390

91+
global_statement.set_name("global_statement")
92+
local_statement.set_name("local_statement")
93+
8494
statement = (
8595
break_statement
8696
| continue_statement
@@ -90,3 +100,4 @@
90100
| structure
91101
| expression
92102
)
103+
statement.set_name("statement")

0 commit comments

Comments
 (0)