简体   繁体   English

解析此BNF时如何删除某些术语?

[英]How can I remove some terms when parsing this BNF?

I am attempting to parse a boolean expression using the Happy library. 我正在尝试使用Happy库解析布尔表达式。 The problem is that the result is not as good as I would want it when I introduce parentheses. 问题在于,引入括号后的结果不如我想要的那样好。 I have made the following grammar. 我做了以下语法。

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}

Below is the string to be parsed and the result. 以下是要分析的字符串和结果。

"(computer AND science) OR cs" -> ActOp Or (Term (Brack (ActOp And (Term (Word "computer")) (Word "science")))) (Word "cs")

I would prefer if it was something like the following since it would be easier to interpret: 我希望它像下面这样,因为它更容易解释:

ActOp Or (ActOp And (Word "computer") (Word "science")) (Word "cs")

Edit - Full code 编辑-完整代码

{
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"

Your data types do not have to correspond directly to the grammar rules. 您的数据类型不必直接对应于语法规则。 It is perfectly valid to have the Term nonterminal produce an Expr value. 让Term nonterminal产生Expr值是完全有效的。 For example 例如

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM