首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >grako规则优先问题

grako规则优先问题
EN

Stack Overflow用户
提问于 2014-09-24 12:05:23
回答 2查看 737关注 0票数 3

我正在重做最初构建在Perl上的一种小型语言(请参阅github上的Chessa#),但在应用语义时遇到了许多问题。

这是语法

代码语言:javascript
复制
(* 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),但我不明白问题在哪里。

例如,4d6停止解析器,因为它被解释为4 d6,其中d6是一个标识符。应该发生的是,它被解释为4 d 6d是一个运算符。在LL解析器中,情况确实如此。

一个可能的解决方案是不允许d开始一个标识符,但这将不允许像drop这样的函数被命名为标识符。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-09-25 21:14:01

您的示例的问题是,默认情况下,Grako启用了nameguard特性,而且当--no-nameguard领先时,不允许只解析--no-nameguard

若要禁用该特性,请实例化您自己的Buffer并将其传递给生成的解析器的实例:

代码语言:javascript
复制
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命令行选项。

票数 1
EN

Stack Overflow用户

发布于 2014-09-26 16:44:56

在Perl中,您可以使用Marpa,这是一种通用的BNF解析器,它支持带关联(以及更多)的广义优先级。

代码语言:javascript
复制
:start ::= Script
Script ::= Expression+ separator => comma
comma ~ [,]
Expression ::=
    Number bless => primary
    | '(' Expression ')' bless => paren assoc => group
   || Expression '**' Expression bless => exponentiate assoc => right
   || Expression '*' Expression bless => multiply
    | Expression '/' Expression bless => divide
   || Expression '+' Expression bless => add
    | Expression '-' Expression bless => subtract

完整的示例是这里。至于编程语言,有一个基于Marpa的C解析器

希望这能有所帮助。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26016475

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档