Created
July 24, 2012 09:09
-
-
Save woosley/3168999 to your computer and use it in GitHub Desktop.
parse::recdescent problem
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/perl | |
use strict; | |
use warnings; | |
use Parse::RecDescent; | |
$RD_HINT = 1; | |
$RD_TRACE = 1; | |
my $gramma = <<'EOF'; | |
line: "hello" /\s+/ "world" eof | |
eof: /^\Z/ | |
EOF | |
my $parse = Parse::RecDescent->new($gramma); | |
$parse->line("hello world") or die "bad text"; | |
--------------------------------------------------------------------------------------------------------- | |
Parse::RecDescent: Treating "line:" as a rule declaration | |
Parse::RecDescent: Treating ""hello"" as an interpolated literal terminal | |
Parse::RecDescent: Treating "/\s+/" as a /../ pattern terminal | |
Parse::RecDescent: Treating ""world"" as an interpolated literal terminal | |
Parse::RecDescent: Treating "eof" as a subrule match | |
Parse::RecDescent: Treating "eof:" as a rule declaration | |
Parse::RecDescent: Treating "/^\Z/" as a /../ pattern terminal | |
printing code (12593) to RD_TRACE | |
1| line |Trying rule: [line] | | |
1| line | |"hello world" | |
1| line |Trying production: ['hello' /\s+/ | | |
| |'world' eof] | | |
1| line | | | |
1| line |Trying terminal: ['hello'] | | |
1| line |>>Matched terminal<< (return value: | | |
| |[hello]) | | |
1| line | | | |
1| line | |" world" | |
1| line |Trying terminal: [/\s+/] | | |
1| line |<<Didn't match terminal>> | | |
1| line |<<Didn't match rule>> | | |
bad text at /home/woosley/t.pl line 15. |
Also, your test for success is not correct. Success of a rule is determined by define'd-ness, not truth. Use:
defined $parser->startrule($text) or print "Bad text!\n";
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Parse::RecDescent matches the $skip pattern just prior to trying each terminal match. By default, $skip is set to '[ \t]+'. At the time "world" is matched against the input text, the whitespace between the two words have been stripped off the matching string. The RD_TRACE output does not show skip's happening (in the interest of parsing speed).
If whitespace is significant in your grammar, you must either localize and modify $Parse::RecDescent::skip prior to creating the P::RD parser, or supply a skip: directive in your grammar prior to whitespace becoming important.