perl – Marpa:我可以明确禁止将关键字作为标识符吗?
发布时间:2020-12-15 23:37:15  所属栏目:大数据  来源:网络整理 
            导读:我正在Marpa中实现一个新的DSL(来自 Regexp :: Grammars)我非常满意.我的语言支持一堆一元和二元运算符,带有C风格标识符的对象和使用熟悉的点符号的方法调用.例如: foo.has(bar == 42 AND baz == 23) 我发现了Marpa的语法描述语言提供的prioritized rules功
                
                
                
            | 
                         
 我正在Marpa中实现一个新的DSL(来自 
 Regexp :: Grammars)我非常满意.我的语言支持一堆一元和二元运算符,带有C风格标识符的对象和使用熟悉的点符号的方法调用.例如: 
  
  
foo.has(bar == 42 AND baz == 23) 我发现了Marpa的语法描述语言提供的prioritized rules功能,并且已经开始依赖于它,所以我几乎只有一个G1规则表达式.摘录(为简洁省略了许多替代方案和语义操作): Expression ::=
      NumLiteral
    | '(' Expression ')'             assoc => group
   || Expression ('.') Identifier
   || Expression ('.') Identifier Args
    | Expression ('==') Expression
   || Expression ('AND') Expression
Args     ::= ('(') ArgsList (')')
ArgsList ::= Expression+             separator => [,]
Identifier         ~ IdentifierHeadChar IdentifierBody
IdentifierBody     ~ IdentifierBodyChar*
IdentifierHeadChar ~ [a-zA-Z_]
IdentifierBodyChar ~ [a-zA-Z0-9_]
NumLiteral ~ [0-9]+ 
 如您所见,我正在使用Scanless界面(SLIF).我的问题是,这也解析,例如: foo.AND(5) Marpa知道点后面只能有一个标识符,因此它甚至不考虑AND可能是关键字的事实.我知道我可以通过单独的lexing阶段来明确地将AND识别为关键字来避免这个问题,但是那个小小的剪纸并不值得付出努力. SLIF中是否有办法仅将标识符规则限制为非关键字标识符? 解决方法
 我不知道如何在语法中表达这样的东西.您可以为标识符引入一个中间非终端,它将检查条件,但是: 
  
  
  
        #!/usr/bin/perl
use warnings;
use strict;
use Syntax::Construct qw{ // };
use Marpa::R2;
my %reserved = map { $_ => 1 } qw( AND );
my $grammar = 'Marpa::R2::Scanless::G'->new(
    { bless_package => 'main',source => ( << '__GRAMMAR__'),:default ::= action => store
:start ::= S
S ::= Id
  | Id NumLiteral
Id ::= Identifier action => allowed
Identifier         ~ IdentifierHeadChar IdentifierBody
IdentifierBody     ~ IdentifierBodyChar*
IdentifierHeadChar ~ [a-zA-Z_]
IdentifierBodyChar ~ [a-zA-Z0-9_]
NumLiteral ~ [0-9]+
:discard ~ whitespace
whitespace ~ [s]+
__GRAMMAR__
    });
for my $value ('ABC','ABC 42','AND 1') {
    my $value = $grammar->parse($value,'main');
    print $$value,"n";
}
sub store {
    my (undef,$id,$arg) = @_;
    $arg //= 'null';
    return "$id $arg";
}
sub allowed {
    my (undef,$id) = @_;
    die "Reserved keyword $id" if $reserved{$id};
    return $id
}
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!  | 
                  
