From 9b27969b4cee3357de76d7837c64ba6f8b1416af Mon Sep 17 00:00:00 2001 From: Ingy dot Net Date: Wed, 21 Sep 2011 23:42:28 +0200 Subject: [PATCH] Released version 0.17 --- Changes | 6 ++++++ Makefile.PL | 2 +- README | 42 ++++++++++++++++++++++++++++++++--------- lib/Pegex.pm | 44 ++++++++++++++++++++++++++++++++----------- lib/Pegex/Compiler.pm | 29 ++++++++++++++++++++++++++++ 5 files changed, 102 insertions(+), 21 deletions(-) diff --git a/Changes b/Changes index dfb1699..2701ae0 100644 --- a/Changes +++ b/Changes @@ -1,4 +1,10 @@ --- +version: 0.17 +date: Wed Sep 21 23:42:00 CEST 2011 +changes: +- Complete refactoring of everything. +- This hard fought gem was released from Liz++ and Wendy++'s TV room. +--- version: 0.16 date: Fri Sep 9 14:51:38 CEST 2011 changes: diff --git a/Makefile.PL b/Makefile.PL index 6e81adc..45b0f05 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -1,5 +1,5 @@ BEGIN { $main::PM = 'lib/Pegex.pm' } -use inc::Module::Package 'Ingy:modern 0.15'; +use inc::Module::Package 'Ingy:modern 0.16'; if (is_admin) { print "Module author removing inc/Pegex/\n"; diff --git a/README b/README index 9af16f7..2f1e427 100644 --- a/README +++ b/README @@ -123,6 +123,29 @@ FYI best ideas from these great works, and make them work in as many languages as possible. That's Acmeism. +SELF COMPILATION TRICKS + You can have some fun using Pegex to compile itself. First get the Pegex + grammar repo: + + git clone git://github.com/ingydotnet/pegex-pgx.git + cd pegex-pgx + + Then parse and dump the Pegex grammar with Pegex: + + perl -MXXX -MPegex -e 'XXX pegex("pegex.pgx")->parse("pegex.pgx")' + + For a different view of the data tree, try: + + perl -MXXX -MPegex -e 'XXX pegex("pegex.pgx", {wrap => 0})->parse("pegex.pgx")' + + Finally to emulate the Pegex compiler do this: + + perl -MXXX -MPegex -e 'XXX pegex("pegex.pgx", {receiver => "Pegex::Compiler::AST"})->parse("pegex.pgx")' + + This specifies a "receiving" class that can shape the results into + something useful. Indeed, this is the exact guts of + Pegex::Grammar::Pegex. + A REAL WORLD EXAMPLE TestML is a new Acmeist unit test language. It is perfect for software that needs to run equivalently in more than one language. In fact, Pegex @@ -132,28 +155,29 @@ A REAL WORLD EXAMPLE http://www.testml.org/specification/language/ The Perl6 implementation of TestML uses this grammar in: - http://github.com/ingydotnet/testml-pm6/lib/TestML/Parser/Grammar.pm + https://github.com/ingydotnet/testml-pm6/blob/master/lib/TestML/Parser/G + rammar.pm All other implementations of TestML use this Pegex grammar: - http://github.com/ingydotnet/testml-pgx/testml.pgx + https://github.com/ingydotnet/testml-pgx/blob/master/testml.pgx In Perl 5, Pegex::Compiler is used to compile the grammar into this simple data structure (shown in YAML): - http://github.com/ingydotnet/testml-pgx/testml.yaml + https://github.com/ingydotnet/testml-pgx/blob/master/testml.pgx.yaml The grammar can also be precompiled to JSON: - http://github.com/ingydotnet/testml-pgx/testml.json + https://github.com/ingydotnet/testml-pgx/blob/master/testml.pgx.json Pegex::Compiler further compiles this into a Perl 5 only grammar tree, which becomes this module: - http://github.com/ingydotnet/testml-pm/lib/TestML/Parser/Grammar.pm + https://github.com/ingydotnet/testml-pm/blob/master/lib/TestML/Grammar.p + m TestML::Parser::Grammar is a subclass of Pegex::Grammar. It can be used to parse TestML files. TestML::Parser calls the "parse()" method of the - grammar with a TestML::Receiver object that receives callbacks when - various rules match, and uses the information to build a - TestML::Document object. - http://github.com/ingydotnet/testml-pm/lib/TestML/Parser.pm + grammar with a TestML::AST object that receives callbacks when various + rules match, and uses the information to build a TestML::Document + object. Thus TestML is an Acmeist language written in Pegex. It can be easily ported to every language where Pegex exists. In fact, it must be ported diff --git a/lib/Pegex.pm b/lib/Pegex.pm index 03a6c21..38cba38 100644 --- a/lib/Pegex.pm +++ b/lib/Pegex.pm @@ -11,14 +11,15 @@ # - irc.freenode.net#pegex use 5.010; -use Mo 0.22 (); +use strict; +use warnings; +use Mo 0.23 (); package Pegex; -use strict; use Pegex::Grammar; -our $VERSION = '0.16'; +our $VERSION = '0.17'; sub import { no strict 'refs'; @@ -170,6 +171,28 @@ Conway's Perl 5 module, L. Pegex tries to take the best ideas from these great works, and make them work in as many languages as possible. That's Acmeism. +=head1 SELF COMPILATION TRICKS + +You can have some fun using Pegex to compile itself. First get the Pegex grammar repo: + + git clone git://github.com/ingydotnet/pegex-pgx.git + cd pegex-pgx + +Then parse and dump the Pegex grammar with Pegex: + + perl -MXXX -MPegex -e 'XXX pegex("pegex.pgx")->parse("pegex.pgx")' + +For a different view of the data tree, try: + + perl -MXXX -MPegex -e 'XXX pegex("pegex.pgx", {wrap => 0})->parse("pegex.pgx")' + +Finally to emulate the Pegex compiler do this: + + perl -MXXX -MPegex -e 'XXX pegex("pegex.pgx", {receiver => "Pegex::Compiler::AST"})->parse("pegex.pgx")' + +This specifies a "receiving" class that can shape the results into something +useful. Indeed, this is the exact guts of L. + =head1 A REAL WORLD EXAMPLE L is a new Acmeist unit test language. It is perfect for software that @@ -180,27 +203,26 @@ TestML has a language specification grammar: http://www.testml.org/specification/language/ The Perl6 implementation of TestML uses this grammar in: -http://github.com/ingydotnet/testml-pm6/lib/TestML/Parser/Grammar.pm +https://github.com/ingydotnet/testml-pm6/blob/master/lib/TestML/Parser/Grammar.pm All other implementations of TestML use this Pegex grammar: -http://github.com/ingydotnet/testml-pgx/testml.pgx +https://github.com/ingydotnet/testml-pgx/blob/master/testml.pgx In Perl 5, Pegex::Compiler is used to compile the grammar into this simple data structure (shown in YAML): -http://github.com/ingydotnet/testml-pgx/testml.yaml +https://github.com/ingydotnet/testml-pgx/blob/master/testml.pgx.yaml The grammar can also be precompiled to JSON: -http://github.com/ingydotnet/testml-pgx/testml.json +https://github.com/ingydotnet/testml-pgx/blob/master/testml.pgx.json Pegex::Compiler further compiles this into a Perl 5 only grammar tree, which becomes this module: -http://github.com/ingydotnet/testml-pm/lib/TestML/Parser/Grammar.pm +https://github.com/ingydotnet/testml-pm/blob/master/lib/TestML/Grammar.pm TestML::Parser::Grammar is a subclass of Pegex::Grammar. It can be used to parse TestML files. TestML::Parser calls the C method of the grammar -with a TestML::Receiver object that receives callbacks when various rules -match, and uses the information to build a TestML::Document object. -http://github.com/ingydotnet/testml-pm/lib/TestML/Parser.pm +with a TestML::AST object that receives callbacks when various rules match, +and uses the information to build a TestML::Document object. Thus TestML is an Acmeist language written in Pegex. It can be easily ported to every language where Pegex exists. In fact, it must be ported to those diff --git a/lib/Pegex/Compiler.pm b/lib/Pegex/Compiler.pm index 119d954..6019560 100644 --- a/lib/Pegex/Compiler.pm +++ b/lib/Pegex/Compiler.pm @@ -196,6 +196,10 @@ sub to_perl { my $pegex_compiler = Pegex::Compiler->new(); my $grammar_tree = $pegex_compiler->compile($grammar_text)->tree; +or: + + perl -Ilib -MYourGrammarModule=compile + =head1 DESCRIPTION The Pegex::Compiler transforms a Pegex grammar string (or file) into a @@ -264,3 +268,28 @@ Serialize the current grammar tree to JSON. Serialize the current grammar tree to Perl. =back + +=head1 IN PLACE COMPILATION + +When you write a Pegex based module you will want to precompile your grammar +into Perl so that it has no load penalty. Pegex::Grammar provides a special +mechanism for this. Say you have a class like this: + + package MyThing::Grammar; + use Pegex::Mo; + extends 'Pegex::Grammar'; + + use constant text => '../mything-grammar-repo/mything.pgx'; + sub tree { + } + +Simply use this command: + + perl -Ilib -MMyThing::Grammar=compile + +and Pegex::Grammar will call Pegex::Compile to put your compiled grammar +inside your C subroutine. It will actually write the text into your +module. This makes it trivial to update your grammar module after making +changes to the grammar file. + +See L for an example.