语法快乐解析器意义
syntax happy parser meaning
我在快乐的解析器中有这个语法部分,在快乐的官方网站上给出,但我需要对括号中规则的含义进行更深入的解释。这是令牌定义
%token
let { TokenLet }
in { TokenIn }
int { TokenInt $$ }
var { TokenVar $$ }
'=' { TokenEq }
'+' { TokenPlus }
'-' { TokenMinus }
'*' { TokenTimes }
'/' { TokenDiv }
'(' { TokenOB }
')' { TokenCB }
这里是语法部分
Exp : let var '=' Exp in Exp { Let }
| Exp1 { Exp1 }
Exp1 : Exp1 '+' Term { Plus }
| Exp1 '-' Term { Minus }
| Term { Term }
Term : Term '*' Factor { Times }
| Term '/' Factor { Div }
| Factor { Factor }
Factor
: int { Int }
| var { Var }
| '(' Exp ')' { Brack }
我的理解是,在文件下面定义的词法分析器应该只生成定义类型的标记,然后使用语法构建解析树。但是“{Let $2 $4 $6}”到底是什么意思呢?我知道 $2 指的是第二个规则参数等等,但如果有人能给我一个 "human read version" 的规则,我会非常高兴。希望我已经清楚了。
提前致谢。
这一行是创建(解析)产生式的一条规则Exp
:
Exp : let var '=' Exp in Exp { Let }
对应规则:
if you see "let" ()
followed by a variable name ()
followed by "=" ()
followed by an Exp ()
followed by "in" ()
followed by another Exp ()
然后 return 值 Let
。 $n
参数将替换为每个子制作的值。因此,如果匹配此规则,将调用 Let
函数(可能是一些数据构造函数):
var
令牌的值作为第一个参数,
- 第一个
Exp
解析为第二个参数($4)
- 并且第二个解析
Exp
($6) 作为第三个参数。
我相信 var
标记的值是变量名。
在 %token
部分中,左栏是语法中其他地方使用的标记名称,右栏是可以在 case
语句中使用的模式。你看到的地方 $$
Happy 将替换它自己的变量。因此,如果生成的解析器在某个时候期望一个整数,那么 Happy 将有一个 case 语句,其模式包括 TokenInt v1234
,其中 v1234
位是由 Happy 创建的变量名称。
"Let"是被识别语法表达式的构造函数。如果您在示例页面中往下看一点,您会看到
data Exp
= Let String Exp Exp
| Exp1 Exp1
deriving Show
所以 Let
构造函数接受一个字符串和两个子表达式('Exp' 类型)。如果您查看语法,您会发现 let
规则中有六个元素。第一个只是常量字符串 "let"。生成的解析器使用它来确定它正在查看 "let" 子句,但生成的解析树不需要它。所以 </code> 没有出现。 <code>Let
构造函数的第一个参数必须是被绑定变量的名称,这是语法规则中的第二项。因此这是 </code>。其他的是两个子表达式,按相同的逻辑是<code>
和
。这两个表达式都可以是任意复杂的表达式:Happy 找出它们的开始和结束位置,并按照构成表达式的其他规则解析它们。
我在快乐的解析器中有这个语法部分,在快乐的官方网站上给出,但我需要对括号中规则的含义进行更深入的解释。这是令牌定义
%token
let { TokenLet }
in { TokenIn }
int { TokenInt $$ }
var { TokenVar $$ }
'=' { TokenEq }
'+' { TokenPlus }
'-' { TokenMinus }
'*' { TokenTimes }
'/' { TokenDiv }
'(' { TokenOB }
')' { TokenCB }
这里是语法部分
Exp : let var '=' Exp in Exp { Let }
| Exp1 { Exp1 }
Exp1 : Exp1 '+' Term { Plus }
| Exp1 '-' Term { Minus }
| Term { Term }
Term : Term '*' Factor { Times }
| Term '/' Factor { Div }
| Factor { Factor }
Factor
: int { Int }
| var { Var }
| '(' Exp ')' { Brack }
我的理解是,在文件下面定义的词法分析器应该只生成定义类型的标记,然后使用语法构建解析树。但是“{Let $2 $4 $6}”到底是什么意思呢?我知道 $2 指的是第二个规则参数等等,但如果有人能给我一个 "human read version" 的规则,我会非常高兴。希望我已经清楚了。
提前致谢。
这一行是创建(解析)产生式的一条规则Exp
:
Exp : let var '=' Exp in Exp { Let }
对应规则:
if you see "let" ()
followed by a variable name ()
followed by "=" ()
followed by an Exp ()
followed by "in" ()
followed by another Exp ()
然后 return 值 Let
。 $n
参数将替换为每个子制作的值。因此,如果匹配此规则,将调用 Let
函数(可能是一些数据构造函数):
var
令牌的值作为第一个参数,- 第一个
Exp
解析为第二个参数($4) - 并且第二个解析
Exp
($6) 作为第三个参数。
我相信 var
标记的值是变量名。
在 %token
部分中,左栏是语法中其他地方使用的标记名称,右栏是可以在 case
语句中使用的模式。你看到的地方 $$
Happy 将替换它自己的变量。因此,如果生成的解析器在某个时候期望一个整数,那么 Happy 将有一个 case 语句,其模式包括 TokenInt v1234
,其中 v1234
位是由 Happy 创建的变量名称。
"Let"是被识别语法表达式的构造函数。如果您在示例页面中往下看一点,您会看到
data Exp
= Let String Exp Exp
| Exp1 Exp1
deriving Show
所以 Let
构造函数接受一个字符串和两个子表达式('Exp' 类型)。如果您查看语法,您会发现 let
规则中有六个元素。第一个只是常量字符串 "let"。生成的解析器使用它来确定它正在查看 "let" 子句,但生成的解析树不需要它。所以 </code> 没有出现。 <code>Let
构造函数的第一个参数必须是被绑定变量的名称,这是语法规则中的第二项。因此这是 </code>。其他的是两个子表达式,按相同的逻辑是<code>
和。这两个表达式都可以是任意复杂的表达式:Happy 找出它们的开始和结束位置,并按照构成表达式的其他规则解析它们。