grako的规则优先级问题

grako的规则优先级问题

本文介绍了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功能,并且当d >在前面.

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的规则优先级问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-03 18:07