Recreate Sprache Csv Parser in Superpower
See original GitHub issueHi @nblumhardt, I have been trying to recreate the Sprache Csv Parser in the test folder over in it’s repository with the Superpower library.
- I have successfully made a simple version to parse my Csv data by row but I wanted to try and recreate the slightly more comprehensive Csv parser from Sprache’s tests but in Superpower.
class Program
{
static void Main(string[] args)
{
var input1 = "a,b,c";
var input2 = "d,e,f" + Environment.NewLine + "a,b,c";
var values = CsvParser.Record.Parse(input1).ToList(); // Works for parsing individual records
Console.WriteLine($"1:{values[0]}, 2:{values[1]}, 3:{values[2]}");
values = CsvParser.Record.Parse(input2).ToList(); // Works just grabbing the first row
Console.WriteLine($"1:{values[0]}, 2:{values[1]}, 3:{values[2]}");
var test = CsvParser.Csv.Parse(input2); // Exception
}
}
public class CsvParser
{
private static readonly TextParser<char> CellSeparator = Character.EqualTo(',');
private static readonly TextParser<char> QuotedCellDelimiter = Character.EqualTo('"');
private static readonly TextParser<char> QuoteEscape = Character.EqualTo('"');
private static TextParser<T> Escaped<T>(TextParser<T> following)
{
return from escape in QuoteEscape
from f in following
select f;
}
private static readonly TextParser<char> QuotedCellContent =
Character.AnyChar.Between(QuotedCellDelimiter, Escaped(QuotedCellDelimiter));
static readonly TextParser<char> LiteralCellContent =
Character.ExceptIn(',', '\r', '\n');
static readonly TextParser<string> QuotedCell =
from open in QuotedCellDelimiter
from content in QuotedCellContent.Try().Many()
from end in QuotedCellDelimiter
select new string(content);
static readonly TextParser<string> NewLine =
Parse.Return(Environment.NewLine);
static readonly TextParser<string> RecordTerminator =
Parse.Return("").AtEnd().Or(
NewLine.AtEnd()).Try().Or(
NewLine);
static readonly TextParser<string> Cell =
QuotedCell.Or(
LiteralCellContent.Many().Select(x => new string(x)));
public static readonly TextParser<IEnumerable<string>> Record =
from leading in Cell
from rest in CellSeparator.Then(_ => Cell).Try().Many()
from terminator in RecordTerminator
select Cons(leading, rest);
static IEnumerable<T> Cons<T>(T head, IEnumerable<T> rest)
{
yield return head;
foreach (var item in rest)
yield return item;
}
public static readonly TextParser<IEnumerable<IEnumerable<string>>> Csv =
Record.Many().AtEnd().Select(x => x.AsEnumerable());
}
I’ve tried following the Sprache Conversion very carefully, but, I cannot get the TextParser<IEnumerable<IEnumerable<string>>> Csv
to work.
Exception:
Exception has occurred: CLR/Superpower.ParseException
An unhandled exception of type 'Superpower.ParseException' occurred in Superpower.dll: 'Many() cannot be applied to zero-width parsers; value ParserConcept.CsvParser+<Cons>d__11`1[System.String] at position 5 (line 1, column 6).'
I have a feeling this is going to be a very simple problem and hoping you can provide some insight. Anything seem wrong to you? I may try and just implement one from scratch instead of converting.
P.S. Thanks for the awesome library, it’s the first combinator I’ve used in C# and falling in love with it. It is making parsing crazy custom files I have much easier and with less code.
Issue Analytics
- State:
- Created 5 years ago
- Comments:7 (4 by maintainers)
Top Results From Across the Web
datalust/superpower: A C# parser construction toolkit with ...
A parser combinator library based on Sprache. Superpower generates friendlier error messages through its support for token-driven parsers.
Read more >Superpower
The filter parser, built with Sprache, is a pretty good use case for it. ... project that's complimentary to Sprache, called Superpower.
Read more >Superpower parser for nested string representation of ...
I'm struggling to understand how recursive parsing works in Superpower. I've studied the blog posts and the examples on github but still ...
Read more >Using the CSV parser to parse CSV text into a JSON object
Using the CSV parser to parse CSV text into a JSON object. In a flow, an event or action can return comma-separated values...
Read more >Superpower: The parser combinator library [Part 2]
It's called “combinator” because it allows you to define a parser by combing existing parsers. In the code above we are creating a...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Closing this as stale since we haven’t looped back to it in a while, but hope all’s going well!
Thanks! 😄
I might have overstated the suggestion to start with token parsers; for simple things that stay simple, text parsers are probably just as good from the perspective of this library. Token parsers are able to make use of more features of Superpower, though, including the nicer error reporting and the easy handling of whitespace and comments. Not a big difference, but probably enough that I’d try starting with a token parser in most cases.
Keen to hear how you go, making the API as usable/approachable as Sprache’s is an ongoing project 😃 Cheers!