Parse::RecDescent problem regarding rule matching

R

Rui Maciel

I'm a Perl newbie and I've started to look into the Parse::RecDescent
module. Meanwhile I've stumbled on a rule matching problem. I've defined
a couple of rules to be able to deal with two different types of numbers:
integers and decimal fractions with a single decimal place. The problem
is that RecDescent returns false positives by matching the integer rule
on decimal fraction numbers.

As far as I can tell, that could only happen if somehow RecDescent
doesn't make any use of any terminal symbol to specify if the rule really
matches a pattern, which I believe could lead to a lot of false positives.

So, am I missing something or is there no solution to this problem?


Some test code follows and thanks in advance
Rui Maciel


#! /usr/bin/perl -w

use strict;
use Parse::RecDescent;
use Encode;

my $text;
my $grammar = <<'EOG';
startrule: grade1 grade2
{ print "$item[1]\t$item[2]\n";
}
grade1: /\d{1,2}\.\d/
grade2: (/\d{1,2}/|"NA")
EOG

my $parser = new Parse::RecDescent($grammar) or die "Bad grammar!\n";

open(FILE, '-') or die "CRAP ON A STICK!";
while($text = <FILE>)
{
chomp($text);
defined $parser->startrule($text) or print "$text\t<------\n";
}
 
B

Brian Helterlilne

Rui said:
I'm a Perl newbie and I've started to look into the Parse::RecDescent
module. Meanwhile I've stumbled on a rule matching problem. I've defined
a couple of rules to be able to deal with two different types of numbers:
integers and decimal fractions with a single decimal place. The problem
is that RecDescent returns false positives by matching the integer rule
on decimal fraction numbers.

As far as I can tell, that could only happen if somehow RecDescent
doesn't make any use of any terminal symbol to specify if the rule really
matches a pattern, which I believe could lead to a lot of false positives.

So, am I missing something or is there no solution to this problem?


Rules match in the order give. Different productions within a rule are
matched in the order given. RecDescent does not try to match the
"longest" production, only the first match succeeds. This means you
need to order your productions appropriately.
given the following rules, integer would always match before fraction in
the 'number' rule but the 'number2' rule would work correctly - it would
try to match a fraction and if that failed, it would try to match an
integer.

integer: \d{1,2}
fraction: \d{1,2}\.\d

number: integer | fraction
number2: fraction | integer

[test coded snipped]
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,990
Messages
2,570,211
Members
46,796
Latest member
SteveBreed

Latest Threads

Top