Perl 6 - the future is here, just unevenly distributed

IRC log for #marpa, 2015-07-31

| Channels | #marpa index | Today | | Search | Google Search | Plain-Text | summary

All times shown according to UTC.

Time Nick Message
02:39 ronsavage joined #marpa
04:36 purmou joined #marpa
04:36 purmou hi there!
04:38 purmou i'm implementing earley parsing in javascript
04:38 purmou and I got the recognizer functioning really well!
04:38 purmou i'm trying to build parse trees with it now
04:40 purmou but the way I'm doing it doesn't account for precedence properly
04:40 purmou using a math expression grammar
04:40 purmou and given a string with explicitly bound operators -- i.e. (1+2)*3
04:40 purmou it gives the correct parse tree
04:40 purmou but without explicit binding, i.e. 1+2*3
04:40 purmou it just picks up the parse from left to right. so it takes the result of 1+2 and multiplies by 3
05:01 rns hi, you can do a good old term/factor thing, e.g. https://metacpan.org/pod/distribution/Marpa-R2/pod/Marpa_R2.pod#Synopsis or rewrite the grammar internally for precedence as Jeffrey described in https://github.com/jeffreykegler/kollos/blob/master/notes/design/precedenced.md -- this is how it is done in Marpa::R2.
05:28 purmou hey! thanks for the response
05:29 purmou that's kind of the problem. the grammar i'm using has proper precedence
05:29 purmou the way I build the parse tree is by maintaining a "scanned" array and a "tree" array. scanned is just a list of the tokens consumer so far, and trees is a list of partial parse trees
05:30 purmou when I encounter a completed production, I loop backwards through the components of the rule, and pop from the scanned list if the component is terminal, or from the trees list of the component is non-terminal
05:31 purmou the only thing is, it's consuming tokens and building incorrect trees prematurely
05:32 purmou here it is in action if you'd like to check it out: http://jsfiddle.net/purmou/opg92y7h/8/
05:48 rns I see. One thing that comes to mind is that using bit vectors instead of arrays would be arguably easier and more efficient as, e.g. it is in lotsawa -- Marpa algorithm reimplementation in JS by Aria, who is on this channel -- https://github.com/aredridel/lotsawa/blob/master/index.js
06:03 ronsavage joined #marpa
06:10 purmou hmmm, interesting. along with that repo, are there other resources as to bit vectors, and I guess how to utilize them in building a parse tree?
06:13 purmou or, follow up to earlier question...is there a better way to do this *after* the recognizer is done? like, a way to loop through the resultant earley sets and build from that?
06:57 koo7 joined #marpa
06:59 rns Not sure if/when it’s better, but you can build a abstract parse forest and then a parse forest grammar, prune the rules which violate precedence, and then prune inaccessible/unproductive symbols as described in Grune & Jacobs -- https://goo.gl/NsG3LL
06:59 rns I tried that approach in perl using Marpa::R2's abstract parse forests fearure -- https://github.com/rns/MarpaX-ASF-PFG/blob/master/t/01_sum_digit.t
07:04 rns There was also a discussion on this channel -- http://irclog.perlgeek.de/marpa/2014-10-15#i_9513712 -- summed up in http://irclog.perlgeek.de/marpa/2014-10-17#i_9522653
07:21 purmou OOOH, I had a better idea!
07:22 purmou what if I had a list of partial parse trees for each state set?
07:22 purmou then I could pop from the tree list in the completed rule's source set
07:23 rns purmou: re http://irclog.perlgeek.de/marpa/2015-07-31#i_10982616 -- libmarpa source code, Marpa article, see topic of this channel; maintains a list of parsing articles, but I can't recall the URL. And http://hardmath123.github.io/earley.html -- not directly related, but a good read.
07:25 rns Aria maintain a list that is.
07:29 rns re http://irclog.perlgeek.de/marpa/2015-07-31#i_10982917 -- IMHO parse trees are built from the resulting Earley sets after the entire input is read by the recognizer. Aria and Jeffrey would offer you better advice anyway.
07:32 purmou okay, cool. thanks for all the links! I'll come back in the morning and hopefully catch one of them. :D
08:44 pczarn joined #marpa
09:13 pczarn purmou: parse trees can be built during recognition, too.
09:19 pczarn purmou, rns: Aria's list: http://dinhe.net/~aredridel/.notmine/PDFs/Parsing/
09:20 rns pczarn: Thanks!
10:47 purmou yeah, that's what I'm trying to do. I read on several sites about maintaining a reference to the particular entry from which another one originated, and that that would help with generating the parse tree
10:53 purmou my issue is that, say I have 1+2*3
10:53 purmou 1+2 is considered a completed statement, so the tree for that is created
10:54 purmou even though we need to create the tree 2*3 first
10:54 rns hmm, there is even an article on partial parse trees in Earley parsing, of which Aycock himself is an author -- http://link.springer.com/article/10.1007%2Fs00236-009-0107-6 -- paywalled, but a couple of pages readable by clicking on Look Inside.
10:55 purmou haha
10:55 purmou I'm writing a C compiler in Javascript
10:55 purmou and wrote a tokenizer, but wanted to be able to get parse trees out of the tokens to use as an intermediary between source and assembly code
10:56 purmou I asked a question on StackOverflow and someone suggested Earley parsing
10:56 purmou and I swear, it feels like I stumbled into an unexplored world of awesomeness!
10:56 purmou there are so few actually good tutorials on how to build the recognizer it's not even funny
10:58 purmou ahhh rns, that is precisely the paper I need...maybe someone here has a pdf or something. worst case scenario, I'll buy it. I need to know how to determine a "safe" early parse tree haha
11:00 pczarn you have the following rules, `Sum ::= ((Sum '+') Product) | Product`, `Product ::= ((Product '*') Number) | Number`
11:01 rns purmou: :) well, yes. BTW, Jean-Damien Durand wrote a C parser -- https://metacpan.org/pod/MarpaX::Languages::C::AST in Perl using Marpa::R2.
11:02 ronsavage joined #marpa
11:02 pczarn well, 1+2 is just a single partial parse
11:03 purmou right, the problem is I pop off the subtrees for 1 and 2 to make that parse
11:03 purmou and I can't just keep them on there and check for a match of types, because in this grammar 1 evaluates to Sum->Product->Factor->1, but 1+2 also evaluates to Sum->[...]
11:04 pczarn purmou: each of your Earley items should have a pointer to a parse tree node
11:04 pczarn where do you pop off the subtrees from?
11:04 purmou you're looking at the jsfiddle link?
11:06 pczarn oh sorry I missed it, huh it's an interesting use of unicode
11:07 rns purmout: is this -- https://github.com/purmou/pearley/blob/master/math.js -- the grammar spec? -- hope you don't mind.
11:08 purmou that's an old one
11:08 purmou let me add the one I'm currently using
11:09 rns yes, on a second look, it uses only parens for precedence.
11:10 purmou new grammar is there
11:11 purmou (eventually, I'll write a grammar to parse BNF and produce the format used in my implementation)
11:11 purmou so that this parser is available to all :)
11:13 rns yep, it's there.
11:13 pczarn add_exp ::= add_exp /[+-]/ mult_exp | mult_exp;  mult_exp ::= mult_exp /[*/]/ factor | factor;  factor ::= "(" add_exp ")" | number;  number ::= /[0-9]+/;
11:13 rns the new grammar, that is.
11:13 purmou I can tell by looking at the resultant Earley sets that it eventually gets it with the proper precedence
11:13 purmou at least, I believe that's the case.
11:15 pczarn the jsfiddle has slightly more code
11:16 purmou yes. it has the parse tree bit included
11:16 purmou oh, and doParse() actually picks up from the user input
11:24 rns Off the top of my head, do you really need parens in factor ::= "(" add_exp ")"? From what I see, it must parse with correct precedence without them.
11:24 purmou I can have my lexer ignore them and see what happens
11:25 pczarn that's right
11:26 purmou oof, I got a huuuuuuuge parse tree from that
11:26 purmou one sec, I'll have the jsfiddle updated so you guys can test out as well
11:26 purmou it prints out the tree and everything
11:28 purmou that it doesn't have proper precedence even without the parentheses is evidence that the way I build the trees is generally incorrect
11:28 pczarn having stacks in a chart parser won't do you any good
11:30 purmou i see
11:30 purmou earlier I had an idea to have sets of partial parses for each state in the chart
11:31 purmou that worked *a bit*, but not that well
11:31 purmou anyways, here is the jsfiddle: http://jsfiddle.net/purmou/opg92y7h/11/
11:32 purmou prints out whatever it was able to parse. any expression with varying operator classes that doesn't have explicit binding is funky.
11:32 purmou OH, and it can't even handle expressions like 1+2+3. haha
11:32 purmou so back to the chalkboard on this, it seems
11:33 pczarn purmou: first, add State.ast_node property
11:37 purmou joined #marpa
11:44 rns purmou: shouldn't factor ::= "(" add_exp ")" | number be just factor ::= number? factor ::= add_exp | number looks like a cycle in your grammar.
11:47 rns Ok, I see the grammar in jsfiddle doesn't have add_exp, so it's all good.
11:52 purmou actually the grammar does have that, in jsfiddle too
11:53 purmou I got that grammar from here
11:53 purmou http://loup-vaillant.fr/tutorials/earley-parsing/recogniser
11:54 purmou pczarn: did I miss anything else you suggested? I dipped off at "State.ast_node"
11:59 purmou this grammar totally works, and the recognizer definitely works with that grammar. if you input "1+2*3" and check the console, the last earley set contains the rule for add_exp that expands to "add_exp [+-] mult_exp"
11:59 purmou which is totally the correct precedence. :)
12:01 purmou by the way guys, thanks SO much for sticking around and helping.
12:03 pczarn purmou: nothing. Second, every time `state.advance` is called, do `state.ast_node.children.push(child_node)`
12:04 purmou so in the Scan and Complete phases, I push whatever I just scanned or complete to the advanced rule's ast_node
12:05 purmou and this is fine because nothing will complete without a finished ast_node
12:05 pczarn yes
12:05 purmou mmmmm, so clever
12:18 pczarn purmou: this basic structure is two optimizations away from becoming a bocage ( = packed shared parse forest) which is much better for ambiguous parses
12:19 purmou i'm getting weird infinite nodes
12:19 purmou haha
12:25 pczarn infinite?
12:26 purmou hold on
12:27 purmou should I be checking for duplicates? for some reason I get the same token pushed twice or more
12:27 purmou okay, a question that may help -- what determines a duplicate earley item? is it just if they have the same rule and type?
12:28 purmou or do they need the same source and dot position as well to be considered duplicates?
12:28 pczarn items are unique pairs of dot position and source
12:30 purmou so as long as dot position and source are unique, I can push it to an earley set
12:30 purmou you can have "X -> Y <dot> a, i" and "X -> Y <dot> a, j" in the same set?
12:31 pczarn yes, if i != j
12:33 pczarn purmou: Your 'equals' function doesn't compare this.next
12:33 purmou i was getting weeeeeeeird stuff when I did
12:36 purmou but...grr...it appears to work now. hah
12:47 purmou i'm getting asts with 10 children for rules with only 3 words
12:57 purmou so here is one that shows that AST as constructed using your method pczarn
12:57 purmou http://jsfiddle.net/purmou/opg92y7h/13/
12:57 purmou I restricted the length of the "children" array to the size of the rule. otherwise, the example expression was going haywire
13:00 pczarn perhaps you need to clone the tree each time it's modified
13:04 djns joined #marpa
13:25 pczarn purmou: works with clone function: http://jsfiddle.net/opg92y7h/14/
13:28 pczarn purmou: of course this method is not mine, see pages 62-65 of http://dinhe.net/~aredridel/.notmine/PDFs/Parsing/SCOTT,%20Elizabeth%20-%20SPPF-Style%20Parsing%20From%20Earley%20Recognizers.pdf
13:33 pczarn (without cloning, every possible partial parse repeatedly adding identical subtrees caused combinatorial explosion)
13:49 djns hi
13:51 pczarn hi
13:58 purmou pczarn...you are incredible
13:58 purmou where do you guys find all these papers?!
14:00 purmou that was actually a pretty simple fix. I took care to clone with the states, but I guess I was too tired to think the same of the asts
14:01 pczarn this paper is even mentioned in Loup's tutorial
14:04 purmou which page?
14:04 pczarn in tutorial? beginning of "The Parser"
14:05 pczarn :)
14:06 purmou ahahaha
14:06 purmou due diligence, i guess. though, this algorithm is a behemoth to truly comprehend...and this is literally the first parser I ever wrote in my life. I'm quite happy with the results!
14:10 djns i have been working on my lexer. http://toeserve.github.io/toese/plex.html
14:10 pczarn keep in mind that the full version as described in the paper includes two optimizations which make it much lighter on memory use
14:13 purmou i'll check it out and implement that. that much i'll force myself to do independently hahahaha
14:13 djns My parser is mainly designed for parsing Pelfe. It wont win any awards for performance, its rather simple
14:14 purmou my lexer is wickedly slow on big strings. need to optimize that
14:14 djns Yes. Its more of a lexer I am working on now
14:15 djns Mine shouldnt be very slow on strings, other than in scanning the characters for a closing paren.
14:15 djns maybe a few variables here and there
14:16 djns The language actually allows full code blocks to be embedded inside a string, if you wanted
14:17 pczarn djns: unfortunately I've already seen some software named plex including a parser/lexer generator
14:18 djns So I am stepping on someones trademark
14:19 djns I will have to come up with a new name
14:19 pczarn sort of; most importantly it's not googleable
14:31 purmou hey pczarn, if you don't mind my asking, what's your background? are you in academia?
14:35 purmou also, you're referring to the optimizations in the make_node routine correct?
14:35 pczarn yes, (S, j, i) is unique in a bocage/SPPF
14:36 pczarn I'm not in academia
14:50 djns In perl, to bring in a C++ library, someone has to write an interface for that, how much easier it would make things if C++ libraries had *easy to access* APIs that gave maps of the data structures of the library. THis would allow libraries to be directly used form Perl with no interfaces
14:50 djns Lets say C++ compilers generated these "maps" automatically they are made available
14:51 djns YEs, yes, I have heard of SWIG
14:55 ceridwen Re: http://irclog.perlgeek.de/marpa/2015-07-30#i_10975643  I know that monadic parser combinators can handle arbitrary CSGs because bind allows a combinator to select which combinator will be used to process its subinput.  This is pretty much morally equivalent to switching between grammars (each set of combinators represents a grammar), so I'd say yes.
15:00 djns interesting
17:00 jeffreykegler joined #marpa
17:01 jeffreykegler purmou: re http://irclog.perlgeek.de/marpa/2015-07-31#i_10984036 -- you *need* to check for duplicates when building a bocage.
17:08 jeffreykegler Aria: re http://irclog.perlgeek.de/marpa/2015-07-31#i_10983676 -- do you want to email Aycock and ask for a preprint?
17:08 jeffreykegler Re "safe" early Earley parsing -- my strand parsing scheme allows early parsing, and does not require the grammar to be "safe".
17:10 Aria Yeah, I may do that.
17:13 jeffreykegler My notes on strand parsing are https://github.com/jeffreykegler/kollos/blob/master/notes/misc/strand.md
17:14 jeffreykegler Basically the scheme is to allow an Earley parse to be stopped anywhere, then resumed, so the parse proceeds in pieces.
17:15 jeffreykegler These pieces can be joined -- the term "strand parsing" is an analogy with DNA
17:16 jeffreykegler Subtrees in the pieces can be evaluated.
17:17 jeffreykegler A major motivation was to make Marpa faster for SAX-ish parsing -- if you do evaluation as you go, you can throw away sections of the parse tree.
17:18 koo7 joined #marpa
17:18 jeffreykegler Parsing itself then takes constant space ...
17:19 jeffreykegler the evaluated interim result still will take whatever space it takes up of course.
17:21 Aria And this is super relevant to my interests.
17:22 jeffreykegler Strand parsing will be part of the Kollos project
17:22 jeffreykegler But it has to wait until I've simplified Libmarpa
17:23 jeffreykegler Which has to wait until I have a running Kollos-based test suite on the un-simplified Libmarpa.
17:36 lwa joined #marpa
17:45 koo7 joined #marpa
18:12 jeffreykegler joined #marpa
18:19 koo7 joined #marpa
20:44 koo7 joined #marpa
21:56 purmou jeffreykegler: I'm writing a compiler, so is evaluating as I go helpful? plus, evluating constitutes translating source code to potentially dozens of lines of assembly
21:57 purmou by the way...I made the assumption that the "ideal" or "correct" parse is the one in the last earley set that is the longest among those which are complete and originate at 0
21:57 purmou basically, requiring more detail out of the parse, I suppose. is that a good assumption?
21:58 ernimril purmou, are you parsing a language that is actually ambiguous? Computer languages tend to be non-ambiguous.
22:00 purmou Is there a quick and dirty way to determine if a grammar is ambiguous?
22:02 purmou also...the only issue I encountered was that, for instance, a multiplicative expression in my grammar can evaluate to an additive expression. i.e. A->M->(M, [*/], F) etc
22:02 purmou so I opted for grabbing the one with the most children, which ends up being the M production as opposed to the A production.
22:02 purmou it's not ambiguity, they're both the exact same parse, but one has more depth
22:20 purmou Oh, wow...my parser handles epsilons fine, too!
22:25 jeffreykegler pmurnou: Evaluating as you go is unknown territory.  One would expect it to be very helpful, though.
22:26 jeffreykegler Assuming that "longest parse is best parse" is correct if your language has that property. :-)
22:27 jeffreykegler Some languages do *not* have that property.
22:27 jeffreykegler It is an undecidable problem to determine if a language is ambiguous.
22:27 jeffreykegler For a specific input, ambiguity is easy to determine, and Marpa has calls to help you do that.
22:29 purmou hmm, i see.
22:29 purmou in general, then, is the one that appears furthest down that is complete and originates at 0 the one I want?
22:29 jeffreykegler Finally, re multiplicative and addition expressions -- if you are implementing the usual kind of expressions, I don't think what you are doing will work.
22:29 jeffreykegler Precedence is usually used for that.
22:30 jeffreykegler "is the one that appears furthest down that is complete and originates at 0 the one I want?"
22:30 jeffreykegler In general, no.
22:31 purmou for reference, I built all this so that I could create a parser with this grammar: http://www.cs.man.ac.uk/~pjj/bnf/c_syntax.bnf
22:32 jeffreykegler The language looks familiar. :-)
22:32 jeffreykegler Have you looked at Jean-Damien's C parser?
22:33 purmou not horoughly yet -- the link is up here somewhere
22:33 jeffreykegler A useful thing might be to look at it, and experiment with it.
22:34 jeffreykegler And blog what you find perhaps.
22:35 purmou I definitely will!
22:35 jeffreykegler I deeply regret that I don't have time to study all the code I should -- in particularly, I've just read JD's code in bits and pieces.
22:35 jeffreykegler One exercise that is useful, and within reach, but would go into new territory ...
22:36 jeffreykegler is a generalized approach to "pretty printing".
22:36 jeffreykegler That is, there are lots of pretty printers out there, but AFAICT they are all "snowflakes"
22:37 jeffreykegler You can't say, take a C pretty-printer whose options you like, and put a Perl parser under it.
22:37 jeffreykegler I think Marpa and/or Earley parsing would allow you to come up with a general theory/approach to this topic.
22:38 jeffreykegler IIRC, it has been discussed on this channel, but nobody followed up.
22:38 purmou ah, you mean to prettify C source?
22:38 jeffreykegler Maybe a start is to do a pretty-printer for C using Jean-Damien's parser.
22:39 jeffreykegler These exists already, but yours, if it was Marpa-based would be easier to read, customize, describe and extend.
22:40 jeffreykegler Trying to do it in a way that you could then, say, grab a Lua grammar and, with a bit of configuration, have a Lua pretty printer, would be very, very cool IMHO ...
22:40 jeffreykegler and I believe go into new territory.
22:41 jeffreykegler rns, Aria: I think there was a paper on parsing identation-sensitive languages that got mentioned on this channel, wasn't there?
22:42 purmou i see what you're saying. wouldn't the grammar need to explicitly define the desired formatting?
22:42 jeffreykegler I half-read it then put it aside, even though I was excited about it, because I have to focus on Kollos or it will never get done.
22:42 purmou i actually watched something interesting on doing this in javascript...
22:43 jeffreykegler Like the TV show begins, "Your mission should you decided to accept it ...."
22:43 jeffreykegler The task would be to separate specification of the format from the BNF.
22:44 jeffreykegler This is in part done, because some pretty printers already allow lots and lots of options.
22:44 purmou http://esprima.org/demo/parse.html
22:45 purmou this one picks up the index ranges at which all the tokens/phrases appear
22:45 purmou turns out they use it to their advantage...for example, to determine the difference between "6* 7" and "6 * 7"
22:46 jeffreykegler Cool.  What's his parser?
22:48 jeffreykegler The tireless Jean-Damien also wrote an ECMAScript parser which, if used might take some items off his TODO list.
22:48 purmou this esprima one appears to be recursive descent
22:49 purmou but they're picking up index information from the lexer, you can see in the tokens tab
22:50 jeffreykegler My general rule is that, if it's just in a brown bag labeled "parser", it's top-down, so that makes sense.
22:51 jeffreykegler Nice web presentation of his parser, very nice.
22:51 purmou I really love the educational value of this tool
22:51 purmou spitting out the parse tree
22:52 purmou I think that a great benefit that mine will have is that you can give it the grammar for any language and see that tree...it will help demystify a lot of things for students learning that language
22:52 jeffreykegler It's a good idea.
22:55 purmou by the way, here's the github for mine if you want to follow along: https://github.com/purmou/pearley
22:55 purmou and also check out the balanced parentheses example! http://jsfiddle.net/purmou/opg92y7h/19/
22:57 jeffreykegler I've added it to my watch list, but I cannot promise I'll be able to watch it very closely, I;m afraid
22:58 purmou of course! no worries my friend. you've been very helpful today though. thanks for giving me the time!
22:58 jeffreykegler Nice presentation.
22:59 jeffreykegler It does not yet do '()()' or '(()())'
22:59 jeffreykegler I did a blog post a while ago, I think, where I used parens as an example, and that parser/grammar could also point out where the mismatch occurred.
23:00 purmou no not yet...would the resolution be to have a rule for `exp -> exp exp`? I feel like that would conflict a lot
23:00 jeffreykegler Which takes us back to some of the "longest best" questions with which we started.
23:01 jeffreykegler http://jeffreykegler.github.io/Ocean-of-Awareness-blog/individual/2014/11/delimiter.html
23:04 purmou haha, the exp -> exp exp rule actually worked out great! http://jsfiddle.net/purmou/opg92y7h/20/
23:04 jeffreykegler I think you might get a lot of that blog post and its code.  In all humility. :-)
23:05 purmou reading now
23:06 jeffreykegler purmou: By the way the technical term for the "paren language" and similar ones is a "Dyck language", after the guy who first characterized them mathematically.
23:06 jeffreykegler https://en.wikipedia.org/wiki/Dyck_language
23:08 purmou indeed I haven't yet thought about reporting syntax errors.
23:08 purmou reporting mismatched grouping symbols is included in there certainly
23:11 jeffreykegler If you are writing a practical parser, error-reporting is nearly as important as producing a correct parse.
23:12 jeffreykegler Failure to realize this made the academic community go a long way down the dead end of LALR/yacc/bison parsing.
23:12 jeffreykegler And unfortunately many people are still marching down that dead end.
23:13 purmou any posts or papers on generalizing error reporting? my first thought is to check if the parse failed, then see what character it expected next and throw that. or, if it picked up a character that didn't match, say "expected [blah], saw [else]"
23:13 purmou also: http://jsfiddle.net/purmou/opg92y7h/21/ here's the longest-best idea failing. Try parsing the empty string there
23:15 jeffreykegler Re error reporting: looking into the delimiter issue you might find helpful -- you could take my work one step further for example.
23:16 jeffreykegler My solution to stating where the error is, is IMHO a good one, but it will not be best for everyone is all circumstances.
23:16 jeffreykegler Even better if the approach is easily configurable.
23:16 jeffreykegler IIRC in the comments I suggest some places where configuration might make sense.
23:17 jeffreykegler By the way, a parenthesis matcher might be a very useful tool.
23:17 koo7 joined #marpa
23:18 jeffreykegler Lots of languages have parsers which, when then hit an delimiter imbalance, do not produce a useful error message, at least not all the time.
23:18 jeffreykegler You could create a utility which did.
23:18 jeffreykegler You'd have to extend it to be aware of strings and comments in the various languages, but otherwise it could be general.
23:18 purmou Right. gcc is just not graceful with that at all
23:19 jeffreykegler So your web page could rescue desperate gcc users.
23:19 jeffreykegler Who realize somewhere in the 8,000 lines, the problem is probably 2 parens mismatching ...
23:20 jeffreykegler but whose gcc is giving them not a clue as to where.
23:26 purmou hmm, so your blog post covers a very ambiguous case. we will often have instnaces of "{ ... { ... }"
23:27 purmou where if the inner one is mismatched, we won't know...we'll only see the outer one as mismatched
23:28 jeffreykegler AFK
23:28 jeffreykegler purmou: Have fun!

| Channels | #marpa index | Today | | Search | Google Search | Plain-Text | summary