grako的规则优先级问题 [英] Rule precedence issue with grako
问题描述
我正在还原最初基于Perl构建的一种迷你语言(请参见 github上的Chessa#),但是我在应用语义时遇到了很多问题.
I'm redoing a minilanguage I originally built on Perl (see Chessa# on github), but I'm running into a number of issues when I go to apply semantics.
这是语法:
(* integers *)
DEC = /([1-9][0-9]*|0+)/;
int = /(0b[01]+|0o[0-7]+|0x[0-9a-fA-F]+)/ | DEC;
(* floats *)
pointfloat = /([0-9]*\.[0-9]+|[0-9]+\.)/;
expfloat = /([0-9]+\.?|[0-9]*\.)[eE][+-]?[0-9]+/;
float = pointfloat | expfloat;
list = '[' @+:atom {',' @+:atom}* ']';
(* atoms *)
identifier = /[_a-zA-Z][_a-zA-Z0-9]*/;
symbol = int |
float |
identifier |
list;
(* functions *)
arglist = @+:atom {',' @+:atom}*;
function = identifier '(' [arglist] ')';
atom = function | symbol;
prec8 = '(' atom ')' | atom;
prec7 = [('+' | '-' | '~')] prec8;
prec6 = prec7 ['!'];
prec5 = [prec6 '**'] prec6;
prec4 = [prec5 ('*' | '/' | '%' | 'd')] prec5;
prec3 = [prec4 ('+' | '-')] prec4;
(* <| and >| are rotate-left and rotate-right, respectively. They assume the nearest C size. *)
prec2 = [prec3 ('<<' | '>>' | '<|' | '>|')] prec3;
prec1 = [prec2 ('&' | '|' | '^')] prec2;
expr = prec1 $;
我遇到的问题是,当运算符与以下任何字母数字字符串之间不存在空格时,d
运算符将被拉入标识符规则.虽然语法本身是LL(2),但我不明白这里的问题所在.
The issue I'm running into is that the d
operator is being pulled into the identifier rule when no whitespace exists between the operator and any following alphanumeric strings. While the grammar itself is LL(2), I don't understand where the issue is here.
例如,4d6
停止解析器,因为它被解释为4
d6
,其中d6
是标识符.应该发生的是它被解释为4
d
6
,其中d
是运算符.在LL解析器中,确实是这种情况.
For instance, 4d6
stops the parser because it's being interpreted as 4
d6
, where d6
is an identifier. What should occur is that it's interpreted as 4
d
6
, with the d
being an operator. In an LL parser, this would indeed be the case.
一种可能的解决方案是禁止以d
开头的标识符,但这将不允许诸如drop
之类的功能这样命名.
A possible solution would be to disallow d
from beginning an identifier, but this would disallow functions such as drop
from being named as such.
推荐答案
您的示例的问题是Grako默认启用了nameguard
功能,并且当
The problem with your example is that Grako has the nameguard
feature enabled by default, and that won't allow parsing just the d
when d6
is ahead.
要禁用此功能,请实例化您自己的Buffer
并将其传递给生成的解析器的实例:
To disable the feature, instantiate your own Buffer
and pass it to an instance of the generated parser:
from grako.buffering import Buffer
from myparser import MyParser
# get the text
parser = MyParser()
parser.parse(Buffer(text, nameguard=False), 'expre')
Bitbucket存储库中的Grako提示版本为生成的内容添加了--no-nameguard
命令行选项解析器.
The tip version of Grako in the Bitbucket repository adds a --no-nameguard
command-line option to generated parsers.
这篇关于grako的规则优先级问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!