使用 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() ))
我正在解析一个文件并想丢弃文件中我不感兴趣的某些行。我已经能够在所有情况下使用它,除了最后一行是一次性的并且不以换行符结尾。
我尝试构建一个 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() ))