parsing - Haskell 解析查询 (Parsec)
问题描述
我正在尝试在 Haskell 中创建查询解析器,但不明白我应该如何允许解析器逻辑的不同可选路径。我的尝试:
query :: Parser Query
query = do
-- add more queries
reserved "SELECT"
select <- sequenceOfExpr
reserved "FROM"
table <- identifier
semi
return $ Select select table (BoolConst True)
<|> do
reserved "SELECT"
select <- sequenceOfExpr
reserved "FROM"
table <- identifier
reserved "WHERE"
whereQ <- bExpression
semi
return $ Select select table whereQ
<|> do
reserved "INSERT"
insert <- sequenceOfExpr
reserved "INTO"
table <- identifier
semi
return $ Insert insert table
<|> do
reserved "REMOVE"
reserved "FROM"
table <- identifier
reserved "WHERE"
whereQ <- bExpression
semi
return $ Remove table whereQ
<|> do
reserved "CREATE"
table <- identifier
fields <- sequenceOfExpr
semi
return $ Create table fields
<|> do
reserved "DROP"
table <- identifier
semi
return $ Drop table
在解析与第一个 do stmt 结构相对应的字符串时有效,例如:
"SELECT testField FROM testTable;"
但不是为了其他人。例如解析时:
"SELECT testField FROM testTable WHERE TRUE"
它没有尝试其他路径,而是返回:
unexpected "W"
expecting ";"
换句话说,它似乎只尝试了第一个逻辑。我究竟做错了什么?
任何帮助将非常感激!
解决方案
发生这种情况是因为SELECT FROM
替代方案已成功并返回其结果,解析从未尝试过SELECT FROM WHERE
替代方案。
在这种特定情况下,我只会颠倒他们的顺序:SELECT FROM WHERE
先尝试,如果这不起作用,则回退到SELECT FROM
. 您还需要将其包装在 atry
中,以便解析器回滚到查询的开头。
或者,您可以将WHERE
解析作为解析器的条件部分SELECT FROM
,如下所示:
do
reserved "SELECT"
select <- sequenceOfExpr
reserved "FROM"
table <- identifier
whereQ <- try (reserved "WHERE" *> bExpression) <|> (pure $ BoolConst True)
semi
return $ Select select table whereQ
推荐阅读
- html - CSS 样式不影响子元素(按钮)
- powershell - 只能进行 10 次试运行?
- c# - JTable 不显示排序或分页
- android - 使用 MediaCodec、Media Extractor 和 Media Muxer 在 Android 上进行视频修剪
- r - 导入多个 Excel 工作簿,每个工作簿都包含 R 中的多个工作表
- symfony4 - 使用 VichUploaderBundle 通过 API 上传文件
- terraform - terraform aws-provider 每次尝试“1 添加,1 更改,1 销毁”
- c++ - std::to_chars 在 MacOS / clang 上编译但不链接
- python-3.x - Raspberry Pi 3 B+ (Buster) 无法控制 Dynamixel AX-12A 与 Raspberry Pi 3 B+ (Buster) 与半双工通信
- r - R中Excel的BETADIST()等价函数