我试图扩展作为"F#解析语言入门“一部分的示例语法,以支持一元减号(对于像2*-5这样的表达式)。
我遇到了像Samsdram here这样的障碍
基本上,我扩展了.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发布于 2011-04-24 10:09:26
在不需要%prec的情况下,成功地实现了优先级。稍微修改了一下starter (更有意义的名字)
Prog:
| Expression EOF { $1 }
Expression:
| Additive { $1 }
Additive:
| Multiplicative { $1 }
| Additive PLUS Multiplicative { Plus($1, $3) }
| Additive MINUS Multiplicative { Minus($1, $3) }
Multiplicative:
| Unary { $1 }
| Multiplicative ASTER Unary { Times($1, $3) }
| Multiplicative SLASH Unary { Divide($1, $3) }
Unary:
| Value { $1 }
| MINUS Value { Negative($2) }
Value:
| FLOAT { Value(Float($1)) }
| INT32 { Value(Integer($1)) }
| LPAREN Expression RPAREN { $2 }我还将表达式分组到一个变体中,因为我不喜欢启动器的方式。(穿行起来很尴尬)。
type Value =
| Float of Double
| Integer of Int32
| Expression of Expression
and Expression =
| Value of Value
| Negative of Expression
| Times of Expression * Expression
| Divide of Expression * Expression
| Plus of Expression * Expression
| Minus of Expression * Expression
and Equation =
| Equation of Expression发布于 2011-04-24 19:00:31
摘自我的文章Parsing text with Lex and Yacc (2007年10月)中的代码。
我的优先顺序如下:
%left PLUS MINUS
%left TIMES DIVIDE
%nonassoc prec_uminus
%right POWER
%nonassoc FACTORIALyacc解析代码是:
expr:
| NUM { Num(float_of_string $1) }
| MINUS expr %prec prec_uminus { Neg $2 }
| expr FACTORIAL { Factorial $1 }
| expr PLUS expr { Add($1, $3) }
| expr MINUS expr { Sub($1, $3) }
| expr TIMES expr { Mul($1, $3) }
| expr DIVIDE expr { Div($1, $3) }
| expr POWER expr { Pow($1, $3) }
| OPEN expr CLOSE { $2 }
;看起来是一样的。我不认为问题出在您使用大写的UMINUS而不是我的prec_uminus?
另一种选择是将expr拆分为几个相互递归的部分,每个优先级一个。
https://stackoverflow.com/questions/5767421
复制相似问题