Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
    Nicholas Blumhardt
    @nblumhardt
    Abstracting the content out into a QuotedValue.XOr(UnquotedValue) seems like it'd make this easier to reason about, @corneliutusnea
    Nicholas Blumhardt
    @nblumhardt
    Untested:
    var name = Parse.IgnoreCase(text).Text;
    var separator = Parse.Char(':');
    var quotedValue = from _ in Parse.Char('\'')
                      from content in Parse.CharExcept('\'').Text()
                      from __ in Parse.Char('\'')
                      select content;
    var unquotedValue = Parse.LetterOrDigit().AtLeastOnce().Text();
    var parser = from n in name
                 from v in quotedValue.XOr(unquotedValue).Optional()
                 select new { n, v };
    Corneliu
    @corneliutusnea
    that looks a lot cleaner than my code :)
    Corneliu
    @corneliutusnea
    @nblumhardt Any idea how to parse strings that contains other escaped strings (like sql)
    `test ``more`` even text`
    my escaping is SQL style with double apostrophes
    I found this https://www.thomaslevesque.com/2017/02/23/easy-text-parsing-in-c-with-sprache/ but seems to use \ for escape which I can't use
    Corneliu
    @corneliutusnea
    ok, I've managed to change that sample - all done :)
    Corneliu
    @corneliutusnea
    Guys, do you know if there is a similar(-ish) library like Sprache for JavaScript ? I'm trying to build a text editor for my language in JS as an extension to Monaco and I think I'll have to process all the text in JS so I avoid roundtrips to the server for the compilation
    Nicholas Blumhardt
    @nblumhardt
    @corneliutusnea none, but looks like there are some interesting options - http://bennu-js.com/ looks pretty complete
    depending on what you want to do (e.g. just a highlighter) you might get away with just writing a tokenizer instead - worth looking into if it's just a quick project
    Corneliu
    @corneliutusnea
    thanks, I was looking at chevrotain atm
    I might just try to write my own using the VS Code Monaco Text Editor as I need it as a language extension for the editor
    Frederik Madsen
    @Zarickan
    Is there any documentation somewhere?
    Perhaps an example on how to parse a basic mathematical equation like "5 + 10 * 2"?
    Michal Pawluk
    @nekomatic
    @corneliutusnea , you may try my parser (inspired also by Sprache) https://github.com/nekomatic/ironik, it is written in Kotlin but it should be compilable to JavaScript - I naven't tried this myself yet... Note it does not yet suppot operator precedence but this may be tricked by using complex rules
    Michal Pawluk
    @nekomatic
    If you are fine with a Lexer based parser you shoudl try ANTLR4, it does generate Javascript code.
    Nicholas Blumhardt
    @nblumhardt
    @Zarickan the second example linked from the README seems close to what you're looking for: https://github.com/sprache/sprache#examples-and-tutorials
    Josh Williams
    @jackjwilliams
    Hellooo, I had some questions regarding Sprache usage. I emailed @nblumhardt awhile back and he gave me some general direction, but I'm having a hard time getting going with Sprache. Would anyone be able to help me?
    Michal Pawluk
    @nekomatic
    @jackjwilliams have a look at https://github.com/IanWold/SpracheJSON. It's an easy to follow sample of Sprache usage.
    Darren R. Starr
    @darrenstarr
        public static class SyslogMessageParser
        {
            public class SyslogHeader
            {
                public int Pri { get; set; }
                public int Version { get; set; }
            }
    
            //    HEADER          = PRI VERSION 
            public static readonly Parser<SyslogHeader> Header =
                from pri in Pri
                from version in Version
                select new SyslogHeader
                {
                    Pri = pri,
                    Version = version
                };
    
            //    PRI = "<" PRIVAL ">"
            public static readonly Parser<int> Pri =
                from leading in Parse.WhiteSpace.Many().Optional()
                from lt in Parse.Char('<')
                from priVal in PriVal
                from gt in Parse.Char('>')
                select priVal;
    
            //    PRIVAL          = 1*3DIGIT ; range 0 .. 191
            public static readonly Parser<int> PriVal =
                Parse.Number
                .Select(x => int.Parse(x));
    
            //    VERSION         = NONZERO-DIGIT 0*2DIGIT
            public static readonly Parser<int> Version =
                from ws in Parse.WhiteSpace.Many().Optional()
                from value in Parse.Number
                select int.Parse(value);
        }
    Can anyone tell me why the above code generates
    Message: System.TypeInitializationException : The type initializer for 'libsyslog.SyslogMessageParser' threw an exception.
    ---- System.ArgumentNullException : Value cannot be null.
    Parameter name: parser
    Nicholas Blumhardt
    @nblumhardt
    @darrenstarr static members are initialized top-to-bottom, so when the Header parser is initialized, the Pri parser will still be null. You can reverse the order of the declarations to fix this, or use Parse.Ref(() => Pri) to lazily reference it.
    Darren R. Starr
    @darrenstarr
    @nblumhardt thanks... that worked... of course... the scary thing is that PriVal and Pri work in the order they are in.... Gotta love it. I'm back to programming C++ where order counts it seems
    Matthew McConnell
    @maca134
    having a little trouble parsing recursive structures. Im 90% there but im missing something, its only parsing a limited number of items
    no errors so kinda dont know were to go lol :(
    Matthew McConnell
    @maca134
    sp is anyone alive in here?
    Martijn Hoekstra
    @martijnhoekstra
    it's a pretty low-traffic room
    Nicholas Blumhardt
    @nblumhardt
    @maca134 try adding a .End() to the very end of your outermost rule; this will cause an error to be returned if the whole input can't be parsed, rather than the default behaivour of just parsing as much as can be matched
    Andrew Shaw Care
    @andrewshawcare
    Is there a way to have a parser error thrown if there is a maximum length constraint?
    It looks like Repeat will throw if there is a minimum length violation, but will just consume up to the maximum length.
    I know this might not make sense for parsing the stream of characters, but wondering if there's any way to address maximum length constraints (in this case, the language puts a maximum length constraint on a variable name)
    I have the following:
    public static readonly Parser<string> VariableName =
          from firstCharacter in Parse.Letter.Or(Parse.Char('_')).Once().Text()
          from remainingCharacters in Parse.LetterOrDigit.Or(Parse.Char('_')).Repeat(minimumCount: 0, maximumCount: 255).Text()
          select $"{firstCharacter}{remainingCharacters}";
    Andrew Shaw Care
    @andrewshawcare
    That "works", but if provided a string that exceeds the length requirements will just chop the stream (which makes sense), but wondering if there's a way to look ahead, realize there are "extra" candidate characters that would have been matched (i.e. the stream has remaining characters that would have been consumed by the current parsing pattern) and to throw if that's the case.
    Andrew Shaw Care
    @andrewshawcare
    Actually, maybe I can get by without throwing. Wanted to fail fast, but will try just truncating as it is for now.
    Chris
    @furesoft
    why is nobody managing the repo right now? no acceptance of pull requests
    Nicholas Blumhardt
    @nblumhardt
    @furesoft the usual reasons :-)
    I can only see one mergeable PR waiting, though, for an unsolicited change with no corresponding issue and no +1 upvotes... Not ideal, it'd be great to get that person a response, but doesn't seem too critical?
    If you have some time to help dig through the issue list and sort out what's what, any and all help would be welcome :+1:
    Chris
    @furesoft
    how can i give a upvote?
    Nicholas Blumhardt
    @nblumhardt
    @furesoft it's the "+ 🙂" icon in the top right of an issue/PR description
    Martijn Hoekstra
    @martijnhoekstra
    When working with IInput, should I advance then get current, or get current then advance?
    Martijn Hoekstra
    @martijnhoekstra
    Also, are there direct ways to construct an IOption value?
    Martijn Hoekstra
    @martijnhoekstra

    I'm now using

    public static IOption<T> Some<T>(T t) => Parse.Return(t).Optional()(new Input("")).Value;
    public static IOption<T> None<T>()  {
      Parser<T> p = ((IInput i) => Result.Failure<T>(i, "failue", Enumerable.Empty<String>()));
      return p.Optional()(new Input("")).Value;
    }

    but that honestly feels a bit silly

    John Zabroski
    @jzabroski
    @nblumhardt How many open source projects have you started? AutoFac, SeriLog, Sprache? I didn't know about Sprache until today. Similarly, I didn't know Jonathan Magnan was behind HtmlAgilityPack and EFPlus. It's pretty amazing how most of the libraries I use come from a very small group of individuals. (Well, we use NLog at work, but I would probably use SeriLog or Its.Log if given a choice...)
    Nicholas Blumhardt
    @nblumhardt
    @jzabroski :-)
    John Zabroski
    @jzabroski

    I actually just found SuperPower, too, after my comment. I kind of wonder if the SuperPower API could be simplified a bit further to make working with tokens nicer.

    However, it's not immediately clear to me why Sprache can't do Tokenization and why SuperPower is needed at all.

    I read through the original motivation of SuperPower - to do tokenization to get better error messages and reduce backtracking due to single-character-at-a-time context.

    Years ago, I also read through Terrance Parr's ANTLR book and tried to grasp a lot of the little computer science concepts like when you can convert a LL(*) grammar to discrete finite automata (I hope I'm remembering this right), so I believe what you were describing in your SuperPower intro blog post is the fundamental limitaitons of LL(1) parsers. It's not the tokenization that kills you, or even the LL(1) model. It's :
    a) Lack of search for ambiguities / aliasing
    b) Need to "thread" through the parser combinators a memo table to reduce to polynomial time the handling of left-recursive production rules

    One thing I believe I recall learning from Parr was the ability to "infer" when a rule could be "rephrased" in such a way to improve performance. For example, if the left recursive production rule is deep in the grammar and not at the top-level, you can greedily consume the entire "forest" from the point at which the rule starts until it certainly ends. Then you can pare the forest down. And this paring probably doesn't need to have the same semantics as the rest of the program, since all you're doing is returning a Context back to the parent Grammar about where you finished reading.