gpt4 book ai didi

parsing - Happy 中命题逻辑解析器中的移位/减少冲突

转载 作者:行者123 更新时间:2023-12-02 15:40:28 38 4
gpt4 key购买 nike

我正在基于 this BNF definition 在 happy 上制作一个简单的命题逻辑解析器命题逻辑语法,这是我的代码

{
module FNC where
import Data.Char
import System.IO
}

-- Parser name, token types and error function name:
--
%name parse Prop
%tokentype { Token }
%error { parseError }

-- Token list:
%token
var { TokenVar $$ } -- alphabetic identifier
or { TokenOr }
and { TokenAnd }
'¬' { TokenNot }
"=>" { TokenImp } -- Implication
"<=>" { TokenDImp } --double implication
'(' { TokenOB } --open bracket
')' { TokenCB } --closing bracket
'.' {TokenEnd}

%left "<=>"
%left "=>"
%left or
%left and
%left '¬'
%left '(' ')'
%%

--Grammar
Prop :: {Sentence}
Prop : Sentence '.' {$1}

Sentence :: {Sentence}
Sentence : AtomSent {Atom $1}
| CompSent {Comp $1}

AtomSent :: {AtomSent}
AtomSent : var { Variable $1 }

CompSent :: {CompSent}
CompSent : '(' Sentence ')' { Bracket $2 }
| Sentence Connective Sentence {Bin $2 $1 $3}
| '¬' Sentence {Not $2}

Connective :: {Connective}
Connective : and {And}
| or {Or}
| "=>" {Imp}
| "<=>" {DImp}


{
--Error function
parseError :: [Token] -> a
parseError _ = error ("parseError: Syntax analysis error.\n")

--Data types to represent the grammar
data Sentence
= Atom AtomSent
| Comp CompSent
deriving Show

data AtomSent = Variable String deriving Show

data CompSent
= Bin Connective Sentence Sentence
| Not Sentence
| Bracket Sentence
deriving Show

data Connective
= And
| Or
| Imp
| DImp
deriving Show

--Data types for the tokens
data Token
= TokenVar String
| TokenOr
| TokenAnd
| TokenNot
| TokenImp
| TokenDImp
| TokenOB
| TokenCB
| TokenEnd
deriving Show

--Lexer
lexer :: String -> [Token]
lexer [] = [] -- cadena vacia
lexer (c:cs) -- cadena es un caracter, c, seguido de caracteres, cs.
| isSpace c = lexer cs
| isAlpha c = lexVar (c:cs)
| isSymbol c = lexSym (c:cs)
| c== '(' = TokenOB : lexer cs
| c== ')' = TokenCB : lexer cs
| c== '¬' = TokenNot : lexer cs --solved
| c== '.' = [TokenEnd]
| otherwise = error "lexer: Token invalido"

lexVar cs =
case span isAlpha cs of
("or",rest) -> TokenOr : lexer rest
("and",rest) -> TokenAnd : lexer rest
(var,rest) -> TokenVar var : lexer rest

lexSym cs =
case span isSymbol cs of
("=>",rest) -> TokenImp : lexer rest
("<=>",rest) -> TokenDImp : lexer rest
}

现在,我有两个问题

  1. 出于某种原因,我遇到了 4 个移位/归约冲突,我真的不知道它们可能在哪里,因为我认为优先级可以解决它们(并且我认为我正确地遵循了 BNF 语法)...
  2. (这更像是一个 Haskell 问题)在我的词法分析器函数上,由于某种原因,我在说如何处理 'Ø' 的行上遇到解析错误,如果我删除该行它就可以工作,为什么会这样呢? (此问题已解决)

任何帮助都会很棒。

最佳答案

如果您将 happy 与 -i 一起使用,它将生成一个信息文件。该文件列出了解析器具有的所有状态。它还将列出每个状态的所有可能的转换。您可以使用此信息来确定您是否关心移位/归约冲突。

有关调用 happy 和冲突的信息:

下面是 -i 的一些输出。我已删除除状态 17 之外的所有内容。您需要获取此文件的副本,以便可以正确调试问题。您在这里看到的只是为了帮助讨论一下:

-----------------------------------------------------------------------------
Info file generated by Happy Version 1.18.10 from FNC.y
-----------------------------------------------------------------------------

state 17 contains 4 shift/reduce conflicts.

-----------------------------------------------------------------------------
Grammar
-----------------------------------------------------------------------------
%start_parse -> Prop (0)
Prop -> Sentence '.' (1)
Sentence -> AtomSent (2)
Sentence -> CompSent (3)
AtomSent -> var (4)
CompSent -> '(' Sentence ')' (5)
CompSent -> Sentence Connective Sentence (6)
CompSent -> '¬' Sentence (7)
Connective -> and (8)
Connective -> or (9)
Connective -> "=>" (10)
Connective -> "<=>" (11)

-----------------------------------------------------------------------------
Terminals
-----------------------------------------------------------------------------
var { TokenVar $$ }
or { TokenOr }
and { TokenAnd }
'¬' { TokenNot }
"=>" { TokenImp }
"<=>" { TokenDImp }
'(' { TokenOB }
')' { TokenCB }
'.' { TokenEnd }

-----------------------------------------------------------------------------
Non-terminals
-----------------------------------------------------------------------------
%start_parse rule 0
Prop rule 1
Sentence rules 2, 3
AtomSent rule 4
CompSent rules 5, 6, 7
Connective rules 8, 9, 10, 11

-----------------------------------------------------------------------------
States
-----------------------------------------------------------------------------
State 17

CompSent -> Sentence . Connective Sentence (rule 6)
CompSent -> Sentence Connective Sentence . (rule 6)

or shift, and enter state 12
(reduce using rule 6)

and shift, and enter state 13
(reduce using rule 6)

"=>" shift, and enter state 14
(reduce using rule 6)

"<=>" shift, and enter state 15
(reduce using rule 6)

')' reduce using rule 6
'.' reduce using rule 6

Connective goto state 11

-----------------------------------------------------------------------------
Grammar Totals
-----------------------------------------------------------------------------
Number of rules: 12
Number of terminals: 9
Number of non-terminals: 6
Number of states: 19

该输出基本上表明它在查看连接词时遇到了一些歧义。事实证明,您链接的幻灯片提到了这一点(幻灯片 11),“通过优先级 Ø∧∨⇒⇔ 或括号解决了歧义”。

此时,我建议查看移位/归约冲突以及您所需的优先级,看看您拥有的解析器是否会做正确的事情。如果是这样,那么您可以安全地忽略这些警告。如果没有,您自己还有更多工作要做。

关于parsing - Happy 中命题逻辑解析器中的移位/减少冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16135480/

38 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com