Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

baby Marpa::R2 haml Error in SLIF parse: No lexemes accepted

Why isn't oneliner matching? Why is   <terminated oneliner> rejected?

#!/usr/bin/perl -- use strict; use warnings; use Data::Dump qw/ dd /; use Marpa::R2; my $hamlInput = q{-# haml comment %p a paragraph %p %span foo inside span inside p }; my $syntax = <<'__SYNTAX__'; :default ::= action => [values] :start ::= haml haml ::= comments | oneliners oneliners ::= oneliner+ comments ::= comment+ comment ::= <hash style comment> # oneliner ::= <terminated oneliner> | <unterminated oneliner> oneliner ::= <terminated oneliner> oneliner ::= <unterminated oneliner> <terminated oneliner> ~ '%' tagname <oneline body> <vert +ical space char> <unterminated oneliner> ~ '%' tagname <oneline body> <oneline body> ~ <hash comment char>+ tagname ~ [a-zA-Z]+ # Hash comment handling copied from Marpa::R2's metag.bnf. <hash style comment> ~ <terminated hash comment> + | <unterminated final hash comment> <terminated hash comment> ~ '-#' <hash comment body> <vertic +al space char> <unterminated final hash comment> ~ '-#' <hash comment body> <hash comment body> ~ <hash comment char>* <vertical space char> ~ [\x{0A}\x{0B}\x{0C}\x{0D}\x{2028 +}\x{2029}] <hash comment char> ~ [^\x{0A}\x{0B}\x{0C}\x{0D}\x{202 +8}\x{2029}] __SYNTAX__ my $grammar = Marpa::R2::Scanless::G->new({source => \$syntax}); my $recce = Marpa::R2::Scanless::R->new( { grammar => $grammar , trace_values => 1, trace_terminals => 1, } ); eval { dd( $recce->read( \$hamlInput, ) ); #~ dd( $recce->read( \$hamlInput, 0,16 ) ); 1; } or warn $@; my $value_ref = $recce->value(); dd( $value_ref ); #~ dd( $recce, $grammar ); __END__ Setting trace_terminals option Setting trace_values option Accepted lexeme L1c1-16 e1: <hash style comment>; value="-# haml comme +nt " Rejected lexeme L2c1-15: <terminated oneliner>; value="%p a paragraph " Error in SLIF parse: No lexemes accepted at line 2, column 1 Rejected lexeme #0: <terminated oneliner>; value="%p a paragraph "; length = 15 * String before error: -# haml comment\n * The error was at line 2, column 1, and at character 0x0025 '%', ... * here: %p a paragraph\n%p\n %span foo inside span inside Marpa::R2 exception at - line 60. \[[["-# haml comment\n"]]]

Inspired by Whitespace-important parsing with Parse::RecDescent (eg. HAML, Python)

Replies are listed 'Best First'.
Re: baby Marpa::R2 haml Error in SLIF parse: No lexemes accepted
by choroba (Cardinal) on Jan 21, 2016 at 10:04 UTC
    For debugging, it's better to set the default rule to
    :default ::= action => [name,value]

    Your problem is at the following line:

    haml ::= comments | oneliners

    Your example doesn't contain only comments or only oneliners, but a mix of both types. What you actually need is

    haml ::= things things ::= thing+ thing ::= oneliner | comment

    Handling of whitespace is weird. You didn't tell Marpa there could be whitespace between the tag and the body. Either do it explicitly, or try the implicit rule

    :discard ~ space space ~ [\s]+
    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,

      Your problem is at the following line:haml ::= comments | oneliners
      Your example doesn't contain only comments or only oneliners, but a mix of both types. What you actually need is

      Aha, thank you choroba . I had written /a+|b+/ instead of /(a|b)+/

      For debugging, it's better to set the default rule to  :default ::= action => [name,value]

      meh :D for debugging I'm using the trace options

      Handling of whitespace is weird. You didn't tell Marpa there could be whitespace between the tag and the body. Either do it explicitly, or try the implicit rule

      What? Why would I discard whitespace?

Re: baby Marpa::R2 haml Error in SLIF parse: No lexemes accepted
by aufflick (Deacon) on Jan 22, 2016 at 06:36 UTC

    Heh, found this suspiciously dated post when googling for Haml BNF myself :)

    FYI I'm looking at Python's BNF grammar - they use an INDENT .. DEDENT approach for modelling the indent level parsing in BNF. I'm going to give that approach a crack with Marpa.