Haskell错误字符'/ r'的字符串/字符文字中的词法错误

时间:2014-12-06 08:26:16

标签: haskell

您好我试图编写一个将markdown转换为HTML的程序,我知道有Pandoc,但我的项目是手动编写的。我已经完成了或至少我认为我这样做但是我得到以下错误Haskell错误lexical error in string/character literal at character ' \r'我不知道指的是什么,指出它的任何帮助都会很棒。谢谢所以更新:我用misc符号更改了一些内容,我现在得到的错误是hs.38:17: Not in scope 'str',当我正在处理它已反复指向第38行的事情时,我无法弄清楚问题是什么因为它忽略了前一个函数中的相同内容

module Main
(
convertToHTML,
convertSpecialChar,
main
) where

import System.Environment (getArgs)
import System.IO
import Data.Char
import Data.List
import Data.List.Split

eof = "</body></html>"

convertToHTML :: String -> String
convertToHTML x = specialTags $ headings $ endings $ beginnings $ replace "---"<hr>" x


convertSpecialChar :: String -> String
ConvertSpecialChar x = (convertLessThan $ convertAmpersand $ convertGreaterThan x)++eof
    where
        convertLessThan str = concat [if c =='<' then '&lt" else [c] | c <- str]
        convertAmpersand str = concat [if c == '&' then "&amp" else [c] | c <- str]
        convertGreaterThan str = concat [if c =='>' then "&gt" else [c] | c <- str]

beginnings :: String -> String
beginnings str = unwords $ map tag ch
   where
   tag x
    | isPrefixOf "**" x = "<strong>" ++ (tail $ tail x)
    | isPrefixOf "__" x = "<strong>" ++ (tail $ tail x)
    | isPrefixOf  "_" x = "<em>" ++ (tail x)
    | isPrefixOf "*" x = "<em>" ++ (tail x)
    | isPrefixOf  "^" x = "<p>" ++ (tail x)
    | isPrefixOf "---" x = replace "---" "<hr>"
    | otherwise = x
ch =splitOn " " str

replace :: Eq a => [a] -> [a] -> [a] -> [a]
replace old new x = intercalate new (splitOn old x)

endings :: String -> String
endings str = unwords $ map tag ch
   where
       tag x
    | isInfixOf "**" x = replace "**" "</strong>" x
    | isInfixOf "__" x = replace "__" "</strong>" x
    | isInfixOf "_"  x = replace "_" "</em>" x
    | isInfixOf "*" x = replace "*" "</em>" x
    | isInfixOf "^" x = replace "^" "</p>" x
    | isInfixOf "---" x = replace "---" "<hr>" x
    | otherwise = x
   ch = splitOn " " str

headings str = unlines $ map heads (lines str)
   where
      heads x
    | isPrefixOf "######" x = "<h6>" ++ (numTail 6 x) ++ "</h6>"
    | isPrefixOf "#####" x = "<h5>" ++ (numTail 5 x) ++ "</h5>"
    | isPrefixOf "####" x = "<h4>" ++ (numTail 4 x) ++ "</h4>"
    | isPrefixOf "###" x = "<h3>" ++ (numTail 3 x) ++ "</h3>"
    | isPrefixOf "##" x = "<h2>" ++ (tail $ tail x) ++ "</h2>"
    | isPrefixOf "#" x = "<h1>" ++ (tail x) ++ "</h1>"
    | otherwise = x

specialTags str = unlines $ map tags (lines str)
   where
      tags x
    | isPrefixOf "[code]" x = "<blockquote><pre><code>" ++ (numTail 6 x)
    | isSuffixOf "[code]" x = (numInit 6 x) ++ "</code></pre></blockquote>"
    | otherwise = x

numTail :: Int -> String -> String
numTail _ [] = []
numTail 1 str = tail str
numTail x str = tail $ (numTail (x-1) str)

numInit :: Int-> String -> String
numInit _ [] = []
numInit 1 str = init str
numInit x str = init $ (numInit (x-1) str)

main = do
   args <- getArgs
   let (infile,outfile) = (\\(x:y:ys) -> (x,y)) args
   putStrLn $ "Input file: " ++ infile
   putStrLn $ "Output file: " ++ outfile
   contents <- readFile infile
   let contentlines = unlines $ tail $ lines contents
   let title = head $ lines contents
   let header = "<!DOCTYPE html> <head>" ++ "<meta http-equiv = \\"Content-type\\"content=\\"text/html; charset=utf-8\\" />" ++ "<title>" ++title++"</title>" ++"</head><body>"
   writeFile outfile $ convertToHTML $ header ++ convertSpecialChar contentlines 

1 个答案:

答案 0 :(得分:4)

在第17行,您缺少双引号。我想replace "---"<hr>" x应该阅读replace "---" "<hr>" x

您的函数convertToHTML的整个声明将会读取

convertToHTML :: String -> String
convertToHTML x = specialTags $ headings $ endings $ beginnings $ replace "---" "<hr>" x 

那么为什么编译器会抱怨字符'\r'

编译Haskell模块的第一个阶段是词法分析,其中您的程序文本被分解为令牌,然后由解析器处理。在您的情况下,词法分析失败,因为假定新的字符串文字由" x启动。然后它遇到第17行的结尾,没有文字开头正确终止,结尾双引号或字符串文字的任何指示是multiline string literal。由于这是非法的词法语法,因此它抱怨遇到行尾('\r')。

不可否认,如果错误消息明确提到非终止字符串文字,那将会更有帮助。

在任何情况下,具有语法突出显示支持Haskell的编辑器可能早就暗​​示了这个问题。 ;)

压痕

您在变量str不在ch的本地定义范围内时遇到的问题是由于布局造成的。确保ch缩进到与前一个tag定义相同的级别。也就是说,而不是

beginnings :: String -> String
beginnings str = unwords $ map tag ch
   where
   tag x
    | isPrefixOf "**" x = "<strong>" ++ (tail $ tail x)
    | isPrefixOf "__" x = "<strong>" ++ (tail $ tail x)
    | isPrefixOf  "_" x = "<em>" ++ (tail x)
    | isPrefixOf "*" x = "<em>" ++ (tail x)
    | isPrefixOf  "^" x = "<p>" ++ (tail x)
    | isPrefixOf "---" x = replace "---" "<hr>"
    | otherwise = x
ch =splitOn " " str

你应该写点像

beginnings :: String -> String
beginnings str = unwords $ map tag ch
  where
    tag x
      | isPrefixOf "**" x = "<strong>" ++ (tail $ tail x)
      | isPrefixOf "__" x = "<strong>" ++ (tail $ tail x)
      | isPrefixOf  "_" x = "<em>" ++ (tail x)
      | isPrefixOf "*" x = "<em>" ++ (tail x)
      | isPrefixOf  "^" x = "<p>" ++ (tail x)
      | isPrefixOf "---" x = replace "---" "<hr>"
      | otherwise = x
    ch = splitOn " " str

请记住,在Haskell中,the layout of your code matters