@@ -68,7 +68,7 @@ impl Production {
68
68
stack : bool ,
69
69
link_map : & HashMap < String , String > ,
70
70
) -> Diagram < Box < dyn Node > > {
71
- let n = self . expression . render_railroad ( stack, link_map) ;
71
+ let n = self . expression . render_railroad ( stack, link_map, false ) ;
72
72
let seq: Sequence < Box < dyn Node > > =
73
73
Sequence :: new ( vec ! [ Box :: new( SimpleStart ) , n. unwrap( ) , Box :: new( SimpleEnd ) ] ) ;
74
74
let vert = VerticalGrid :: < Box < dyn Node > > :: new ( vec ! [
@@ -85,28 +85,34 @@ impl Expression {
85
85
& self ,
86
86
stack : bool ,
87
87
link_map : & HashMap < String , String > ,
88
+ reverse : bool ,
88
89
) -> Option < Box < dyn Node > > {
89
90
let n: Box < dyn Node > = match & self . kind {
90
91
ExpressionKind :: Grouped ( e) => {
91
92
// I don't think this needs anything special. The grouped
92
93
// expression is usually an Alt or Optional or something like
93
94
// that which ends up as a distinct railroad node. But I'm not
94
95
// sure.
95
- e. render_railroad ( stack, link_map) ?
96
+ e. render_railroad ( stack, link_map, reverse ) ?
96
97
}
97
98
ExpressionKind :: Alt ( es) => {
98
99
let choices: Vec < _ > = es
99
100
. iter ( )
100
- . map ( |e| e. render_railroad ( stack, link_map) )
101
+ . map ( |e| e. render_railroad ( stack, link_map, reverse ) )
101
102
. filter_map ( |n| n)
102
103
. collect ( ) ;
103
104
Box :: new ( Choice :: < Box < dyn Node > > :: new ( choices) )
104
105
}
105
106
ExpressionKind :: Sequence ( es) => {
106
- let make_seq = |es : & [ Expression ] | {
107
+ let mut es: Vec < _ > = es. iter ( ) . collect ( ) ;
108
+ // For reversing, see ::Repeat for an explanation.
109
+ if reverse {
110
+ es. reverse ( ) ;
111
+ }
112
+ let make_seq = |es : & [ & Expression ] | {
107
113
let seq: Vec < _ > = es
108
114
. iter ( )
109
- . map ( |e| e. render_railroad ( stack, link_map) )
115
+ . map ( |e| e. render_railroad ( stack, link_map, reverse ) )
110
116
. filter_map ( |n| n)
111
117
. collect ( ) ;
112
118
let seq: Sequence < Box < dyn Node > > = Sequence :: new ( seq) ;
@@ -142,35 +148,38 @@ impl Expression {
142
148
Box :: new ( Stack :: new ( breaks) )
143
149
}
144
150
} else {
145
- make_seq ( es)
151
+ make_seq ( & es)
146
152
}
147
153
}
148
154
ExpressionKind :: Optional ( e) => {
149
- let n = e. render_railroad ( stack, link_map) ?;
155
+ let n = e. render_railroad ( stack, link_map, reverse ) ?;
150
156
Box :: new ( Optional :: new ( n) )
151
157
}
152
158
ExpressionKind :: Repeat ( e) => {
153
- let n = e. render_railroad ( stack, link_map) ?;
159
+ // Railroad renders everything in the opposite order. However,
160
+ // our grammar is not written that way, so we need to undo the
161
+ // reversal.
162
+ let n = e. render_railroad ( stack, link_map, !reverse) ?;
154
163
Box :: new ( Repeat :: new ( railroad:: Empty , n) )
155
164
}
156
165
ExpressionKind :: RepeatNonGreedy ( e) => {
157
- let n = e. render_railroad ( stack, link_map) ?;
166
+ let n = e. render_railroad ( stack, link_map, !reverse ) ?;
158
167
let r = Box :: new ( Repeat :: new ( railroad:: Empty , n) ) ;
159
168
let lbox = LabeledBox :: new ( r, Comment :: new ( "non-greedy" . to_string ( ) ) ) ;
160
169
Box :: new ( lbox)
161
170
}
162
171
ExpressionKind :: RepeatPlus ( e) => {
163
- let n = e. render_railroad ( stack, link_map) ?;
172
+ let n = e. render_railroad ( stack, link_map, reverse ) ?;
164
173
Box :: new ( Repeat :: new ( n, railroad:: Empty ) )
165
174
}
166
175
ExpressionKind :: RepeatPlusNonGreedy ( e) => {
167
- let n = e. render_railroad ( stack, link_map) ?;
176
+ let n = e. render_railroad ( stack, link_map, reverse ) ?;
168
177
let r = Repeat :: new ( n, railroad:: Empty ) ;
169
178
let lbox = LabeledBox :: new ( r, Comment :: new ( "non-greedy" . to_string ( ) ) ) ;
170
179
Box :: new ( lbox)
171
180
}
172
181
ExpressionKind :: RepeatRange ( e, a, b) => {
173
- let n = e. render_railroad ( stack, link_map) ?;
182
+ let n = e. render_railroad ( stack, link_map, reverse ) ?;
174
183
let cmt = match ( a, b) {
175
184
( Some ( a) , Some ( b) ) => format ! ( "repeat between {a} and {b} times" ) ,
176
185
( None , Some ( b) ) => format ! ( "repeat at most {b} times" ) ,
@@ -189,7 +198,7 @@ impl Expression {
189
198
Box :: new ( Choice :: < Box < dyn Node > > :: new ( ns) )
190
199
}
191
200
ExpressionKind :: NegExpression ( e) => {
192
- let n = e. render_railroad ( stack, link_map) ?;
201
+ let n = e. render_railroad ( stack, link_map, reverse ) ?;
193
202
let lbox = LabeledBox :: new ( n, Comment :: new ( "any character except" . to_string ( ) ) ) ;
194
203
Box :: new ( lbox)
195
204
}
0 commit comments