【问题标题】:Parse::RecDescent and GrammarParse::RecDescent 和语法
【发布时间】:2019-03-27 01:05:27
【问题描述】:
我使用 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' -> 它 pring '2'
将上述语法更改为在上述所有 3 种情况下打印 2 的任何想法,即删除引号
【问题讨论】:
标签:
perl
parse-recdescent
【解决方案1】:
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') ));