语法快乐解析器含义

问题描述:

我有一个快乐的解析器中的这个语法部分,在快乐的官方网站上给出,但我需要对括号中的规则的含义进行更深入的解释。下面是令牌定义语法快乐解析器含义

%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开始和结束数字,并根据构成表达式的其他规则解析它们。

+0

嗨,谢谢所有的答案。例如,在“Plus $ 1 $ 3”行动中,写入$$ = $ 1 + $ 3是不够的? – davideb93

+0

“Plus”是您在Haskell中使用的构造函数,而“+”是您在解析文档的语法中找到的东西。您的“$$ = $ 1 + $ 3”无法将文档中的“+”与分析树中的“Plus”链接起来。 –

这条线是用于创建(解析)生产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的值是变量名。