@@ -40,40 +40,53 @@ def _scaling_find_blocks(token_stream: Generator[TokenInfo, Any, None]) -> List[
40
40
multiplicative subunits of the original expression.
41
41
42
42
"""
43
+ def _handle_operator (token_ , exponent_context_ , operator_stack_ , result_ ):
44
+ if token_ .string not in _ALLOWED_OPERATORS :
45
+ raise UndefinedUnitError (f"Unrecognized operator: { token_ .string } " )
46
+
47
+ # Figure out what level to append at
48
+ if exponent_context_ or token_ .string in {"**" , "^" , "." , "-" , "+" }:
49
+ # Exponents & unaries do not change context
50
+ result_ [- 1 ].append (token_ )
51
+ else :
52
+ result_ .append ([])
53
+
54
+ # Manage the operator stack
55
+ if token_ .string == '(' :
56
+ operator_stack_ .append (token_ )
57
+ elif token_ .string == ')' :
58
+ while operator_stack_ : # don't worry about enforcing balance
59
+ if operator_stack_ .pop ().string == '(' :
60
+ break # We found token's friend
61
+ elif token_ .string in {"**" , "^" }:
62
+ # A spare to pop so next loop is in exponent context
63
+ operator_stack_ .extend ([token_ ] * 2 )
64
+
65
+ def _handle_name (token_ , exponent_context_ , operator_stack_ , result_ ):
66
+ if exponent_context_ or len (result_ [- 1 ]) == 0 or result_ [- 1 ][- 1 ].type != NAME :
67
+ result_ [- 1 ].append (token_ )
68
+ else : # Break blocks for two units in a row
69
+ result_ .append ([token_ ])
70
+
71
+ def _just_append (token_ , exponent_context_ , operator_stack_ , result_ ):
72
+ result_ [- 1 ].append (token_ )
73
+
74
+ def _do_nothing (token_ , exponent_context_ , operator_stack_ , result_ ):
75
+ pass
76
+
77
+ dispatch = {
78
+ OP : _handle_operator ,
79
+ NAME : _handle_name ,
80
+ NUMBER : _just_append ,
81
+ ERRORTOKEN : _just_append ,
82
+ }
83
+
43
84
result = [[]]
44
85
operator_stack = []
45
86
for token in token_stream :
46
87
exponent_context = any (t .string in {"**" , "^" } for t in operator_stack )
47
- if token .type == OP :
48
- if token .string not in _ALLOWED_OPERATORS :
49
- raise UndefinedUnitError (f"Unrecognized operator: { token .string } " )
50
-
51
- if exponent_context or token .string in {"**" , "^" , "." , "-" , "+" }:
52
- # Exponents & unaries do not change context
53
- result [- 1 ].append (token )
54
- elif token .string not in {}:
55
- result .append ([])
56
-
57
- if token .string == '(' :
58
- operator_stack .append (token )
59
- elif token .string == ')' :
60
- while operator_stack : # don't worry about enforcing balance
61
- if operator_stack .pop ().string == '(' :
62
- break # We found token's friend
63
- elif token .string in {"**" , "^" }:
64
- operator_stack .append (token )
65
- continue # Break flow since next token is in exponent context
66
- elif token .type == NAME :
67
- if exponent_context or len (result [- 1 ]) == 0 or result [- 1 ][- 1 ].type != NAME :
68
- result [- 1 ].append (token )
69
- else : # Break blocks for two units in a row
70
- result .append ([token ])
71
- elif token .type == NUMBER :
72
- result [- 1 ].append (token )
73
- elif token .type == ERRORTOKEN : # Keep non-legal Python symbols like °
74
- result [- 1 ].append (token )
75
- # Drop other tokens, such as EOF
76
-
88
+ method = dispatch .get (token .type , _do_nothing )
89
+ method (token , exponent_context , operator_stack , result )
77
90
if len (operator_stack ) > 0 and operator_stack [- 1 ].string in {"**" , "^" }:
78
91
operator_stack .pop () # Exit context for this exponential
79
92
0 commit comments