pydot icon indicating copy to clipboard operation
pydot copied to clipboard

Parser error for final ';'

Open phwuil opened this issue 4 years ago • 3 comments

Hi all,

Is this an error or an expected behaviour ? Using this code :

import pydot

print(pydot.graph_from_dot_data('''graph G {
  A--B
}''')[0].to_string())

print(pydot.graph_from_dot_data('''graph G {
  A--B;
}''')[0].to_string())

I can see :

image

The comma at line 8 seems to create a node "\n" in the graph ??

Thanks,

PS: windows, python3.10, pydot1.4.2, pyparsing3.0.7

phwuil avatar Dec 04 '21 03:12 phwuil

I've been able to reproduce this bug locally too and it looks like it's an issue caused by the later releases of pyparsing. Using 'graph {\n0 ;\n1 ;\n2 ;\n0 -- 1 ;\n1 -- 2 ;\n2 -- 0 ;\n}\n' as a test string I was able to confirm that running with pyparsing<=3.0.1 pydot parses the string correctly but running with pyparsing>=3.0.3 the extra newline node is added to the parsed output (pyparsing 3.0.2 raised an error trying to parse the string).

mtreinish avatar Dec 05 '21 19:12 mtreinish

I hit this same issue and did a little digging into the root cause. I think the issue is the \n after the edge is matched by the ID (node_id), alphastring_ option, of node_stmt.

Excluding '\n' from alphastring_ seems to fix the issue: alphastring_ = OneOrMore(CharsNotIn(noncomma + " \n"))

If this is the correct fix, '\r' and '\t' should probably be excluded too.

Here is a unit test that can be added to the test suite for this issue:

def test_parse_white_space(self):
    g = pydot.graph_from_dot_data('graph {\n1;\n2;\n2 -- 1;\n}')
    self.assertEqual(2, len(g[0].get_node_list()))

FWIW, I think the reason this doesn't happen with a node at the end of the graph is because the node_stmt includes Optional(semi.suppress()) which matches the ';' and then the Optional(semi.suppress()) in stmt_list skips the '\n'.

huston avatar Mar 19 '22 06:03 huston

just ran into the same problem with a ghost "\n" node before graph closing '}'

            'name': '"\\n"',
            'parent_graph': <pydot.Dot object at 0x7fe11c6eee48>,
            'parent_node_list': None,
            'port': None,
            'sequence': 66,
            'type': 'node'}],

and came up with same fix for alphastring_ to include newline. also had issues with the keywords not being registered as such instead of literals.

teichopsia avatar May 31 '22 07:05 teichopsia

Fixed

lkk7 avatar Dec 16 '23 13:12 lkk7