#!perl -w use strict; use warnings; use Data::Dumper; use W3C::Grammar::YaccParser; my $GenSpec = W3C::Grammar::GenSpec::Perl->new(); $GenSpec->toggleExpandTerminals(); my $bnf = do { local $/; }; my $p = new W3C::Grammar::YaccParser(); # @@ Hack -- to add the default @pass directive. my $text = $bnf =~ m/^\s*(?:\[[0-9][0-9a-zA-Z]*\]\s*)?\@pass\s*:/m ? $bnf : "$bnf\n\@pass: [ \\t\\r\\n]+\n"; if ($text !~ m{^\%\%}) { $p->fake('bodyTransition'); } my ($g, $errs) = $p->Parse($text, 0x00); my $suppressLineDirectives = 0; my $stubs = 1; my $name; my $terminalPatterns = []; my $productions = ''; my $productionList = []; my $dependencyList = {}; my $quoter = \&W3C::Grammar::YaccCompileTree::Grammar::DQuoteRegexp; my $isStartRule = 1; my %flags = ( LineNumbers => 0, Types => 0, OrigCode => 0, Comments => 1, Yacc => 1, GenSpec => $GenSpec, Stubs => $stubs ? $GenSpec : undef, SuppressLineDirectives => $suppressLineDirectives, Class => $name, EndProductionString => ';', # TerminalPatterns => $terminalPatterns, TerminalDependsOn => $dependencyList, Quoter => $quoter, ProductionList => $productionList, IsStartRule => \ $isStartRule, Grammar => $g, ); $g->yaccify(undef, $GenSpec); my $re = $g->{Body}->[1]->toString(%flags); { no warnings 'utf8'; $re = eval "qq($re)"; } $re =~ s/([\x00-\x20\x80-\x{10FFFF}])/"\\x{".sprintf('%x',ord"$1")."}"/eg; print $re; # getProductionByName __DATA__ fake ::= 'fake' @terminals begin_value_list ::= begin_value ( S* ';' S* begin_value )* begin_value ::= ( offset_value | syncbase_value | repeat_value | event_value | accessKey_value | wallclock_sync_value | 'indefinite' ) offset_value ::= ( S* '+' | '-' S* )? ( Clock_value ) syncbase_value ::= ( Id_value '.' ( 'begin' | 'end' ) ) ( S* ('+'|'-') S* Clock_value )? event_value ::= ( Id_value '.' )? ( event_ref ) ( S* ('+'|'-') S* Clock_value )? repeat_value ::= ( Id_value '.' )? 'repeat(' integer ')' ( S* ('+'|'-') S* Clock_value )? accessKey_value ::= 'accessKey(' character ')' ( S* ('+'|'-') S* Clock_value )? wallclock_sync_value ::= wallclock_val Clock_value ::= Full_clock_val | Partial_clock_val | Timecount_val Full_clock_val ::= Hours ':' Minutes ':' Seconds ('.' Fraction)? Partial_clock_val ::= Minutes ':' Seconds ('.' Fraction)? Timecount_val ::= Timecount ('.' Fraction)? (Metric)? Id_value ::= ('\\'? NameStartChar) ('\\'? NameChar)* event_ref ::= Id_value wallclock_val ::= 'wallclock(' S* (DateTime | WallTime) S* ')' DateTime ::= Date 'T' WallTime Date ::= Years '-' Months '-' Days WallTime ::= (HHMM_Time | HHMMSS_Time)(TZD)? HHMM_Time ::= Hours24 ':' Minutes HHMMSS_Time ::= Hours24 ':' Minutes ':' Seconds ('.' Fraction)? TZD ::= 'Z' | (('+' | '-') Hours24 ':' Minutes ) Metric ::= 'h' | 'min' | 's' | 'ms' Hours ::= DIGIT+ Minutes ::= TwoDIGIT Seconds ::= TwoDIGIT Fraction ::= DIGIT+ Timecount ::= DIGIT+ TwoDIGIT ::= DIGIT DIGIT integer ::= DIGIT+ Years ::= FourDIGIT Months ::= TwoDIGIT Days ::= TwoDIGIT Hours24 ::= TwoDIGIT FourDIGIT ::= DIGIT DIGIT DIGIT DIGIT DIGIT ::= [0-9] NMTOKEN ::= Nmtoken IDREF ::= Name character ::= Char Char ::= [#x1-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF] S ::= #x20 | #x9 | #xD | #xA Nmtoken ::= (NameChar)+ Name ::= NameStartChar (NameChar)* NameChar ::= NameStartChar | '-' | '.' | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040] NameStartChar ::= ':' | [A-Z] | '_' | [a-z] | [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x2FF] | [#x370-#x37D] | [#x37F-#x1FFF] | [#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF]