question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Recreate Sprache Csv Parser in Superpower

See original GitHub issue

Hi @nblumhardt, I have been trying to recreate the Sprache Csv Parser in the test folder over in it’s repository with the Superpower library.

  1. 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:closed
  • Created 5 years ago
  • Comments:7 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
nblumhardtcommented, Jan 8, 2019

Closing this as stale since we haven’t looped back to it in a while, but hope all’s going well!

0reactions
nblumhardtcommented, Oct 26, 2018

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!

Read more comments on GitHub >

github_iconTop 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 >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found