Excursions into Parrot

Uncategorized 8 August 2006 | 2 Comments

Let me warn you from the start: Patrick Michaud’s slides make it look deceptively easy!

First of all, I created “simple.pg” according to his recipe:

grammar Simple::Grammar ;

token variable { [  | _ ] \w* }
token number { \d+ }

token addop { \+ | - }
token mulop { \* | / }

rule expression {  [   ] * }
rule addterm {  [   ] * }
rule multerm {  |  | \(  \) }

This looks all fine and dandy. Next, to compile: $ parrot pgc.pir simple.pg > simple.pir.

Error reading source file pgc.pir.

Huh? Well he didn’t say anything about that. Maybe I have a path wrong somewhere? A quick “locate” reveals it doesn’t lie anywhere on my computer. Next step is to check the downloaded source code to see if I wasn’t meant to delete it yet… ah, yes, it’s hiding under ./compilers/pge/. It looks like it will be easier to work from this directory, so I’ll move everything into there.

Unfortunately, pgc.pir won’t run straight away, and you’ll need to patch it up a bit:

@@ -49,7 +49,7 @@
     .param pmc args
     load_bytecode 'Getopt/Obj.pbc'
     load_bytecode 'dumper.pbc'
-    load_bytecode 'PGE/Dumper.pbc'
+    load_bytecode 'Data/Dumper.pbc'
     '__onload'()

     ##   create an option parser
@@ -153,8 +153,8 @@

 .sub '__onload' :load
     load_bytecode 'PGE.pbc'
-    load_bytecode 'PGE/Text.pbc'
-    load_bytecode 'PGE/Util.pbc'
+    load_bytecode 'PGE/Text.pir'
+    load_bytecode 'PGE/Util.pir'

     .local pmc p6regex
     p6regex = compreg 'PGE:6Regex'

Now it runs fine and generates the output file perfectly. Quite a bit of code in there! Next to use the parser on a real string, using the example:

.include 'simple.pir'

.sub 'foo'
  ...
  ##   get the parrot sub for parsing an expression
  parse = find_global 'Simple::Grammar', 'expression'

  ##   the expression to be parsed
  expr = '3 + 4 * (a-2)'

  ##   parse the expression
  match = parse(expr)

  ##   dump the parse tree
  '_dumper'(match)

That little ellipsis is really in there to let you know that you need to read quite a few more Parrot docs before you’re allowed to progress past this step.

In fact, you’ll be able to get up to speed in no time just by copying some of the example files. I found that I could get by with guessing a bit;

  • .sub needed an .end,
  • the main method needs to be marked :main to run automatically,
  • the variables need to be declared… with appropriate types… you can’t just use pmc for everything,
  • and the _dumper code needed to be loaded.

Here’s what it eventually looked like:

.include 'simple.pir'

.sub main :main
        .local pmc parse, match
        .local string expr
        ## get the parrot sub for parsing an expression
        parse = find_global 'Simple::Grammar', 'expression'
        ## the expression to be parsed
        expr = "3 + 4 * (a-2)"
        ## parse the expression
        match = parse(expr)
        ## dump the parse tree
        load_bytecode 'dumper.pbc'
        '_dumper'(match)
.end

But that’s not all, you’ll need to jump through the automagically-generated parser code to put in things that it forgot to. For brevity, here’s the diff:

@@ -1,6 +1,7 @@
       .sub '__onload' :load
           .local pmc optable
           ## namespace Simple::Grammar
+          load_bytecode 'PGE.pbc'
           $I0 = find_type 'Simple::Grammar'
           if $I0 != 0 goto onload_186
           $P0 = subclass 'PGE::Grammar', 'Simple::Grammar'
@@ -288,6 +289,7 @@
           .local string target    :unique_reg
           .local pmc mfrom, mpos  :unique_reg
           .local int cpos, iscont :unique_reg
+          load_bytecode 'PGE/Match.pir'
           $P0 = getclass 'PGE::Match'
           (mob, cpos, target, mfrom, mpos, iscont) = $P0.'new'(mob, adverbs :flat :named)           .local pmc ustack :unique_reg
@@ -321,6 +323,7 @@
           goto fail_cut
         R: # concat
         R147: # subrule ws
+          load_bytecode 'PGE/Regex.pir'
           captob = captscope
           $P0 = getattribute captob, '$.pos'
           $P0 = pos

And now, one and a half hours later, for the grand finale…

$ parrot simpleparse.pir
"VAR1" => PMC 'PGE::Match' { ... }

VoilĂ ! My first excursion into Parrot. A bit fiddly, but I enjoyed myself

Tagged in , ,

2 Responses on “Excursions into Parrot”

  1. JC says:

    This parrot is DEAD!

  2. Porges says:

    No; merely pining.

Leave a Reply