@@ -82,124 +82,140 @@ function parse_array(ps::ParseState, isref = false)
82
82
end
83
83
push! (trivia, accept_rsquare (ps))
84
84
if dims > 1
85
- pushfirst! (args, EXPR (Symbol (dims), 0 , 0 , " " ))
86
- return EXPR (:ncat , args, trivia)
85
+ ret = EXPR (:ncat , args, trivia)
86
+ pushfirst! (ret, EXPR (Symbol (dims), 0 , 0 , " " ))
87
+ return ret
87
88
else
88
89
return EXPR (:vect , args, trivia)
89
90
end
90
91
else
91
- first_arg = @nocloser ps :newline @closesquare ps @closer ps :insquare @closer ps :ws @closer ps :wsop @closer ps :comma parse_expression (ps)
92
- if isref && _do_kw_convert (ps, first_arg)
93
- first_arg = _kw_convert (first_arg)
94
- end
92
+ ret = parse_array_outer (ps:: ParseState , trivia, isref)
95
93
96
- if kindof (ps. nt) === Tokens. RSQUARE
97
- if headof (first_arg) === :generator || headof (first_arg) === :flatten
98
- push! (trivia, accept_rsquare (ps))
99
- if isbinarycall (first_arg. args[1 ]) && is_pairarrow (first_arg. args[1 ]. args[2 ])
100
- return EXPR (:dict_comprehension , EXPR[first_arg], trivia)
101
- else
102
- return EXPR (:comprehension , EXPR[first_arg], trivia)
103
- end
104
- elseif kindof (ps. ws) == SemiColonWS
105
- dims = count_semicolons (ps)
106
- push! (args, first_arg)
107
- push! (trivia, accept_rsquare (ps))
108
- if dims > 1
109
- pushfirst! (args, EXPR (Symbol (dims), 0 , 0 , " " ))
110
- return EXPR (:ncat , args, trivia)
111
- else
112
- return EXPR (:vcat , args, trivia)
113
- end
114
- else
115
- push! (args, first_arg)
116
- push! (trivia, accept_rsquare (ps))
117
- ret = EXPR (:vect , args, trivia)
118
- end
119
- elseif iscomma (ps. nt)
120
- push! (args, first_arg)
121
- push! (trivia, accept_comma (ps))
122
- @closesquare ps parse_comma_sep (ps, args, trivia, isref, insert_params_at = 1 )
123
- push! (trivia, accept_rsquare (ps))
124
- return EXPR (:vect , args, trivia)
125
- elseif kindof (ps. ws) == WS || kindof (ps. ws) == SemiColonWS || kindof (ps. ws) == NewLineWS
126
- ps. closer. inref = false
127
- args1 = EXPR[first_arg]
128
- prevpos = position (ps)
129
- ncatdims = 0
130
- while kindof (ps. nt) != = Tokens. RSQUARE && kindof (ps. ws) != = NewLineWS && kindof (ps. ws) != = SemiColonWS && kindof (ps. nt) != = Tokens. ENDMARKER
131
- a = @closesquare ps @closer ps :ws @closer ps :wsop parse_expression (ps)
132
- push! (args1, a)
94
+ pushtotrivia! (ret, accept_rsquare (ps))
95
+ return ret
96
+ end
97
+ return ret
98
+ end
133
99
134
- prevpos = loop_check (ps, prevpos)
135
- end
136
- if kindof (ps. ws) === SemiColonWS
137
- ncatdims = count_semicolons (ps)
138
- end
139
- if kindof (ps. nt) === Tokens. RSQUARE && kindof (ps. ws) != SemiColonWS
140
- push! (trivia, accept_rsquare (ps))
141
- if length (args1) == 1
142
- return EXPR (:vcat , args1, trivia)
143
- else
144
- return EXPR (:hcat , args1, trivia)
145
- end
146
- else
147
- if length (args1) == 1
148
- first_row = args1[1 ]
149
- else
150
- first_row = EXPR (:row , args1, nothing )
151
- end
152
- push! (args, first_row)
153
- prevpos = position (ps)
154
- while kindof (ps. nt) != = Tokens. RSQUARE && kindof (ps. nt) != = Tokens. ENDMARKER
155
- thisdims = 0
156
- first_arg = @closesquare ps @closer ps :ws @closer ps :wsop parse_expression (ps)
157
- args2 = EXPR[first_arg]
158
- prevpos1 = position (ps)
159
- while kindof (ps. nt) != = Tokens. RSQUARE && kindof (ps. ws) != = NewLineWS && kindof (ps. ws) != = SemiColonWS && kindof (ps. nt) != = Tokens. ENDMARKER
160
- a = @closesquare ps @closer ps :ws @closer ps :wsop parse_expression (ps)
100
+ binding_power (ps) =
101
+ if kindof (ps. ws) == Tokens. SEMICOLON_WS
102
+ - count_semicolons (ps)
103
+ elseif kindof (ps. ws) == Tokens. NEWLINE_WS
104
+ - 1
105
+ elseif kindof (ps. ws) == Tokens. WS
106
+ 0
107
+ else
108
+ 1
109
+ end
161
110
162
- push! (args2, a)
163
- prevpos1 = loop_check (ps, prevpos1)
164
- end
165
- if kindof (ps. ws) === SemiColonWS
166
- thisdims = count_semicolons (ps)
167
- if thisdims > ncatdims
168
- ncatdims = thisdims
169
- end
111
+ function parse_array_outer (ps:: ParseState , trivia, isref)
112
+ args_list = EXPR[]
113
+ trivia_list = Any[]
114
+ trivia_bp = Int[]
115
+ min_bp = 0
116
+ is_start = true
117
+ while kindof (ps. nt) != = Tokens. RSQUARE && kindof (ps. nt) != = Tokens. ENDMARKER
118
+ a = @nocloser ps :newline @closesquare ps @closer ps :insquare @closer ps :ws @closer ps :wsop @closer ps :comma parse_expression (ps)
119
+ if is_start
120
+ args = EXPR[]
121
+ if isref && _do_kw_convert (ps, a)
122
+ a = _kw_convert (a)
123
+ end
124
+ if kindof (ps. nt) === Tokens. RSQUARE
125
+ if headof (a) === :generator || headof (a) === :flatten
126
+ if isbinarycall (a. args[1 ]) && is_pairarrow (a. args[1 ]. args[2 ])
127
+ return EXPR (:dict_comprehension , EXPR[a], trivia)
128
+ else
129
+ return EXPR (:comprehension , EXPR[a], trivia)
170
130
end
171
- # if only one entry dont use :row
172
- if length (args2) == 1
173
- push! (args, args2[1 ])
131
+ elseif kindof (ps. ws) == SemiColonWS
132
+ dims = count_semicolons (ps)
133
+ push! (args, a)
134
+ if dims > 1
135
+ ret = EXPR (:ncat , args, trivia)
136
+ pushfirst! (ret, EXPR (Symbol (dims), 0 , 0 , " " ))
137
+ return ret
174
138
else
175
- if thisdims > 1
176
- pushfirst! (args2, EXPR (Symbol (thisdims), 0 , 0 , " " ))
177
- push! (args, EXPR (:nrow , args2, nothing ))
178
- else
179
- push! (args, EXPR (:row , args2, nothing ))
180
- end
139
+ return EXPR (:vcat , args, trivia)
181
140
end
182
- prevpos = loop_check (ps, prevpos)
183
- end
184
- push! (trivia, accept_rsquare (ps))
185
- if ncatdims > 1
186
- pushfirst! (args, EXPR (Symbol (ncatdims), 0 , 0 , " " ))
187
- return EXPR (:ncat , args, trivia)
188
141
else
189
- return EXPR (:vcat , args, trivia)
142
+ push! (args, a)
143
+ return EXPR (:vect , args, trivia)
190
144
end
145
+ elseif iscomma (ps. nt)
146
+ args = EXPR[]
147
+ push! (args, a)
148
+ push! (trivia, accept_comma (ps))
149
+ @closesquare ps parse_comma_sep (ps, args, trivia, isref, insert_params_at = 1 )
150
+ return EXPR (:vect , args, trivia)
191
151
end
152
+ end
153
+ is_start = false
154
+ push! (args_list, a)
155
+ push! (trivia_list, ps. ws)
156
+ bp = binding_power (ps)
157
+ bp < min_bp && (min_bp = bp)
158
+ if bp <= 0
159
+ push! (trivia_bp, bp)
160
+ end
161
+ end
162
+ ret = _process_inner_array (args_list, trivia_bp)
163
+ for t in trivia
164
+ pushtotrivia! (ret, t)
165
+ end
166
+
167
+ if ret. head === :nrow
168
+ if min_bp == 0
169
+ popfirst! (ret. args)
170
+ ret. head = :hcat
171
+ elseif min_bp == - 1
172
+ popfirst! (ret. args)
173
+ ret. head = :vcat
192
174
else
193
- push! (args, first_arg)
194
- push! (trivia, accept_rsquare (ps))
195
- ret = EXPR (:vect , args, trivia)
175
+ ret. head = :ncat
196
176
end
177
+ elseif min_bp == 0
178
+ ret. head = :hcat
179
+ elseif min_bp == - 1
180
+ ret. head = :vcat
197
181
end
182
+
198
183
return ret
199
184
end
200
185
201
- function parse_array_row ()
186
+ function _process_inner_array (args_list, trivia_bp)
187
+ if isempty (trivia_bp)
188
+ return only (args_list)
189
+ end
190
+ bp = minimum (trivia_bp)
191
+ if all (== (bp), trivia_bp)
192
+ if bp == 0
193
+ ret = EXPR (:row , EXPR[], EXPR[])
194
+ else
195
+ ret = EXPR (:nrow , copy (args_list), EXPR[])
196
+ pushfirst! (ret, EXPR (Symbol (- bp), 0 , 0 , " " ))
197
+ end
198
+ end
202
199
200
+ i = 1
201
+ i0 = 1
202
+ if bp == 0
203
+ ret = EXPR (:row , EXPR[], EXPR[])
204
+ else
205
+ ret = EXPR (:nrow , EXPR[], EXPR[])
206
+ push! (ret, EXPR (Symbol (- bp), 0 , 0 , " " ))
207
+ end
208
+ while true
209
+ i = findnext (== (bp), trivia_bp, i0)
210
+ i === nothing && (i = length (args_list))
211
+ inner_args = args_list[i0: i]
212
+ inner_trivia = trivia_bp[i0: (i- 1 )]
213
+ i0 = i + 1
214
+
215
+ push! (ret, _process_inner_array (inner_args, inner_trivia))
216
+ i >= length (args_list) && break
217
+ end
218
+ return ret
203
219
end
204
220
205
221
"""
0 commit comments