我使用Parse :: RecDescent定义了以下语法
my $grammar = q{
top : operand equal value { print $item{value} }
operand: /\w+/
equal : /\=/
value : { my $value = extract_quotelike($text) ;$return =$value;}
};
我希望它处理以下情况:
X = 2->应该打印2
X =“ 2”->应该打印2
x ='2'->应该打印2
但是上面的语法提供了不同的结果:
对于x = 2,它无法解析
对于x =“ 2”->打印“ 2”
对于x ='2'->它推入'2'
任何将上述语法更改为在上述所有3种情况下均打印2的想法,即删除引号
答案 0 :(得分:2)
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__
根据需要调整字符串文字的定义(但请记住同时调整规则和dequote
)。
运行build_parser.pl
将生成Parser.pm
,可按如下方式使用它:
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') ));