Changes between Initial Version and Version 1 of NQP-rx Tricks

Show
Ignore:
Timestamp:
03/22/10 21:35:18 (5 years ago)
Author:
Austin_Hastings
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • NQP-rx Tricks

    v1 v1  
     1= NQP-rx Tricks = 
     2 
     3Here are some tricks for parsing with NQP-rx: 
     4 
     5== Global Variables == 
     6 
     7A bunch of stuff in -rx is still done with globals. This will all move to contextuals, or to attributes of a common object, or something. Eventually. 
     8 
     9=== HLL::Grammar::%!MARKHASH === 
     10 
     11The MARKED/MARKER special rules, which are used by default in the <ws> rule, tracks mark info in a global hash. In order to parse a different source, you need to reset this hash. 
     12{{{ 
     13Q:PIR { 
     14    $P0 = null 
     15    set_hll_global ['HLL';'Grammar'], '%!MARKHASH', $P0 
     16}; 
     17}}} 
     18 
     19I use this to enable test cases for the grammar. The code below (built with the Kakapo library) runs the parser over and over again: 
     20{{{ 
     21method code_test(%code_matchers) { 
     22        my $slam := Slam::Compiler.new; 
     23        my $past; 
     24         
     25        for %code_matchers -> $pair { 
     26                my $code := $pair.key; 
     27                say("Code: $code"); 
     28 
     29                Q:PIR { 
     30                        $P0 = null 
     31                        set_hll_global ['HLL';'Grammar'], '%!MARKHASH', $P0 
     32                }; 
     33                 
     34                $past := $slam.compile: $code, :rule<EXPR>, :target<past>; #, :parsetrace; 
     35                #_dumper($past); 
     36                 
     37                my $matcher := $pair.value; 
     38                assert_match($past, $matcher, 
     39                        'Failed to parse {' ~  $code ~ '} as expected'); 
     40        } 
     41} 
     42 
     43method test_postcircumfix_array_index() { 
     44        my %code_matchers; 
     45        %code_matchers<x[0]>            := var( :scope<keyed>, var( :name<x> ), val( :value<0> )); 
     46        %code_matchers<x[ 1]>           := var( :scope<keyed>, var( :name<x> ), val( :value<1> )); 
     47        %code_matchers<x[ 2 ]>  := var( :scope<keyed>, var( :name<x> ), val( :value<2> )); 
     48 
     49        %code_matchers<x[ y ]>          := var( :scope<keyed>, var( :name<x> ), var( :name<y> )); 
     50         
     51        self.code_test: %code_matchers; 
     52} 
     53}}} 
     54 
     55The `var(...)` functions are syntactic sugar that generate a special Matcher for validating PCT trees. 
     56 
     57== HLL::Compiler == 
     58 
     59=== Debugging === 
     60 
     61The Regex code supports debugging with a `!cursor_debug` call. To enable this, the topmost regex (your grammar) has to be called with the `'rxtrace'` flag. The default compiler doesn't appear to support this, so I overrode the `parse` method: 
     62{{{ 
     63class Slam::Compiler; 
     64 
     65method parse($source, *%adverbs) { 
     66        unless %adverbs<actions> { 
     67                %adverbs<actions> := %adverbs<target> eq 'parse'  
     68                        ?? pir::null__P() 
     69                        !! self.parseactions; 
     70        } 
     71 
     72        my %options_map := hash( 
     73                actions => 'actions', 
     74                parsetrace => 'rxtrace', 
     75                rule => 'rule', 
     76        ); 
     77         
     78        my %parse_flags; 
     79         
     80        for %options_map -> $map { 
     81                %parse_flags{$map.value} := %adverbs{$map.key} 
     82                        if %adverbs.contains: $map.key; 
     83        } 
     84         
     85        my $match := self.parsegrammar.parse($source, :p(0), |%parse_flags); 
     86         
     87        self.panic('Failed to parse source') 
     88                unless $match; 
     89         
     90        $match; 
     91} 
     92}}}