Haskell Parsec在语法中考虑了多个表达式的出现 [英] Haskell Parsec accounting for multiple expression occrrences in grammar

查看:130
本文介绍了Haskell Parsec在语法中考虑了多个表达式的出现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在尝试使用以下教程中的详细信息创建解析器



大部分代码直接从教程中复制,只改变了一些名字。

 导入合格的Text.ParserCombinators.Parsec.Token为P 

保留=保留的词法分析器
整数= P.integer的词法分析器
whiteSpace = P.whiteSpace词法分析器
identifier = P.identifier lexer

data Express = Seq [Express]
| ID字符串
|数字整数
| BoolConst Bool
派生(显示)

whileParser :: Parser Express
whileParser = whiteSpace>> expr7

expr7 = seqOfStmt
< |> expr8
$ b $ seqOfStmt =
do list < - (sepBy1 expr8 whiteSpace)
返回$ if length list == 1 then head list else Seq list

expr8 :: Parser Express
expr8 = name
< |>号码
< |> bTerm

名称:: Parser Express
name = fmap ID标识符

编号:: Parser Express
编号= fmap编号整数

bTerm :: Parser Express
bTerm =(保留True>> return(BoolConst True))
< |> (保留False>> return(BoolConst False))

我知道这段代码可能可笑,但我真的想更多地了解我要去哪里错了。

 错误:
输入的解析错误`return'

我相信这个错误与不同的返回类型有关,这很奇怪,我试图在开始的时候使用教程作为我尝试的所有基础。



在此先感谢,

Seán

解决方案

如果您对布局规则不满意,也可以使用不同的语法:

  seqOfStmt = 
do {list
< - (sepBy1 expr8 whiteSpace);
如果长度为
list == 1
则返回$如果其他列表为其他列表;}

无花括号和分号的布局被认为是优越的,原因有两个:


  1. 您不需要打字丑陋;和花括号
  2. 它强制你编写(大部分)可读的代码,不像上面给出的扭曲废话。

规则非常简单:


  1. 不要使用制表符,请使用空格。总是。 (你的编辑可以做到这一点,如果没有,扔掉它,它是crapware。)

  2. 属于一起的东西必须在同一列中对齐。

例如,您有2条属于 do 块的语句,因此它们必须对齐同一列。但是你已经将 return do 对齐,因此编译器将此视为:

  do {list<  -  sepBy1 expr8 whiteSpace; }; 
返回$ ....;

但是您想要的是:

  do {
list< - sepBy1 ....;
返回$ .....; (注意,你可以省略大括号和分号,它将会只要您完整地保留缩进即可。


I have been trying to create a parser using details from the following tutorial

much of the code is copied directly from the tutorial with only a few names changed.

import qualified Text.ParserCombinators.Parsec.Token as P 

reserved   = P.reserved   lexer  
integer    = P.integer    lexer
whiteSpace = P.whiteSpace lexer
identifier = P.identifier lexer

data Express = Seq [Express]
          | ID String
          | Num Integer
          | BoolConst Bool
          deriving (Show)

whileParser :: Parser Express
whileParser = whiteSpace >> expr7

expr7 = seqOfStmt 
    <|> expr8        

seqOfStmt =         
    do list <- (sepBy1 expr8 whiteSpace)
    return $ if length list == 1 then head list else Seq list

expr8 :: Parser Express
expr8 = name 
    <|> number
    <|> bTerm

name :: Parser Express
name = fmap ID identifier

number :: Parser Express
number = fmap Num integer

bTerm :: Parser Express
bTerm = (reserved "True"  >> return (BoolConst True ))
    <|> (reserved "False" >> return (BoolConst False))

I understand that this code might be laughable but I would really like to learn a bit more about where I'm going wrong. I also think that this should provide enough info but if not let me know.

Error:
parse error on input `return'  

I believe that the error has something to do with different return types, which is strange because I have tried to use the tutorial at the start of the post as a basis for all that I am attempting.

Thanks in advance,

Seán

解决方案

If you are not comfortable with the layout rules, you may also use different syntax:

seqOfStmt =         
   do { list 
 <- (sepBy1 expr8 whiteSpace);
       return $ if length 
            list == 1 
        then head list else Seq list;}

The layout without braces and semicolons is regarded superior, though, for 2 reasons:

  1. You don't need to type ugly ; and braces
  2. It forces you to write (mostly) readable code, unlike the distorted crap I gave as example above.

And the rules are really easy:

  1. Don't use tabs, use spaces. Always. (Your editor can do that, if not, throw it away, it's crapware.)
  2. Things that belong together must be aligned in the same column.

For example, you have 2 statements that belong to the do block, hence they must be aligned in the same column. But you have aligned the return with the do, hence the compiler sees this as:

do { list <- sepBy1 expr8 whiteSpace; };
return $  ....;

but what you want is this:

do {
    list <- sepBy1 ....;
    return $ .....;
}

(Note that you can just leave out the braces and the semicolon and it will be ok as long as you leave the indentation intact.

这篇关于Haskell Parsec在语法中考虑了多个表达式的出现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆