【问题标题】: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') ));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-03
      • 2011-01-12
      相关资源
      最近更新 更多