|
36 | 36 | cStyleComment,
|
37 | 37 | lineno,
|
38 | 38 | nums,
|
39 |
| - pyparsing_unicode, |
40 | 39 | restOfLine,
|
| 40 | + unicode, |
41 | 41 | )
|
42 | 42 |
|
43 | 43 | import pydot.core
|
@@ -180,6 +180,28 @@ def push_dbl_quoted(toks: ParseResults) -> str:
|
180 | 180 | return s
|
181 | 181 |
|
182 | 182 |
|
| 183 | +def push_ID(toks: ParseResults) -> str: |
| 184 | + """Join multiple string pieces into a single ID string.""" |
| 185 | + if "concat" in toks: |
| 186 | + out = "".join(s[1:-1] for s in toks.concat) |
| 187 | + return f'"{out}"' |
| 188 | + if "dbl_quoted" in toks: |
| 189 | + return str(toks.dbl_quoted) |
| 190 | + if "ident" in toks: |
| 191 | + return str(toks.ident) |
| 192 | + # (by process of elimination, HTML) |
| 193 | + assert "html" in toks and isinstance(toks.html, str) |
| 194 | + return toks.html |
| 195 | + |
| 196 | + |
| 197 | +def push_node_id(toks: ParseResults) -> str: |
| 198 | + out = [] |
| 199 | + for group in toks: |
| 200 | + assert "id_part" in group |
| 201 | + out.append(str(group.id_part)) |
| 202 | + return ":".join(out) |
| 203 | + |
| 204 | + |
183 | 205 | def push_graph_stmt(toks: ParseResults) -> pydot.core.Subgraph:
|
184 | 206 | g = pydot.core.Subgraph("")
|
185 | 207 | g.obj_dict["show_keyword"] = False
|
@@ -258,25 +280,33 @@ class GraphParser:
|
258 | 280 | edge_ = CaselessLiteral("edge")
|
259 | 281 |
|
260 | 282 | # token definitions
|
261 |
| - identifier = Word( |
262 |
| - pyparsing_unicode.BasicMultilingualPlane.alphanums + "_." |
| 283 | + identifier = Word(unicode.BasicMultilingualPlane.alphanums + "_.") |
| 284 | + |
| 285 | + double_quoted = ( |
| 286 | + QuotedString('"', multiline=True, unquote_results=False, esc_char="\\") |
| 287 | + .set_results_name("dbl_quoted") |
| 288 | + .set_parse_action(push_dbl_quoted) |
263 | 289 | )
|
264 | 290 |
|
265 |
| - double_quoted_string = QuotedString( |
266 |
| - '"', multiline=True, unquote_results=False, esc_char="\\" |
| 291 | + concat_string = DelimitedList( |
| 292 | + double_quoted, delim="+", min=2, combine=False |
267 | 293 | )
|
268 | 294 |
|
269 | 295 | ID = (
|
270 |
| - identifier |
271 |
| - | HTML() |
272 |
| - | double_quoted_string("dbl_quoted").set_parse_action(push_dbl_quoted) |
273 |
| - ) |
| 296 | + concat_string("concat") |
| 297 | + | double_quoted |
| 298 | + | identifier("ident") |
| 299 | + | HTML().set_results_name("html") |
| 300 | + ).set_parse_action(push_ID) |
274 | 301 |
|
275 | 302 | float_number = Combine(Optional(minus) + OneOrMore(Word(nums + ".")))
|
276 | 303 |
|
277 | 304 | righthand_id = float_number | ID
|
278 | 305 |
|
279 |
| - node_id = DelimitedList(ID, delim=":", min=1, max=3, combine=True) |
| 306 | + node_id = DelimitedList( |
| 307 | + Group(ID("id_part")), delim=":", min=1, max=3, combine=False |
| 308 | + ).set_parse_action(push_node_id) |
| 309 | + |
280 | 310 | a_list = OneOrMore(
|
281 | 311 | ID + Optional(equals + righthand_id) + Optional(comma.suppress())
|
282 | 312 | )
|
@@ -363,8 +393,7 @@ def parse_dot_data(s: str) -> list[pydot.core.Dot] | None:
|
363 | 393 | @rtype: `list` of `pydot.core.Dot`
|
364 | 394 | """
|
365 | 395 | try:
|
366 |
| - graphparser = GraphParser.parser |
367 |
| - tokens = graphparser.parse_string(s) |
| 396 | + tokens = GraphParser.parser.parse_string(s) |
368 | 397 | return list(tokens)
|
369 | 398 | except ParseException as err:
|
370 | 399 | print(err.line)
|
|
0 commit comments