in reply to Re^3: Help with Parse::RecDescent grammar
in thread Help with Parse::RecDescent grammar

Hello, Thanks for the reply.

Does the  /\Z/ match the #f at the end of the DATA?

Here is the output I get:

$VAR1 = [ 'dbSetCellPortTypes', '/opt/mylib/s956M', '*', '(' ];

Looks like the portLists are not being returned correctly...could this have something to do with the #f? Thanks,

Frank

Replies are listed 'Best First'.
Re^5: Help with Parse::RecDescent grammar
by ikegami (Patriarch) on Dec 12, 2006 at 20:20 UTC

    Here is the output I get:

    Oops, portList should be

    portList : "'" "(" record(s?) ")" { $item[3] }

    I made a minor change (undid my mergine of ' and ( into a single token) right before posting without testing.

    By the way, "'(" means no whitespace (as defined by <skip>, \s* by default) is allwed between the two characters, while "'" "(" means whitespace IS allowed.

    could this have something to do with the #f?

    Is that a commment? I treated it as a comment, so I used <skip> to handle it.

    If it's not a comment, what is it? An unquoted string? Does it support any kind of escapes?

      The  #f is a boolean value used to tell a EDA program how to update the corresponding data. The #f, tells the system to only update new data, whereas #t tells the system to overwrite all previous data. This always comes after the last ")" and is never quoted. Im not sure what you would call this?

      I changed the code to return $item[3] and I now get a nice looking structure. One thing I notice is when I try to parse multiple entries, I get the bad netlist error again. For example:

      Consider my data is the following:

      my $text = <<'_EOT_'; dbSetCellPortTypes "/opt/mylib/s956M" "blahblah" '( ("gnd!" "Inout" "Ground" ) ("vint!" "Inout" "Power" ) ) #f dbSetCellPortTypes "/opt/mylib/s956M" "newCell" '( ("gnd!" "Inout" "Ground" ) ("vint!" "Inout" "Power" ) ) #f _EOT_

      I've tried changing the parse rule to the following as well:

      parse : <skip:'(?:\s*(?:#[^\n]*)?)'> portDef(s?) /\Z/ { $item[2] }

      What is the /\Z/ doing actually?

      Thanks,

      Frank

        The #f is a boolean value

        ah!

        my $grammar = <<'_EOGRAMMAR_'; { # These apply to code in those block and all actions. use strict; use warnings; my %escapes = ( n => "\n", ); sub dequote_double { for (my $s = @_ ? $_[0] : $_) { s/^"//g; s/"$//g; s/\\(.)/$escapes{$1} || $1/eg; return $_; } } } parse : portDef(s?) /\Z/ { $item[1] } portDef : "dbSetCellPortTypes" QSTRING QSTRING portList BOOL { [ @item[1..5] ] } portList : "'" "(" record(s?) ")" { $item[3] } record : "(" QSTRING(s?) ")" { $item[2] } QSTRING : /"(?:[^"\\]|\\.)*"/ { dequote_double($item[1]) } BOOL : /#[tf]\b/ _EOGRAMMAR_

        One thing I notice is when I try to parse multiple entries, I get the bad netlist error again.

        Copy and paste error. There was a missing *.

        What is the /\Z/ doing actually?

        /\Z/ means makes sure we're at end of file. Without it, extra garbage at the end will just get ignored. It's worst that it sounds, because anything the parser doesn't understand is garbage, includes malformed dbSetCellPortTypes records. If there were a syntax error halfway through the file, you'd silently ignore everything after the syntax error if the /\Z/ is missing.