How does one create a Raku Grammar programatically (dynamically)?
Asked Answered
C

1

6

Suppose grammar G has two productions …

  1. S → λ
  2. S → aSb

In Raku, how would one create this grammar programmatically (i.e., dynamically, at runtime)?

The goal is to have a Raku program create — at runtime — a Raku grammar that might be written statically as …

grammar Parser
  {
  token  TOP  { <S> }
  token S { '' | 'a' <S> 'b' }
  }

Given the first answer to my question, I am trying to dynamically create what would be statically written as …

  grammar Parser
    {
    token TOP { <S> }
    } # end grammar Parser

I have tried …

  constant Parser := Metamodel::GrammarHOW.new_type( name => 'Parser' ) ;
  Parser.^add_method('TOP', my method TOP(Parser:) { <S> }) ;
  Parser.^compose;                                                 # } 
  say Parser.HOW.^name ;
  say Parser.^methods(:local) ;

However, the reply is …

Perl6::Metamodel::GrammarHOW
(TOP)

… rather than the hoped-for …

Perl6::Metamodel::GrammarHOW
(token TOP { <S> } BUILDALL)

How should add_method be invoked to add the TOP token (and later, other tokens such as the S token)?


After more work, I believe that I may have a solution

  constant Parser := Metamodel::GrammarHOW.new_type( name => 'Parser' ) ;
  Parser.^add_method( 'TOP', my token TOP { <S> } ) ;
  Parser.^add_method( 'S', my token S { '' | 'a' <S> 'b' } ) ;
  Parser.^compose ;
  say Parser.HOW.^name ;
  say Parser.^methods( :local ) ;
  say Parser.parse: 'aabb' ;

Output is …

Perl6::Metamodel::GrammarHOW
(token TOP { <S> } token S { '' | 'a' <S> 'b' })
「aabb」
 S => 「aabb」
  S => 「ab」
   S => 「」

I had coded a static version of Parser and for that static Parser similar output to that shown above had been …

(token TOP { <S> } token S { '' | 'a' 'a' <S> 'b' 'b' } BUILDALL)

I am not sure about the fact that BUILDALL is missing from my dynamically created Parser. I do not understand BUILDALL and did not find much when searching on-line.


Craggy answered 15/6, 2022 at 16:32 Comment(0)
S
4

Using the metamodel, of course. Same as there are HOWs (Higher Order Working) for every basic type, there's a GrammarHOW for grammars. Unfortunately, there's not a whole lot of information on the metamodel; there's this article by Masak which mentions the GrammarHOW, and that's that. However, looking at the code, it's essentially a class; you're probably OK if you look at the classHOW examples, and make methods be tokens and classes be grammars.

Metaprogramming, in general, is a subject that's not been extensively covered so far. Which is a pity.

Save answered 15/6, 2022 at 18:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.