使用一元减法扩展 Fsyacc 的示例语法
我尝试扩展“F# Parsed Language Starter”中的示例语法来支持一元减号(对于 2 * -5 这样的表达式)。
我遇到了像 Samsdram 这样的块 这里
基本上,我扩展了 . fsy 文件包含如下优先级:
......
%nonassoc UMINUS
....
然后是语法规则,如下所示:
...
Expr:
| MINUS Expr %prec UMINUS { Negative ($2) }
...
还有 AST 的定义:
...
and Expr =
| Negative of Expr
.....
但在尝试解析上述表达式时仍然会出现解析器错误。
有什么想法缺少什么吗?我阅读了 F# 编译器的源代码,并不清楚他们如何解决这个问题,似乎非常相似
编辑
优先级按以下方式排序:
%left ASSIGN
%left AND OR
%left EQ NOTEQ LT LTE GTE GT
%left PLUS MINUS
%left ASTER SLASH
%nonassoc UMINUS
I tried to extend the example grammar that comes as part of the "F# Parsed Language Starter" to support unary minus (for expressions like 2 * -5).
I hit a block like Samsdram here
Basically, I extended the header of the .fsy file to include precedence like so:
......
%nonassoc UMINUS
....
and then the rules of the grammar like so:
...
Expr:
| MINUS Expr %prec UMINUS { Negative ($2) }
...
also, the definition of the AST:
...
and Expr =
| Negative of Expr
.....
but still get a parser error when trying to parse the expression mentioned above.
Any ideas what's missing? I read the source code of the F# compiler and it is not clear how they solve this, seems quite similar
EDIT
The precedences are ordered this way:
%left ASSIGN
%left AND OR
%left EQ NOTEQ LT LTE GTE GT
%left PLUS MINUS
%left ASTER SLASH
%nonassoc UMINUS
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
从我的文章 使用 Lex 和 Yacc 解析文本中获取代码(2007 年 10 月)。
我的优先级看起来像:
yacc 解析代码是:
看起来等效。我不认为问题在于您在大写字母中使用了
UMINUS
而不是在我的例子中使用了prec_uminus
?另一种选择是将
expr
拆分为几个相互递归的部分,每个部分对应一个优先级。Taking code from my article Parsing text with Lex and Yacc (October 2007).
My precedences look like:
and the yacc parsing code is:
Looks equivalent. I don't suppose the problem is your use of
UMINUS
in capitals instead ofprec_uminus
in my case?Another option is to split
expr
into several mutually-recursive parts, one for each precedence level.经过一番尝试,并设法在不需要
%prec
的情况下获得优先级。不过,对启动器进行了一些修改(更有意义的名称),我还将表达式分组为一个变体,因为我不喜欢启动器的方式。 (走过它很尴尬)。
Had a play around and managed to get the precedence working without the need for
%prec
. Modified the starter a little though (more meaningful names)I also grouped the expressions into a single variant, as I didn't like the way the starter done it. (was awkward to walk through it).