使用 FParsec 我将如何解析: line ending in newline <|> a line ending with eof

With FParsec how would I parse: line ending in newline <|> a line ending with eof

我正在解析一个文件并想丢弃文件中我不感兴趣的某些行。我已经能够在所有情况下使用它,除了最后一行是一次性的并且不以换行符结尾。

我尝试构建一个 endOfInput 规则并通过 <|> 将其与 skipLine 规则连接起来。这一切都包裹在 many 中。调整所有内容,当我不尝试某种回溯时,我似乎要么得到 'many succeeds without consuming input...' 错误,要么在 skipLine 规则上失败。

let skipLine = many (noneOf "\n") .>> newline |>> fun x -> [string x]

let endOfInput = many (noneOf "\n") .>> eof |>> fun x -> [string x]

test (many (skipLine <|> endOfInput)) "And here is the next.\nThen the last."

** 在最后一行的 skipLine 解析器上出现此错误

我试过了

let skipLine = many (noneOf "\n") .>>? newline |>> fun x -> [string x]

...和...

let skipLine = many (noneOf "\n") .>> newline |>> fun x -> [string x]

test (many (attempt skipLine <|> endOfInput)) "And here is the next.\nThen the last."

** 这些会产生很多错误

注意:输出函数只是占位符,可以让它们与我的其他规则一起使用。我还没有弄清楚如何格式化输出。 这是我第一次使用 FParsec 并且我是 F# 的新手。

FParsec 实际上有一个内置的解析器,可以完全满足您的需求:skipRestOfLine。它终止于换行符或 eof,就像您正在寻找的那样。

如果您想自己尝试将其作为学习练习来实施,请告诉我,我会尽力帮助您解决问题。但是如果你只是想要一个跳过字符直到行尾的解析器,内置的 skipRestOfLine 正是你所需要的。

这是一种使用 Option 类型解析此类文件的方法, 它将帮助您解析最后带有换行符的文件或跳过中间的空行。我从 post - fparsec key-value parser fails to parse 得到了解决方案。解析一列中包含整数值的文本文件:

module OptionIntParser =
 open FParsec
 open System
 open System.IO
  
 let pCell: Parser<int, unit> = pint32 |>> fun x -> x
 let pSome =   pCell |>> Some
 let pNone =  (restOfLine false) >>% None
 let pLine = (attempt pSome) <|> pNone
 let pAllover = sepBy pLine newline  |>> List.choose id

 let readFile filePath =
    let rr = File.OpenRead(filePath)    
    use reader = new IO.StreamReader(rr)    
    reader.ReadToEnd()

 let testStr = readFile("./test1.txt")

 let runAll s  =
  let res = run pAllover s in
    match res with
     | Success (rows, _, _) ->  rows 
     | Failure (s, _, _) -> []

 let myTest =
   let res = runAll testStr
   res |> List.iter (fun (x) -> Console.WriteLine(x.ToString() ))