Parsing Haskell自定义解析器术语
因此,我正在做一个家庭作业,以填写一些使用自定义Haskell解析器的函数的实现(这只适用于布尔逻辑)。我试图从更高的层次上理解代码的含义或应该做什么。其中一些(标有“(错了?)的)是我实现的,但我认为大部分都是错的,因为我真的不明白发生了什么 Haskell解析con/disjunction ast意味着什么?这应该使解析器中的东西看起来像Parsing Haskell自定义解析器术语,parsing,haskell,Parsing,Haskell,因此,我正在做一个家庭作业,以填写一些使用自定义Haskell解析器的函数的实现(这只适用于布尔逻辑)。我试图从更高的层次上理解代码的含义或应该做什么。其中一些(标有“(错了?)的)是我实现的,但我认为大部分都是错的,因为我真的不明白发生了什么 Haskell解析con/disjunction ast意味着什么?这应该使解析器中的东西看起来像ptu或q,对吗?parseNegation、parseNot和parseParens呢 对不起,范围太广了,我只是不明白它们应该做什么。这是所有相关代码,
ptu或q
,对吗?parseNegation、parseNot和parseParens呢
对不起,范围太广了,我只是不明白它们应该做什么。这是所有相关代码,因此如果您不知道,请给出您的最佳猜测
parseOr implements the single rule D --> C | D. The definition says:
- parse a conjunction AST and name it "p"
- ensure that the next symbol in the stream is T_OR
- parse a disjunction AST and name it "q"
- return the AST "AND p q"
> parseOr = do
> p <- parseConjunction
> eat T_OR
> q <- parseDisjunction
> return (OR p q)
parseDisjunction implements the CFG rules for the D nonterminal:
D --> C | D
D --> C
> parseDisjunction = parseOr <|> parseConjunction
parseAnd implements the rule C --> N & C.
> parseAnd = do
> p <- parseNegation
> eat T_AND
> q <- parseConjunction
> return (AND p q)
parseConjunction should implement the rules for the C nonterminal:
C --> N & C
C --> N
It will probably look almost identical to parseDisjunction, but with different
parsers being combined.
(wrong?)
> parseConjunction = parseAnd <|> parseDisjunction
parseNot should implement the rule N --> !N.
(wrong?)
> parseNot = do
> p <- parseNegation
> eat T_NOT
> return (NOT p)
parseNegation should implement the rules for the N nonterminal:
N --> !N
N --> A
(wrong?)
> parseNegation = parseNot <|> parseConjunction
parseParens should implement the rule A --> (D).
(wrong?)
> parseParens = do
> eat L_PAREN
> p <- parseParens
> eat R_PAREN
> return (p)
这里有一个以一元形式编写的语法,有时称为“一元语法分析器”。这是在Haskell中编写解析器的一种非常常见的方法,并且有许多非常流行的解析器库(例如Parsec)支持以这种方式编写解析器
看起来这一个可能是为这个任务手工编写的,因此您可能有一些样板代码,其中包括一个解析器类型,其中定义了Applicative
、Monad
、和Alternative
实例,以及您在问题中包含的eat
实用函数。您可能还有一个parse
或runParser
帮助函数,用于将其中一个解析函数(例如,parseDisjunction
)实际应用于输入标记列表
一方面,这些解析器如何工作的细节可能相当复杂。但是,在较高的层次上,您可以快速对它们的行为形成直观的理解。事实上,看起来你的教授可能认为仅仅一个例子(parser
加上一些注释)就足以解释它,尽管这可能是乐观的
如果您不清楚,那么这个解析器的使用方式是我们假设布尔表达式的一些人类可读的表示形式,比如字符串:
"A and B or C or not D"
已处理为“令牌”列表:
请注意,我没有在代码中看到t_ATOM
,但我假设您在令牌数据类型的定义中有类似的内容
解析器函数(如parseOr
)的目的是将此令牌列表作为输入,并生成一个抽象语法树(AST)来表示它。在这种情况下,AST将如下所示:
OR (AND (ATOM "A") (ATOM "B")) (OR (ATOM "C") (NOT (ATOM "D")))
因此,当注释说“解析连词AST并将其命名为p
”时,它们指的是以下事实:
p <- parseConjunction
从输入列表的开头开始,将其解析为以下AST,该AST将分配给p
:
(AND (ATOM "A") (ATOM "B"))
现在,用这种风格编写解析器的好处是,您不必显式地操作令牌列表。相反,您可以以一种非常抽象的方式编写解析器,这种方式与语法的形式规则非常匹配。例如,规则:
D -> C | D
可以直接转化为:
parseOr = do
p <- parseConjuction -- this parses the conjunction "C" on the RHS
eat T_OR -- this parses the terminal symbol "|"
q <- parseDisjunction -- this parses the disjunction "D" on the RHS
return (OR p q) -- the produces the AST result of the parse
-- which is the disjunction "D" on the LHS
parseDisjunction =
parseOr -- try to parse "C | D" RHS
<|> parseConjunction -- if that fails, try just the "C" RHS
可译为:
parseOr = do
p <- parseConjuction -- this parses the conjunction "C" on the RHS
eat T_OR -- this parses the terminal symbol "|"
q <- parseDisjunction -- this parses the disjunction "D" on the RHS
return (OR p q) -- the produces the AST result of the parse
-- which is the disjunction "D" on the LHS
parseDisjunction =
parseOr -- try to parse "C | D" RHS
<|> parseConjunction -- if that fails, try just the "C" RHS
解析析取=
解析器——尝试解析“C | D”RHS
parseConjunction——如果失败,请尝试使用“C”RHS
这有帮助吗?这里有一个以一元形式编写的语法,有时称为“一元语法分析器”。这是在Haskell中编写解析器的一种非常常见的方法,并且有许多非常流行的解析器库(例如Parsec)支持以这种方式编写解析器
看起来这一个可能是为这个任务手工编写的,因此您可能有一些样板代码,其中包括一个解析器类型,其中定义了Applicative
、Monad
、和Alternative
实例,以及您在问题中包含的eat
实用函数。您可能还有一个parse
或runParser
帮助函数,用于将其中一个解析函数(例如,parseDisjunction
)实际应用于输入标记列表
一方面,这些解析器如何工作的细节可能相当复杂。但是,在较高的层次上,您可以快速对它们的行为形成直观的理解。事实上,看起来你的教授可能认为仅仅一个例子(parser
加上一些注释)就足以解释它,尽管这可能是乐观的
如果您不清楚,那么这个解析器的使用方式是我们假设布尔表达式的一些人类可读的表示形式,比如字符串:
"A and B or C or not D"
已处理为“令牌”列表:
请注意,我没有在代码中看到t_ATOM
,但我假设您在令牌数据类型的定义中有类似的内容
解析器函数(如parseOr
)的目的是将此令牌列表作为输入,并生成一个抽象语法树(AST)来表示它。在这种情况下,AST将如下所示:
OR (AND (ATOM "A") (ATOM "B")) (OR (ATOM "C") (NOT (ATOM "D")))
因此,当注释说“解析连词AST并将其命名为p
”时,它们指的是以下事实:
p <- parseConjunction
从输入列表的开头开始,将其解析为以下AST,该AST将分配给p
:
(AND (ATOM "A") (ATOM "B"))
现在,用这种风格编写解析器的好处是,您不必显式地操作令牌列表。相反,您可以以一种非常抽象的方式编写解析器,这种方式与语法的形式规则非常匹配。例如,规则:
D -> C | D
可以直接转化为:
parseOr = do
p <- parseConjuction -- this parses the conjunction "C" on the RHS
eat T_OR -- this parses the terminal symbol "|"
q <- parseDisjunction -- this parses the disjunction "D" on the RHS
return (OR p q) -- the produces the AST result of the parse
-- which is the disjunction "D" on the LHS
parseDisjunction =
parseOr -- try to parse "C | D" RHS
<|> parseConjunction -- if that fails, try just the "C" RHS
可译为:
parseOr = do
p <- parseConjuction -- this parses the conjunction "C" on the RHS
eat T_OR -- this parses the terminal symbol "|"
q <- parseDisjunction -- this parses the disjunction "D" on the RHS
return (OR p q) -- the produces the AST result of the parse
-- which is the disjunction "D" on the LHS
parseDisjunction =
parseOr -- try to parse "C | D" RHS
<|> parseConjunction -- if that fails, try just the "C" RHS
解析析取=
解析器——尝试解析“C | D”RHS
parseConjunction——如果失败,请尝试使用“C”RHS
这有帮助吗?所以在我看来,你是在比赛