🦋 Welcome to the MAIN() IRC channel of the Raku Programming Language (raku.org). Log available at irclogs.raku.org/raku/live.html . If you're a beginner, you can also check out the #raku-beginner channel!
Set by lizmat on 6 September 2022.
epony HN2020.4Y!!!! 04:25
jdv where? 04:27
Guest94 tonyo in relation to your example: 06:28
role Text { regex text { <+[a..z]>+ } }; grammar Test  { rule TOP { ^ <text> $ } };   Test.^add_method("text", Text.^lookup("text")); dd Test.parse("abc");
This is not what I’m looking for I think. In this example I don’t see operating on the level of “grammars”. First I need Text not to be “grammar” but something else. 06:29
evalable6 Match.new(:orig("abc"), :from(0), :pos(3), :hash(Map.new((:text(Match.new(:orig("abc"), :from(0), :pos(3)))))))
Guest94 Second I have to patch Test to have some extra methods. So the same problems appear as with “is/does”, like name clashing and/or namespace pollution, etc.
Say the constraint is I have this grammar I absolutely can’t change but want to just use for my another grammar: 06:38
grammar Timestamp {token TOP{^<y><m><d>T<hours><minutes>$};token y{\d**4};token m{\d**2};token d{\d**2};token hours{\d**2};token minutes{\d**2}}
Mind that this example is artificial, for the sake of demonstration. It parses a string like ‘20130304T0102’
And then I have a grammar like this: 06:40
grammar TimestampedFile {token TOP{^<name>-<timestamp>.<ext>$};token name{<[a..z]>+};token timestamp{{Timestamp}};token ext{<[a..z]>**3}}
I just want to use the TOP parser of Timestamp in a piece of my TimestampedFile grammar implementation, that’s all. 06:41
And when I reach to <timestamp> of a parsed TimestampedFile I want to just access that Timestamp parsed object. Like <timestamp><year> 06:44
Simply composability over grammars 06:45
Guest94 Well, say maybe I can remove `^` and `$` from the Timestamp::TOP to make it more embeddable into other parsers. 07:06
Guest94 The best I can do at the moment is: token timestamp { .* {Timestamp.subparse($/)} } where it’s parsed from current point selecting everything till the end by `.*`. 07:40
If there was a way to return Timestamp match and tell the “token" how much I actually consumed
But I feel the grammars are not made to be actually composable, like in a functional style. 07:41
i can implement my own applicative-style parsers that are freely composable but it’s frustrating that builtin solution can’t be used in a similar manner 07:44
I just want a way to define some building blocks and then reuse them.
Like in Haskell you would have atomic stuff like “char” parser, then “string”, or a function that consumes as long as a char satisfies the predicate. 07:48
And out of it you can build something like timestamp parser, then using that you can build the filename parser.
Just like adding onion layers you make your parser be more and more complex one, consisting of a composition of simpler ones.
tonyo Guest94: no name clashing exists because you're only adding one or two methods. for your first point `grammars` compile to class/methods so anything you see in the MOP docs can be used against a grammar 08:59
to call the other grammar you'd use the rule TOP in it to do the match, and the fn alias is whatever you want - so: 09:00
Guest94 tonyo sorry, got disconnected after your ”...and the fn alias is whatever you want - so:“ and the logs seems to be only available up to yesterday 09:07
tonyo what you're looking to do is non-trivial. consider that most gramamr's TOP rule contains some statement like `^ <something>|<something-else>|.,, $` so doing the match requires some finagling or adding all of the stuff you might want to match via ^add_method and rewriting top 09:15
but just to call TOP you can do something like
m: grammar A { rule TOP { ^ "a"+ $ } }; grammar B { rule TOP { ^ <call-a-grammar> $ }; token b { "b"+ }; }; B.^add_method("call-a-grammar", -> *@_, *%_ { A.parse(@_[*-1].orig) }); dd B.parse("aaaa")
camelia Match.new(:orig("aaaa"), :from(0), :pos(4), :hash(Map.new((:call-a-grammar(Match.new(:orig("aaaa"), :from(0), :pos(4)))))))
tonyo that seems really tedious though, to find longest match, as an example, you'd have to just keep picking substrings until you reach the length and taking the last one to match 09:17
neither is a good solution but one is definitely less good
nemokosch I feel that this question is about slangs in disguise 09:54
The Raku language itself consists of different grammars but not by embedding one in the other. I'm not sure how that would even work. 09:58
Sounds like that would require incremental parsing in several turns, with appropriate multi-layered backtracking 09:59
Raku is built around a much more flat and eager approach: the encountered symbols can switch the used parsing rules 10:05
Which means, to my understanding, that there is always one set of rules to be used and you won't backtrack to a completely different grammar 10:07
tonyo yea, i mean it's easy enough to not have collisions and just use `is`. for instance where do you think <ws> comes from? i think actions is different. 10:32
nemokosch well collisions kind of give me a flashback, there is even an issue for it 10:34
long story short, I think it's a conceptual issue that tokens/regexes/rules are just "global" methods
the problem isn't that they are backed by methods but why not in a way that resembles operators? why don't they have a prefix, why do they indeed pollute the usual method namespace? 10:35
one often gets the impression that the reason for a lot of design "decisions" is simply "meh, good enough" 10:38
when it's not really good enough and it would have cost little to nothing to do it properly...
jdv lizmat: is the logging stuff broke? 15:27
seems to be stuck in 2023
librasteve Guest94: I made this gist to try and solve your problem - forgive me if I do not understand the full picture, but this seems to address your "consume with no change" requirement gist.github.com/librasteve/3fc8e23...63b4d260b2 17:19
The snag (ifaict) is that the existing Timestamp grammar is poorly designed for composability since it's TOP assumes control over the start (^) and end ($) of the string, so I propose using child class that adjusts and reexports the TOP accordingly 17:22
(I guess that this assumption is quite common in the grammars you want to reuse) 17:23
lizmat jdv: looks like it's not taking a year change correctly, fixed with a restart 17:37
librasteve Guest94: I also made a gist where you do not need to touch the inner grammar gist.github.com/librasteve/242125b...fe43c3f88c here with a lookaround assertion that actually runs the inner grammar and then actions to "bolt on" the inner match 18:44
jdv lizmat: classic. thanks. 18:56
Xliff \o 22:00
If I have a Callable I created that I want to convert to RakuAST, is there an interface to do that, yet?
Guest94 librasteve thanks, but that’s what I wanted to avoid. Like by adding <-[.]>+ selector for token timestamp I’m already parsing it, just not that precise. 22:04
I want the timestamp parser just be some kind of a blackbox.
Like like another token 22:05
And this $ts-match variable outside of the grammar is... bad. 22:06
I think I got disconnected when writing this. I’ll write again. 22:07
tonyo your example does not apply for my timestamp+filename scenario. see pastebin.com/8M25pvWm
And I think it shouldn’t since `@_[*-1].orig` is the whole input string for the Filename. 22:08
Filename.^add_method("timestamp", -> *@_, *%_ { Timestamp.subparse(@_[*-1].orig.substr(@_[*-1].pos)); }); 22:09
This works though to parse the Timestamp, as I’m cutting the already consumed piece. Except that it does not seem to propagate that N chars are consumed by the <timestamp>. 22:10
Also shouldn’t i call Filename.^compose after I do `Filename.^add_method? 22:11
Is there some kind of method or operator to merge two hashes together? 22:17
Or extend one with another
Xliff 22:29
librasteve Guest94: your 'adding <-[.]>+ selector' complaint is a bit of red herring ... that is easy to sidestep gist.github.com/librasteve/ff7deab...514be3b4e1 22:37
Xliff 22:44
librasteve stackoverflow.com/questions/608741...-hash-raku 23:16
I accept that storing and reuisng the inner match in a shared variable is 'bad' form, but others with more insight than I may be able to help with how to get an argument from a grammar token to the action method (maybe can use make in the token?) 23:18
my %c = %a, %b; with the ',' operator is the one I like 23:20
lizmat Xliff: no, there isn't. By that time it's already bytecode 23:24
there's an interface to create an AST from source code: the Str.AST method
sleep&
guifa o/ 23:38
Xliff lizmat: So how about this. Would it be possible to mark callables so they maintain a role that exposes the .AST method, which is preserved prior to bytecode generation? I was working on a PR for that a while ago, but I think it might have gotten eaten. Maybe I will try to reimplement. 23:51
guifa Xliff: so not sure the back story on this Q, but if traits can eventually be passed ASTs, I'd think this would be easy as pie 23:58