Parsing 在解析此BNF时,如何删除一些术语?
我正在尝试使用Happy库解析布尔表达式。问题是,当我引入括号时,结果没有我想要的那么好。我已经做了以下语法Parsing 在解析此BNF时,如何删除一些术语?,parsing,haskell,grammar,bnf,happy,Parsing,Haskell,Grammar,Bnf,Happy,我正在尝试使用Happy库解析布尔表达式。问题是,当我引入括号时,结果没有我想要的那么好。我已经做了以下语法 Query : Expr { $1 } Expr : Expr "OR" Term { ActOp Or $1 $3 } | Expr "AND" Term { ActOp And $1 $3 } | Term
Query : Expr { $1 }
Expr : Expr "OR" Term { ActOp Or $1 $3 }
| Expr "AND" Term { ActOp And $1 $3 }
| Term { Term $1 }
Term : '"' string '"' { QuotedWord $2 }
| string { Word $1 }
| '(' Expr ')' { Brack $2}
下面是要分析的字符串和结果
"(computer AND science) OR cs" -> ActOp Or (Term (Brack (ActOp And (Term (Word "computer")) (Word "science")))) (Word "cs")
我更希望它是如下所示,因为它更容易解释:
ActOp Or (ActOp And (Word "computer") (Word "science")) (Word "cs")
编辑-完整代码
{
module BoolAst where
import Data.Char
import Data.List
}
%name translate
%tokentype { Token }
%token
string { TokenString $$ }
'"' { TokenQuote}
"AND" { TokenAnd }
"OR" { TokenOr }
'(' { TokenOb }
')' { TokenCb }
%%
Query : Expr { $1 }
Expr : Expr "OR" Term { ActOp Or $1 $3 }
| Expr "AND" Term { ActOp And $1 $3 }
| Term { Term $1 }
Term : '"' string '"' { QuotedWord $2 }
| string { Word $1 }
| '(' Expr ')' { Brack $2}
{
happyError :: [Token] -> a
happyError _ = error ("Parse error\n")
type Query
= Expr
data Expr
= ActOp Op Expr Term
| Term Term
deriving Show
data Op
= Or
| And
deriving Show
data Term
= QuotedWord String
| Word String
| Brack Expr
deriving Show
data Token
= TokenQuote
| TokenAnd
| TokenOr
| TokenString String
| TokenOb
| TokenCb
deriving Show
lexer :: String -> [Token]
lexer [] = []
lexer cs
| isPrefixOf "AND" cs = TokenAnd : (lexer $ drop 3 cs)
| isPrefixOf "OR" cs = TokenOr : (lexer $ drop 2 cs)
lexer (c:cs)
| isSpace c = lexer cs
| isAlpha c = lexVar (c:cs)
lexer ('"':cs) = TokenQuote : lexer cs
lexer ('(':cs) = TokenOb : lexer cs
lexer (')':cs) = TokenCb : lexer cs
lexVar cs =
case span isAlphaNum cs of
(var,rest) -> TokenString var : lexer rest
main = print $ translate . lexer $ "computer AND science OR cs"
您的数据类型不必直接对应于语法规则。让术语nonterminal生成Expr值是完全有效的。比如说
data Expr
= ActOp Op Expr Expr
| QuotedWord String
| Word String
deriving Show
...
Expr : Expr "OR" Term { ActOp Or $1 $3 }
| Expr "AND" Term { ActOp And $1 $3 }
| Term { $1 } -- no need to wrap in a constructor
Term : '"' string '"' { QuotedWord $2 }
| string { Word $1 }
| '(' Expr ')' { $2 } -- no need to wrap in a constructor
您的数据类型不必直接对应于语法规则。让术语nonterminal生成Expr值是完全有效的。比如说
data Expr
= ActOp Op Expr Expr
| QuotedWord String
| Word String
deriving Show
...
Expr : Expr "OR" Term { ActOp Or $1 $3 }
| Expr "AND" Term { ActOp And $1 $3 }
| Term { $1 } -- no need to wrap in a constructor
Term : '"' string '"' { QuotedWord $2 }
| string { Word $1 }
| '(' Expr ')' { $2 } -- no need to wrap in a constructor
你能发布包括数据结构定义在内的全部代码吗?我现在已经编辑了原始问题:)你能发布包括数据结构定义在内的全部代码吗?我现在编辑了原始问题:)太棒了!非常感谢你的帮助。太棒了!非常感谢你的帮助。