1

我使用 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 的任何想法,即删除引号

4

1 回答 1

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') ));
于 2019-03-27T01:37:37.027 回答