Я определил следующий синтаксический анализатор Parsec для анализа файлов csv в таблицу строк, т.е. [[String]]
--A csv parser is some rows seperated, and possibly ended, by a newline charater
csvParser = sepEndBy row (char '\n')
--A row is some cells seperated by a comma character
row = sepBy cell (char ',')
--A cell is either a quoted cell, or a normal cell
cell = qcell <|> ncell
--A normal cell is a series of charaters which are neither , or newline. It might also be an escape character
ncell = many (escChar <|> noneOf ",\n")
--A quoted cell is a " followd by some characters which either are escape charaters or normal characters except for "
qcell = do
char '"'
res <- many (escChar <|> noneOf "\"")
char '"'
return res
--An escape character is anything followed by a \. The \ will be discarded.
escChar = char '\\' >> anyChar
Я действительно не знаю, то ли комментарии слишком много и раздражают, то ли они помогают. Мне, как новичку в Parsec, они бы помогли, поэтому я решил их добавить.
Работает очень хорошо, но есть проблема. Он создает дополнительную пустую строку в таблице. Итак, если у меня, например, есть файл csv с 10 строками (то есть только 10 строк. В конце нет пустых строк*), структура [[String]]
будет иметь длину 11, а последний список String
s будет содержать 1 элемент. Пустой String
(по крайней мере, так он выглядит при печати с помощью show
).
Мой главный вопрос: почему появляется эта дополнительная строка и что я могу сделать, чтобы ее остановить?
Еще одна вещь, которую я заметил, заключается в том, что если после данных в файлах csv есть пустые строки, они закончатся строками, содержащими только пустые String
в таблице. Я думал, что использование sepEndBy
вместо sepBy
приведет к игнорированию лишних пустых строк. Разве это не так?
* После просмотра текстового файла в шестнадцатеричном редакторе кажется, что он действительно заканчивается символом новой строки, хотя vim этого не показывает...