语法快乐解析器含义
我有一个快乐的解析器中的这个语法部分,在快乐的官方网站上给出,但我需要对括号中的规则的含义进行更深入的解释。下面是令牌定义语法快乐解析器含义
%token
let { TokenLet }
in { TokenIn }
int { TokenInt $$ }
var { TokenVar $$ }
'=' { TokenEq }
'+' { TokenPlus }
'-' { TokenMinus }
'*' { TokenTimes }
'/' { TokenDiv }
'(' { TokenOB }
')' { TokenCB }
这里的语法部分
Exp : let var '=' Exp in Exp { Let $2 $4 $6 }
| Exp1 { Exp1 $1 }
Exp1 : Exp1 '+' Term { Plus $1 $3 }
| Exp1 '-' Term { Minus $1 $3 }
| Term { Term $1 }
Term : Term '*' Factor { Times $1 $3 }
| Term '/' Factor { Div $1 $3 }
| Factor { Factor $1 }
Factor
: int { Int $1 }
| var { Var $1 }
| '(' Exp ')' { Brack $2 }
我的理解是,词法分析器,文件在下面定义,应该只生产definined类型的令牌,然后生成使用语法解析树。但是什么意思是“{Let $ 2 $ 4 $ 6}”?我知道2美元是指第二个规则论点等等,但如果有人能给我一个“人类阅读版本”的规则,我会非常高兴。希望我已经清楚。
在此先感谢。
在%token
部分中,左列是语法中其他位置使用的标记名称,右边是可在case
语句中使用的模式。你在哪看到$$
Happy会替代自己的变量。因此,如果生成的解析器在某个时间点期待Integer,那么Happy将具有包含TokenInt v1234
的模式的case语句,其中v1234
位是由Happy创建的变量名称。
“Let”是被识别的语法表达式的构造函数。如果您在示例页面看起来有点低,你会看到
data Exp
= Let String Exp Exp
| Exp1 Exp1
deriving Show
所以Let
构造函数需要一个字符串和两个子表达式(类型“精通”的)。如果你看看语法,你可以看到let
规则中有六个元素。第一个是常量字符串“let”。这被生成的解析器用来找出它在查看“let”子句,但生成的解析树不需要它。所以$1
没有出现。相反,构造函数Let
的第一个参数必须是被绑定变量的名称,这是语法规则中的第二项。因此这是$2
。其他的东西是两个子表达式,它们是$4
和$6
。这些都可以是任意复杂的表达式:Happy开始和结束数字,并根据构成表达式的其他规则解析它们。
这条线是用于创建(解析)生产Exp
一个规则:
Exp : let var '=' Exp in Exp { Let $2 $4 $6 }
它对应于规则:
if you see "let" ($1)
followed by a variable name ($2)
followed by "=" ($3)
followed by an Exp ($4)
followed by "in" ($5)
followed by another Exp ($6)
然后返回该值Let $2 $4 $6
。 $n
参数将被替换为每个子生产的值。所以,如果这条规则匹配,则Let
功能(这可能是一些数据的构造函数)将一个名为:
- 的
var
令牌作为第一个参数的值, - 第一
Exp
解析($ 4)作为第二个参数 - 和第二个解析的
Exp
($ 6)作为第三个参数。
我相信这里的令牌var
的值是变量名。
嗨,谢谢所有的答案。例如,在“Plus $ 1 $ 3”行动中,写入$$ = $ 1 + $ 3是不够的? – davideb93
“Plus”是您在Haskell中使用的构造函数,而“+”是您在解析文档的语法中找到的东西。您的“$$ = $ 1 + $ 3”无法将文档中的“+”与分析树中的“Plus”链接起来。 –