Perl Marpa:我可以明确禁止关键字作为标识符吗?

Perl Marpa:我可以明确禁止关键字作为标识符吗?,perl,parsing,marpa,Perl,Parsing,Marpa,我正在Marpa中实现一个新的DSL(来自Regexp::Grammars),我非常满意。我的语言支持一系列一元和二元运算符、具有C样式标识符的对象以及使用熟悉的点表示法的方法调用。例如: foo.AND(5) foo.has(bar==42和baz==23) 我发现了Marpa的语法描述语言提供的功能,并且已经非常依赖它,因此我几乎只有一条G1规则表达式。摘录(许多备选方案,为简洁起见省略了语义动作): 如您所见,我使用的是无扫描接口(SLIF)。我的问题是,这也会解析,例如: foo.A

我正在Marpa中实现一个新的DSL(来自Regexp::Grammars),我非常满意。我的语言支持一系列一元和二元运算符、具有C样式标识符的对象以及使用熟悉的点表示法的方法调用。例如:

foo.AND(5)
foo.has(bar==42和baz==23)

我发现了Marpa的语法描述语言提供的功能,并且已经非常依赖它,因此我几乎只有一条G1规则
表达式
。摘录(许多备选方案,为简洁起见省略了语义动作):

如您所见,我使用的是无扫描接口(SLIF)。我的问题是,这也会解析,例如:

foo.AND(5)
Marpa知道在一个点之后只能有一个标识符,所以它甚至不考虑“代码>和< /代码>可能是关键字的事实。我知道我可以通过单独的词法分析阶段来避免这个问题,该阶段将
明确地识别为关键字,但是这个小小的剪纸不太值得


在SLIF中是否有办法将
标识符
规则仅限于非关键字标识符?

我不知道如何在语法中表达这种东西。您可以为标识符引入一个中间非终端,它将检查条件,不过:

#/usr/bin/perl
使用警告;
严格使用;
使用语法::构造qw{/};
使用Marpa::R2;
my%reserved=map{$\=>1}qw(和);
my$grammar='Marpa::R2::Scanless::G'->新建(
{bless_package=>'main',
source=>\(存储)
:开始::=S
S::=Id
|单侧
Id::=标识符操作=>允许
标识符~IdentifierHeadChar IdentifierBody
IdentifierBody~ IdentifierBodyChar*
IdentifierHeadChar~[a-zA-Z_]
识别基炭~[a-zA-Z0-9_U2;
numlateral~[0-9]+
:放弃~空格
空格[\s]+
__文法__
});
对于我的美元价值(“ABC”、“ABC 42”和“1”){
my$value=$grammar->parse(\$value,'main');
打印$$value,“\n”;
}
分店{
我的(未定义,$id,$arg)=@;
$arg/='null';
返回“$id$arg”;
}
允许转租{
我的(未定义,$id)=@;
如果$Reserved{$id},则为“Reserved关键字$id”;
返回$id
}

您可以使用lexeme优先级来处理这类事情,示例在Marpa::R2测试套件中


基本上,您声明
,。

您所说的“关键字”是什么意思?
assoc
separator
是Marpa行话中的关键词。@choroba,他的意思是如果他定义了一个操作符
,他不希望它被允许作为标识符。我还没有测试过这一点,但你可能想看看“latm”副词。这允许你关闭Marpa关于什么词素是可以接受的知识,而re,在每个词素的基础上——事实上,这使这个词素变得“愚蠢”,因此它会认为一个“AND”是可以的,然后根据您的需要,使解析失败。将这一点与更高的词素优先级结合起来,使“AND”作为运算符优先于“AND”作为标识符。我不知道,但希望它能有所帮助。哎呀,doh![will self Destructure]我尝试了
优先级
latm
词素副词的各种排列,但这是唯一让我的单元测试变绿的东西。错误消息可能没有那么漂亮,但至少它正确地接受了语法。@StefanMajewsky:“否定规则”如果有,那就太好了。谢谢你提出了一个有趣的问题。这个问题的来源可能会更多我可能会考虑为此DSL构建一个自动完成代码编辑器。可以使用操作,但效率不高——读取输入时在评估阶段调用操作。事件更好,请参见本要点--
标识符在输入中遇到时会被拒绝。re--是的,它可以用于访问任何input span,如果需要的话。使用事件发出警告,要求在
12 34-56 78
中的
-
周围使用空格需要更多的工作----它使用有效空格(无
:放弃
)、标记符号和空事件,请参阅