I defined the following grammar using Parse::RecDescent
my $grammar = q{
top : operand equal value { print $item{value} }
operand: /\w+/
equal : /\=/
value : { my $value = extract_quotelike($text) ;$return =$value;}
};
which i wants it to handle the following cases :
X = 2 -> should print 2
X = "2" -> should print 2
x = '2' -> should print 2
but the above grammar provide different results :
for x=2 it fail to parse it
for x="2" -> it print "2"
for x ='2' -> it pring '2'
any idea to change the above grammar to print 2 on all the the 3 above cases , i.e removing the quotes
build_parser.pl
:
use strict;
use warnings;
use Parse::RecDescent qw( );
Parse::RecDescent->Precompile(<<'__EOS__', "Parser");
{
# The code in rules is also covered by these pragmas.
use strict;
use warnings;
sub dequote { substr($_[0], 1, -1) =~ s/\\(.)/$1/srg }
}
start : assign /\Z/ { $item[1] }
assign : lvalue '=' expr { [ 'assign', $item[1], $item[3] ] }
lvalue : IDENT
expr : NUM_LIT { [ 'num_const', $item[1] ] }
| STR_LIT { [ 'str_const', $item[1] ] }
# TOKENS
# ----------------------------------------
IDENT : \w+
NUM_LIT : /[0-9]+/
STR_LIT : /'(?:[^'\\]++|\\.)*+'/s { dequote($item[1]) }
| /"(?:[^"\\]++|\\.)*+"/s { dequote($item[1]) }
__EOS__
Adjust the definition of string literals to your needs (but remember to adjust both the rule and dequote
).
Running build_parser.pl
will generate Parser.pm
, which can be used as follows:
use strict;
use warnings;
use FindBin qw( $RealBin );
use lib $RealBin;
use Data::Dumper qw( Dumper );
use Parser qw( );
my $parser = Parser->new();
print(Dumper( $parser->start('x = 2') ));