【问题标题】:syntax happy parser meaning语法快乐解析器含义
【发布时间】:2016-05-23 19:55:16
【问题描述】:

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

%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 }

我的理解是,在文件下面定义的词法分析器应该只生成定义类型的标记,然后使用语法构建解析树。但是“{Let $2 $4 $6}”到底是什么意思?我知道 $2 指的是第二个规则参数,依此类推,但如果有人能给我一个规则的“人工阅读版本”,我会非常高兴。希望我已经清楚了。

提前致谢。

【问题讨论】:

    标签: haskell happy


    【解决方案1】:

    %token 部分中,左列是语法中其他地方使用的标记名称,右列是可以在case 语句中使用的模式。你在哪里看到$$ Happy 将替换它自己的变量。因此,如果生成的解析器在某个时刻期待一个整数,那么 Happy 将有一个包含 TokenInt v1234 模式的 case 语句,其中 v1234 位是由 Happy 创建的变量名。

    “Let”是要识别的语法表达式的构造函数。如果您在示例页面中看起来稍低一些,您会看到

    data Exp  
        = Let String Exp Exp
        | Exp1 Exp1
        deriving Show
    

    所以Let 构造函数接受一个字符串和两个子表达式('Exp' 类型)。如果您查看语法,您会发现let 规则中有六个元素。第一个只是常量字符串“let”。生成的解析器使用它来确定它正在查看“let”子句,但生成的解析树不需要它。所以$1 没有出现。相反,Let 构造函数的第一个参数必须是被绑定变量的名称,这是语法规则中的第二项。因此这是$2。其他的是两个子表达式,它们是$4$6,逻辑相同。这两种表达式都可以是任意复杂的表达式:Happy 找出它们的开始和结束位置,并按照构成表达式的其他规则来解析它们。

    【讨论】:

    • 大家好,谢谢大家的回答。例如,在“Plus $1 $3”这个动作中写成 $$ = $1 + $3 还不够吗?
    • “加号”是您在 Haskell 中使用的构造函数,而“+”是您在已解析文档的语法中找到的内容。您的“$$ = $1 + $3”没有将文档中的“+”与解析树中的“Plus”链接起来。
    【解决方案2】:

    这一行是创建(解析)产生式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 标记的值是变量名。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多