SlideShare a Scribd company logo
1 of 43
Download to read offline
Perl6 Regexen:
Reducing line noise in your code.
Steven Lembark
Workhorse Computing
lembark@wrkhors.com
The difference
… prefer readabity over compactness.
– Larry Wall
Regexes you can read.
Code you can maintain.
Do what I mean need.
What is line noise?
Random garbage on the screen.
Due to signal noise.
Eliminted by error correcting modems.
More effective use of Regex
Daisy-chaining tokens.
RX-from-hell with alternations.
Q: Why?
A: Parsing.
What we had to do.
Without grammars.
Parsing order implicit in RX, code.
Branching logic on matched tokens.
Nested-if in for loops.
Parse *.ini file
my $header = qr{ ^ h* [ (?<name> [^][]+ ) ] h* $ }xm;
my $property = qr{ ^ h* (?<key> .+? ) h* = h* (?<value> .+ ) $ }xm;
my $comment = qr{ ^ h* # }xm;
my $empty_line = qr{ ^ h* $}xm;
Regexen tokenize input.
Parse *.ini
for my $nextline (readline($INI_FILE)) {
# If it's a header line, start a new section...
if ($nextline =~ /$header/) {
$section = $config{ $+{name} } //= {};
}
# If it's a property, add the key and value to the current section...
elsif ($nextline =~ /$property/) {
$section->{ $+{key} } = $+{value};
}
# Ignore comments or empty lines
elsif ($nextline =~ /$comment|$empty_line/) {
# Do nothing
}
# Report anything else as a probable error...
else {
warn "Invalid data in INI file at line $.n"
. "t$nextlinen";
}
}
Code processes it.
Maintainable?
Inter-related order of code and rx.
Code changes affect rx?
Rx changes affect code?
Find out: Try it and see...
Perl6: Grammars
Structure in one place.
Declarative.
No iterative code.
Tokens & Structure
grammar INI
{
token TOP { <section>* }
token section { [ ^ | <header> ] <block> }
token header { '[' $<ID> = <-[ [ ] n ]>+ ']' h* n }
token block { [ <property> | <.emptylines> | <.comment> ]* }
token property { h* $<name>=N+? h* '=' h* $<value>=N+ n }
token comment { ^^ h* '#' N* n }
token emptylines { [ ^^ h* n ]+ }
}
Tokens & Structure
grammar INI
{
token TOP { <section>* }
token section { [ ^ | <header> ] <block> }
token header { '[' $<ID> = <-[ [ ] n ]>+ ']' h* n }
token block { [ <property> | <.emptylines> | <.comment> ]* }
token property { h* $<name>=N+? h* '=' h* $<value>=N+ n }
token comment { ^^ h* '#' N* n }
token emptylines { [ ^^ h* n ]+ }
}
Tokens & Structure
grammar INI
{
token TOP { <section>* }
token section { [ ^ | <header> ] <block> }
token header { '[' $<ID> = <-[ [ ] n ]>+ ']' h* n }
token block { [ <property> | <.emptylines> | <.comment> ]* }
token property { h* $<name>=N+? h* '=' h* $<value>=N+ n }
token comment { ^^ h* '#' N* n }
token emptylines { [ ^^ h* n ]+ }
}
Process the content
class INI::hash_builder
{
method TOP ($/) { make %( $<section>».ast ) }
method section ($/) { make ~($<header><ID>//'') => $<block>.ast }
method block ($/) { make %( $<property>».ast ) }
method property ($/) { make ~$<name> => ~$<value> }
}
my %config = INI.parsefile( 'example.ini', :actions(INI::hash_builder) ).ast;
say %config.perl;
Process the content
class INI::hash_builder
{
method TOP ($/) { make %( $<section>».ast ) }
method section ($/) { make ~($<header><ID>//'') => $<block>.ast }
method block ($/) { make %( $<property>».ast ) }
method property ($/) { make ~$<name> => ~$<value> }
}
my %config = INI.parsefile( 'example.ini', :actions(INI::hash_builder) ).ast;
say %config.perl;
Process the content
class INI::hash_builder
{
method TOP ($/) { make %( $<section>».ast ) }
method section ($/) { make ~($<header><ID>//'') => $<block>.ast }
method block ($/) { make %( $<property>».ast ) }
method property ($/) { make ~$<name> => ~$<value> }
}
my %config = INI.parsefile( 'example.ini', :actions(INI::hash_builder) ).ast;
say %config.perl;
Process the content
class INI::hash_builder
{
method TOP ($/) { make %( $<section>».ast ) }
method section ($/) { make ~($<header><ID>//'') => $<block>.ast }
method block ($/) { make %( $<property>».ast ) }
method property ($/) { make ~$<name> => ~$<value> }
}
my %config = INI.parsefile( 'example.ini', :actions(INI::hash_builder) ).ast;
say %config.perl;
Process the content
class INI::hash_builder
{
method TOP ($/) { make %( $<section>».ast ) }
method section ($/) { make ~($<header><ID>//'') => $<block>.ast }
method block ($/) { make %( $<property>».ast ) }
method property ($/) { make ~$<name> => ~$<value> }
}
my %config = INI.parsefile( 'example.ini', :actions(INI::hash_builder) ).ast;
say %config.perl;
Care to guess what this does?
/{~}!@#$%^(&*)-+=[/]:;"'<.,>?/
Care to guess what this does?
Q: Which char's match themselves?
/{~}!@#$%^(&*)-+=[/]:;"'<.,>?/
Care to guess what this does?
Q: Which char's match themselves?
A: None, in Perl6, since they are punctuation.
/{~}!@#$%^(&*)-+=[/]:;"'<.,>?/
Saner metachars
Match integers enclosed in braces.
Perl 5:
/ [ s* (?: d+ (?: s* , s* d+ )* s* )? ] /x
Saner metachars
Match integers enclosed in braces.
Perl 5:
/ [ s* (?: d+ (?: s* , s* d+ )* s* )? ] /x
Perl 6:
/ :s '[' [d+]* % ',' ']' /
Saner metachars
Match integers enclosed in braces.
Perl 5:
/ [ s* (?: d+ (?: s* , s* d+ )* s* )? ] /x
Perl 6:
/ :s '[' [d+]* % ',' ']' / Consume WS
Saner metachars
Match integers enclosed in braces.
Perl 5:
/ [ s* (?: d+ (?: s* , s* d+ )* s* )? ] /x
Perl 6:
/ :s '[' [d+]* % ',' ']' / Literals
Saner metachars
Match integers enclosed in braces.
Perl 5:
/ [ s* (?: d+ (?: s* , s* d+ )* s* )? ] /x
Perl 6:
/ :s '[' [d+]* % ',' ']' / Non-capturing match
Saner metachars
Match integers enclosed in braces.
Perl 5:
/ [ s* (?: d+ (?: s* , s* d+ )* s* )? ] /x
Perl 6:
/ :s '[' [d+]* % ',' ']' / Separator
Aside: Future speed
Perl6 regexen execute as DFA where possible.
Opportunity for much faster execution.
For some definition of ...
Aside: Future speed
Perl6 regexen execute as DFA where possible.
Also benefit from saner results.
DFA more likely to Do What I Mean.
Alternations match best, not first match.
Smartest matching
Perl 5:
say $& if 'Which regex engine is smartest?'
=~ /smart|smarter|smartest/;
Smartest matching
Perl 5:
say $& if 'Which regex engine is smartest?'
=~ /smart|smarter|smartest/;
Smartest matching
Perl 5:
say $& if 'Which regex engine is smartest?'
=~ /smart|smarter|smartest/;
Perl 6:
say $/ if 'Which regex engine is smartest?'
~~ /smart|smarter|smartest/;
Smartest matching
Perl 5:
say $& if 'Which regex engine is smartest?'
=~ /smart|smarter|smartest/;
Perl 6:
say $/ if 'Which regex engine is smartest?'
~~ /smart|smarter|smartest/;
Smartest matching
Perl 5:
say $& if 'Which regex engine is smartest?'
=~ /smart|smarter|smartest/;
Perl 6:
say $/ if 'Which regex engine is smartest?'
~~ /smart|smarter|smartest/;
Perl5 nested structure
#! /usr/bin/env perl
use 5.010;
# We're going to need this to extract hierarchical data structures...
our @stack = [];
my $LIST = qr{
# Match this...
(?&NESTED)
# Which is defined as...
(?(DEFINE)
(?<NESTED>
# Keep track of recursions on a stack...
(?{ local @::stack = (@::stack, []); })
# Match a list of items...
[ s* (?>
(?&ITEM)
(?:
s* , s* (?&ITEM)
)*+
)? s*
]
# Pop the stack and add that frame to the growing data structure...
(?{ local @::stack = @::stack;
my $nested = pop @stack;
push @{$::stack[-1]}, $nested;
})
)
# For each item, push it onto the stack if it's a leaf node...
(?<ITEM>
(d+) (?{ push @{$stack[-1]}, $^N })
| (?&NESTED)
)
)
}x;
# Match, extracting a data structure...
'[1,2,[3,3,[4,4]],5]' =~ /$LIST/;
# Retrieve the data structure...
my $parse_tree = pop @stack;
# Show it...
use Data::Dumper 'Dumper';
say Dumper($parse_tree);
Perl6 nested grammar
#! /usr/bin/env perl6
use v6;
# Define the structure of a list...
grammar LIST {
rule TOP { '[' <ITEM>* % ',' ']' }
token ITEM { d+ | <TOP> }
}
# Define how to convert list elements to a suitable data structure...
class TREE {
method TOP ($/) { make [ $<ITEM>».ast ] }
method ITEM ($/) { make $<TOP>.ast // +$/ }
}
# Parse, extracting the data structure...
my $parse_tree = LIST.parse('[1,2,[3,3,[4,4]],5]', :actions(TREE)).ast;
# Show what we got...
say $parse_tree.perl;
Perl6 nested regex
#! /usr/bin/env perl6
use v6;
'[1,2,[3,3,[4,4]],5]'
~~ /'[' [ (d+) | $<0>=<~~> ]* % ',' ']' /;
say $/;
Perl6 nested regex
#! /usr/bin/env perl6
use v6;
'[1,2,[3,3,[4,4]],5]'
~~ /'[' [ (d+) | $<0>=<~~> ]* % ',' ']' /;
say $/;
In Perl6
Regexen are saner.
In Perl6
Regexen are saner.
Grammars offer cleaner code.
In Perl6
Regexen are saner.
Grammars offer cleaner code.
Smart matching works.
In Perl6
Regexen are saner.
Grammars offer cleaner code.
Smart matching works.
Objects have useful methods.
In Perl6
Regexen are saner.
Grammars offer cleaner code.
Smart matching works.
Objects have useful methods.
It's new.
In Perl6
Regexen are saner.
Grammars offer cleaner code.
Smart matching works.
Objects have useful methods.
It's worth learning.

More Related Content

What's hot

Perl.Hacks.On.Vim
Perl.Hacks.On.VimPerl.Hacks.On.Vim
Perl.Hacks.On.VimLin Yo-An
 
Object Trampoline: Why having not the object you want is what you need.
Object Trampoline: Why having not the object you want is what you need.Object Trampoline: Why having not the object you want is what you need.
Object Trampoline: Why having not the object you want is what you need.Workhorse Computing
 
DBIx::Class introduction - 2010
DBIx::Class introduction - 2010DBIx::Class introduction - 2010
DBIx::Class introduction - 2010leo lapworth
 
DBIx::Class beginners
DBIx::Class beginnersDBIx::Class beginners
DBIx::Class beginnersleo lapworth
 
The Joy of Smartmatch
The Joy of SmartmatchThe Joy of Smartmatch
The Joy of SmartmatchAndrew Shitov
 
Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)Kang-min Liu
 
SPL: The Missing Link in Development
SPL: The Missing Link in DevelopmentSPL: The Missing Link in Development
SPL: The Missing Link in Developmentjsmith92
 
Introduction to Perl - Day 1
Introduction to Perl - Day 1Introduction to Perl - Day 1
Introduction to Perl - Day 1Dave Cross
 
Simple Ways To Be A Better Programmer (OSCON 2007)
Simple Ways To Be A Better Programmer (OSCON 2007)Simple Ways To Be A Better Programmer (OSCON 2007)
Simple Ways To Be A Better Programmer (OSCON 2007)Michael Schwern
 
Good Evils In Perl
Good Evils In PerlGood Evils In Perl
Good Evils In PerlKang-min Liu
 
Building and Distributing PostgreSQL Extensions Without Learning C
Building and Distributing PostgreSQL Extensions Without Learning CBuilding and Distributing PostgreSQL Extensions Without Learning C
Building and Distributing PostgreSQL Extensions Without Learning CDavid Wheeler
 
Adventures in Optimization
Adventures in OptimizationAdventures in Optimization
Adventures in OptimizationDavid Golden
 
Xlab #1: Advantages of functional programming in Java 8
Xlab #1: Advantages of functional programming in Java 8Xlab #1: Advantages of functional programming in Java 8
Xlab #1: Advantages of functional programming in Java 8XSolve
 
Creating own language made easy
Creating own language made easyCreating own language made easy
Creating own language made easyIngvar Stepanyan
 

What's hot (20)

Memory Manglement in Raku
Memory Manglement in RakuMemory Manglement in Raku
Memory Manglement in Raku
 
Perl6 in-production
Perl6 in-productionPerl6 in-production
Perl6 in-production
 
Perl.Hacks.On.Vim
Perl.Hacks.On.VimPerl.Hacks.On.Vim
Perl.Hacks.On.Vim
 
Object Trampoline: Why having not the object you want is what you need.
Object Trampoline: Why having not the object you want is what you need.Object Trampoline: Why having not the object you want is what you need.
Object Trampoline: Why having not the object you want is what you need.
 
DBIx::Class introduction - 2010
DBIx::Class introduction - 2010DBIx::Class introduction - 2010
DBIx::Class introduction - 2010
 
DBIx::Class beginners
DBIx::Class beginnersDBIx::Class beginners
DBIx::Class beginners
 
Perl
PerlPerl
Perl
 
The Joy of Smartmatch
The Joy of SmartmatchThe Joy of Smartmatch
The Joy of Smartmatch
 
Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)
 
Perl6 grammars
Perl6 grammarsPerl6 grammars
Perl6 grammars
 
Perl 6 by example
Perl 6 by examplePerl 6 by example
Perl 6 by example
 
Short Introduction To "perl -d"
Short Introduction To "perl -d"Short Introduction To "perl -d"
Short Introduction To "perl -d"
 
SPL: The Missing Link in Development
SPL: The Missing Link in DevelopmentSPL: The Missing Link in Development
SPL: The Missing Link in Development
 
Introduction to Perl - Day 1
Introduction to Perl - Day 1Introduction to Perl - Day 1
Introduction to Perl - Day 1
 
Simple Ways To Be A Better Programmer (OSCON 2007)
Simple Ways To Be A Better Programmer (OSCON 2007)Simple Ways To Be A Better Programmer (OSCON 2007)
Simple Ways To Be A Better Programmer (OSCON 2007)
 
Good Evils In Perl
Good Evils In PerlGood Evils In Perl
Good Evils In Perl
 
Building and Distributing PostgreSQL Extensions Without Learning C
Building and Distributing PostgreSQL Extensions Without Learning CBuilding and Distributing PostgreSQL Extensions Without Learning C
Building and Distributing PostgreSQL Extensions Without Learning C
 
Adventures in Optimization
Adventures in OptimizationAdventures in Optimization
Adventures in Optimization
 
Xlab #1: Advantages of functional programming in Java 8
Xlab #1: Advantages of functional programming in Java 8Xlab #1: Advantages of functional programming in Java 8
Xlab #1: Advantages of functional programming in Java 8
 
Creating own language made easy
Creating own language made easyCreating own language made easy
Creating own language made easy
 

Similar to Perl6 Regexen: Reduce the line noise in your code.

Achieving Parsing Sanity In Erlang
Achieving Parsing Sanity In ErlangAchieving Parsing Sanity In Erlang
Achieving Parsing Sanity In ErlangSean Cribbs
 
Using Regular Expressions and Staying Sane
Using Regular Expressions and Staying SaneUsing Regular Expressions and Staying Sane
Using Regular Expressions and Staying SaneCarl Brown
 
Beginning Scala Svcc 2009
Beginning Scala Svcc 2009Beginning Scala Svcc 2009
Beginning Scala Svcc 2009David Pollak
 
Round PEG, Round Hole - Parsing Functionally
Round PEG, Round Hole - Parsing FunctionallyRound PEG, Round Hole - Parsing Functionally
Round PEG, Round Hole - Parsing FunctionallySean Cribbs
 
Slaying the Dragon: Implementing a Programming Language in Ruby
Slaying the Dragon: Implementing a Programming Language in RubySlaying the Dragon: Implementing a Programming Language in Ruby
Slaying the Dragon: Implementing a Programming Language in RubyJason Yeo Jie Shun
 
All I Need to Know I Learned by Writing My Own Web Framework
All I Need to Know I Learned by Writing My Own Web FrameworkAll I Need to Know I Learned by Writing My Own Web Framework
All I Need to Know I Learned by Writing My Own Web FrameworkBen Scofield
 
Swift Sequences & Collections
Swift Sequences & CollectionsSwift Sequences & Collections
Swift Sequences & CollectionsCocoaHeads France
 
Introduction to Perl
Introduction to PerlIntroduction to Perl
Introduction to PerlSway Wang
 
Petitparser at the Deep into Smalltalk School 2011
Petitparser at the Deep into Smalltalk School 2011Petitparser at the Deep into Smalltalk School 2011
Petitparser at the Deep into Smalltalk School 2011Tudor Girba
 
Codementor Office Hours with Eric Chiang: Stdin, Stdout: pup, Go, and life at...
Codementor Office Hours with Eric Chiang: Stdin, Stdout: pup, Go, and life at...Codementor Office Hours with Eric Chiang: Stdin, Stdout: pup, Go, and life at...
Codementor Office Hours with Eric Chiang: Stdin, Stdout: pup, Go, and life at...Arc & Codementor
 
My First Rails Plugin - Usertext
My First Rails Plugin - UsertextMy First Rails Plugin - Usertext
My First Rails Plugin - Usertextfrankieroberto
 
Wheels we didn't re-invent: Perl's Utility Modules
Wheels we didn't re-invent: Perl's Utility ModulesWheels we didn't re-invent: Perl's Utility Modules
Wheels we didn't re-invent: Perl's Utility ModulesWorkhorse Computing
 
Pxb For Yapc2008
Pxb For Yapc2008Pxb For Yapc2008
Pxb For Yapc2008maximgrp
 
Hacking parse.y (RubyKansai38)
Hacking parse.y (RubyKansai38)Hacking parse.y (RubyKansai38)
Hacking parse.y (RubyKansai38)ujihisa
 

Similar to Perl6 Regexen: Reduce the line noise in your code. (20)

Achieving Parsing Sanity In Erlang
Achieving Parsing Sanity In ErlangAchieving Parsing Sanity In Erlang
Achieving Parsing Sanity In Erlang
 
Using Regular Expressions and Staying Sane
Using Regular Expressions and Staying SaneUsing Regular Expressions and Staying Sane
Using Regular Expressions and Staying Sane
 
Beginning Scala Svcc 2009
Beginning Scala Svcc 2009Beginning Scala Svcc 2009
Beginning Scala Svcc 2009
 
Scala 2 + 2 > 4
Scala 2 + 2 > 4Scala 2 + 2 > 4
Scala 2 + 2 > 4
 
Round PEG, Round Hole - Parsing Functionally
Round PEG, Round Hole - Parsing FunctionallyRound PEG, Round Hole - Parsing Functionally
Round PEG, Round Hole - Parsing Functionally
 
Slaying the Dragon: Implementing a Programming Language in Ruby
Slaying the Dragon: Implementing a Programming Language in RubySlaying the Dragon: Implementing a Programming Language in Ruby
Slaying the Dragon: Implementing a Programming Language in Ruby
 
ES6 is Nigh
ES6 is NighES6 is Nigh
ES6 is Nigh
 
Unfiltered Unveiled
Unfiltered UnveiledUnfiltered Unveiled
Unfiltered Unveiled
 
All I Need to Know I Learned by Writing My Own Web Framework
All I Need to Know I Learned by Writing My Own Web FrameworkAll I Need to Know I Learned by Writing My Own Web Framework
All I Need to Know I Learned by Writing My Own Web Framework
 
SDC - Einführung in Scala
SDC - Einführung in ScalaSDC - Einführung in Scala
SDC - Einführung in Scala
 
Swift Sequences & Collections
Swift Sequences & CollectionsSwift Sequences & Collections
Swift Sequences & Collections
 
Introduction to Perl
Introduction to PerlIntroduction to Perl
Introduction to Perl
 
Petitparser at the Deep into Smalltalk School 2011
Petitparser at the Deep into Smalltalk School 2011Petitparser at the Deep into Smalltalk School 2011
Petitparser at the Deep into Smalltalk School 2011
 
Codementor Office Hours with Eric Chiang: Stdin, Stdout: pup, Go, and life at...
Codementor Office Hours with Eric Chiang: Stdin, Stdout: pup, Go, and life at...Codementor Office Hours with Eric Chiang: Stdin, Stdout: pup, Go, and life at...
Codementor Office Hours with Eric Chiang: Stdin, Stdout: pup, Go, and life at...
 
My First Ruby
My First RubyMy First Ruby
My First Ruby
 
My First Rails Plugin - Usertext
My First Rails Plugin - UsertextMy First Rails Plugin - Usertext
My First Rails Plugin - Usertext
 
Wheels we didn't re-invent: Perl's Utility Modules
Wheels we didn't re-invent: Perl's Utility ModulesWheels we didn't re-invent: Perl's Utility Modules
Wheels we didn't re-invent: Perl's Utility Modules
 
Pxb For Yapc2008
Pxb For Yapc2008Pxb For Yapc2008
Pxb For Yapc2008
 
Hacking parse.y (RubyKansai38)
Hacking parse.y (RubyKansai38)Hacking parse.y (RubyKansai38)
Hacking parse.y (RubyKansai38)
 
Spark_Documentation_Template1
Spark_Documentation_Template1Spark_Documentation_Template1
Spark_Documentation_Template1
 

More from Workhorse Computing

Paranormal statistics: Counting What Doesn't Add Up
Paranormal statistics: Counting What Doesn't Add UpParanormal statistics: Counting What Doesn't Add Up
Paranormal statistics: Counting What Doesn't Add UpWorkhorse Computing
 
The $path to knowledge: What little it take to unit-test Perl.
The $path to knowledge: What little it take to unit-test Perl.The $path to knowledge: What little it take to unit-test Perl.
The $path to knowledge: What little it take to unit-test Perl.Workhorse Computing
 
Generating & Querying Calendar Tables in Posgresql
Generating & Querying Calendar Tables in PosgresqlGenerating & Querying Calendar Tables in Posgresql
Generating & Querying Calendar Tables in PosgresqlWorkhorse Computing
 
The W-curve and its application.
The W-curve and its application.The W-curve and its application.
The W-curve and its application.Workhorse Computing
 
Shared Object images in Docker: What you need is what you want.
Shared Object images in Docker: What you need is what you want.Shared Object images in Docker: What you need is what you want.
Shared Object images in Docker: What you need is what you want.Workhorse Computing
 
Selenium sandwich-3: Being where you aren't.
Selenium sandwich-3: Being where you aren't.Selenium sandwich-3: Being where you aren't.
Selenium sandwich-3: Being where you aren't.Workhorse Computing
 
Selenium Sandwich Part 1: Data driven Selenium
Selenium Sandwich Part 1: Data driven Selenium Selenium Sandwich Part 1: Data driven Selenium
Selenium Sandwich Part 1: Data driven Selenium Workhorse Computing
 
Ethiopian multiplication in Perl6
Ethiopian multiplication in Perl6Ethiopian multiplication in Perl6
Ethiopian multiplication in Perl6Workhorse Computing
 

More from Workhorse Computing (20)

mro-every.pdf
mro-every.pdfmro-every.pdf
mro-every.pdf
 
Paranormal statistics: Counting What Doesn't Add Up
Paranormal statistics: Counting What Doesn't Add UpParanormal statistics: Counting What Doesn't Add Up
Paranormal statistics: Counting What Doesn't Add Up
 
The $path to knowledge: What little it take to unit-test Perl.
The $path to knowledge: What little it take to unit-test Perl.The $path to knowledge: What little it take to unit-test Perl.
The $path to knowledge: What little it take to unit-test Perl.
 
Unit Testing Lots of Perl
Unit Testing Lots of PerlUnit Testing Lots of Perl
Unit Testing Lots of Perl
 
Generating & Querying Calendar Tables in Posgresql
Generating & Querying Calendar Tables in PosgresqlGenerating & Querying Calendar Tables in Posgresql
Generating & Querying Calendar Tables in Posgresql
 
Effective Benchmarks
Effective BenchmarksEffective Benchmarks
Effective Benchmarks
 
The W-curve and its application.
The W-curve and its application.The W-curve and its application.
The W-curve and its application.
 
Smoking docker
Smoking dockerSmoking docker
Smoking docker
 
Getting Testy With Perl6
Getting Testy With Perl6Getting Testy With Perl6
Getting Testy With Perl6
 
Light my-fuse
Light my-fuseLight my-fuse
Light my-fuse
 
Paranormal stats
Paranormal statsParanormal stats
Paranormal stats
 
Shared Object images in Docker: What you need is what you want.
Shared Object images in Docker: What you need is what you want.Shared Object images in Docker: What you need is what you want.
Shared Object images in Docker: What you need is what you want.
 
Putting some "logic" in LVM.
Putting some "logic" in LVM.Putting some "logic" in LVM.
Putting some "logic" in LVM.
 
Selenium sandwich-3: Being where you aren't.
Selenium sandwich-3: Being where you aren't.Selenium sandwich-3: Being where you aren't.
Selenium sandwich-3: Being where you aren't.
 
Selenium sandwich-2
Selenium sandwich-2Selenium sandwich-2
Selenium sandwich-2
 
Selenium Sandwich Part 1: Data driven Selenium
Selenium Sandwich Part 1: Data driven Selenium Selenium Sandwich Part 1: Data driven Selenium
Selenium Sandwich Part 1: Data driven Selenium
 
Docker perl build
Docker perl buildDocker perl build
Docker perl build
 
Designing net-aws-glacier
Designing net-aws-glacierDesigning net-aws-glacier
Designing net-aws-glacier
 
Ethiopian multiplication in Perl6
Ethiopian multiplication in Perl6Ethiopian multiplication in Perl6
Ethiopian multiplication in Perl6
 
Lies, Damn Lies, and Benchmarks
Lies, Damn Lies, and BenchmarksLies, Damn Lies, and Benchmarks
Lies, Damn Lies, and Benchmarks
 

Recently uploaded

CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilV3cube
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 

Recently uploaded (20)

CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of Brazil
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 

Perl6 Regexen: Reduce the line noise in your code.

  • 1. Perl6 Regexen: Reducing line noise in your code. Steven Lembark Workhorse Computing lembark@wrkhors.com
  • 2. The difference … prefer readabity over compactness. – Larry Wall Regexes you can read. Code you can maintain. Do what I mean need.
  • 3. What is line noise? Random garbage on the screen. Due to signal noise. Eliminted by error correcting modems.
  • 4. More effective use of Regex Daisy-chaining tokens. RX-from-hell with alternations. Q: Why? A: Parsing.
  • 5. What we had to do. Without grammars. Parsing order implicit in RX, code. Branching logic on matched tokens. Nested-if in for loops.
  • 6. Parse *.ini file my $header = qr{ ^ h* [ (?<name> [^][]+ ) ] h* $ }xm; my $property = qr{ ^ h* (?<key> .+? ) h* = h* (?<value> .+ ) $ }xm; my $comment = qr{ ^ h* # }xm; my $empty_line = qr{ ^ h* $}xm; Regexen tokenize input.
  • 7. Parse *.ini for my $nextline (readline($INI_FILE)) { # If it's a header line, start a new section... if ($nextline =~ /$header/) { $section = $config{ $+{name} } //= {}; } # If it's a property, add the key and value to the current section... elsif ($nextline =~ /$property/) { $section->{ $+{key} } = $+{value}; } # Ignore comments or empty lines elsif ($nextline =~ /$comment|$empty_line/) { # Do nothing } # Report anything else as a probable error... else { warn "Invalid data in INI file at line $.n" . "t$nextlinen"; } } Code processes it.
  • 8. Maintainable? Inter-related order of code and rx. Code changes affect rx? Rx changes affect code? Find out: Try it and see...
  • 9. Perl6: Grammars Structure in one place. Declarative. No iterative code.
  • 10. Tokens & Structure grammar INI { token TOP { <section>* } token section { [ ^ | <header> ] <block> } token header { '[' $<ID> = <-[ [ ] n ]>+ ']' h* n } token block { [ <property> | <.emptylines> | <.comment> ]* } token property { h* $<name>=N+? h* '=' h* $<value>=N+ n } token comment { ^^ h* '#' N* n } token emptylines { [ ^^ h* n ]+ } }
  • 11. Tokens & Structure grammar INI { token TOP { <section>* } token section { [ ^ | <header> ] <block> } token header { '[' $<ID> = <-[ [ ] n ]>+ ']' h* n } token block { [ <property> | <.emptylines> | <.comment> ]* } token property { h* $<name>=N+? h* '=' h* $<value>=N+ n } token comment { ^^ h* '#' N* n } token emptylines { [ ^^ h* n ]+ } }
  • 12. Tokens & Structure grammar INI { token TOP { <section>* } token section { [ ^ | <header> ] <block> } token header { '[' $<ID> = <-[ [ ] n ]>+ ']' h* n } token block { [ <property> | <.emptylines> | <.comment> ]* } token property { h* $<name>=N+? h* '=' h* $<value>=N+ n } token comment { ^^ h* '#' N* n } token emptylines { [ ^^ h* n ]+ } }
  • 13. Process the content class INI::hash_builder { method TOP ($/) { make %( $<section>».ast ) } method section ($/) { make ~($<header><ID>//'') => $<block>.ast } method block ($/) { make %( $<property>».ast ) } method property ($/) { make ~$<name> => ~$<value> } } my %config = INI.parsefile( 'example.ini', :actions(INI::hash_builder) ).ast; say %config.perl;
  • 14. Process the content class INI::hash_builder { method TOP ($/) { make %( $<section>».ast ) } method section ($/) { make ~($<header><ID>//'') => $<block>.ast } method block ($/) { make %( $<property>».ast ) } method property ($/) { make ~$<name> => ~$<value> } } my %config = INI.parsefile( 'example.ini', :actions(INI::hash_builder) ).ast; say %config.perl;
  • 15. Process the content class INI::hash_builder { method TOP ($/) { make %( $<section>».ast ) } method section ($/) { make ~($<header><ID>//'') => $<block>.ast } method block ($/) { make %( $<property>».ast ) } method property ($/) { make ~$<name> => ~$<value> } } my %config = INI.parsefile( 'example.ini', :actions(INI::hash_builder) ).ast; say %config.perl;
  • 16. Process the content class INI::hash_builder { method TOP ($/) { make %( $<section>».ast ) } method section ($/) { make ~($<header><ID>//'') => $<block>.ast } method block ($/) { make %( $<property>».ast ) } method property ($/) { make ~$<name> => ~$<value> } } my %config = INI.parsefile( 'example.ini', :actions(INI::hash_builder) ).ast; say %config.perl;
  • 17. Process the content class INI::hash_builder { method TOP ($/) { make %( $<section>».ast ) } method section ($/) { make ~($<header><ID>//'') => $<block>.ast } method block ($/) { make %( $<property>».ast ) } method property ($/) { make ~$<name> => ~$<value> } } my %config = INI.parsefile( 'example.ini', :actions(INI::hash_builder) ).ast; say %config.perl;
  • 18. Care to guess what this does? /{~}!@#$%^(&*)-+=[/]:;"'<.,>?/
  • 19. Care to guess what this does? Q: Which char's match themselves? /{~}!@#$%^(&*)-+=[/]:;"'<.,>?/
  • 20. Care to guess what this does? Q: Which char's match themselves? A: None, in Perl6, since they are punctuation. /{~}!@#$%^(&*)-+=[/]:;"'<.,>?/
  • 21. Saner metachars Match integers enclosed in braces. Perl 5: / [ s* (?: d+ (?: s* , s* d+ )* s* )? ] /x
  • 22. Saner metachars Match integers enclosed in braces. Perl 5: / [ s* (?: d+ (?: s* , s* d+ )* s* )? ] /x Perl 6: / :s '[' [d+]* % ',' ']' /
  • 23. Saner metachars Match integers enclosed in braces. Perl 5: / [ s* (?: d+ (?: s* , s* d+ )* s* )? ] /x Perl 6: / :s '[' [d+]* % ',' ']' / Consume WS
  • 24. Saner metachars Match integers enclosed in braces. Perl 5: / [ s* (?: d+ (?: s* , s* d+ )* s* )? ] /x Perl 6: / :s '[' [d+]* % ',' ']' / Literals
  • 25. Saner metachars Match integers enclosed in braces. Perl 5: / [ s* (?: d+ (?: s* , s* d+ )* s* )? ] /x Perl 6: / :s '[' [d+]* % ',' ']' / Non-capturing match
  • 26. Saner metachars Match integers enclosed in braces. Perl 5: / [ s* (?: d+ (?: s* , s* d+ )* s* )? ] /x Perl 6: / :s '[' [d+]* % ',' ']' / Separator
  • 27. Aside: Future speed Perl6 regexen execute as DFA where possible. Opportunity for much faster execution. For some definition of ...
  • 28. Aside: Future speed Perl6 regexen execute as DFA where possible. Also benefit from saner results. DFA more likely to Do What I Mean. Alternations match best, not first match.
  • 29. Smartest matching Perl 5: say $& if 'Which regex engine is smartest?' =~ /smart|smarter|smartest/;
  • 30. Smartest matching Perl 5: say $& if 'Which regex engine is smartest?' =~ /smart|smarter|smartest/;
  • 31. Smartest matching Perl 5: say $& if 'Which regex engine is smartest?' =~ /smart|smarter|smartest/; Perl 6: say $/ if 'Which regex engine is smartest?' ~~ /smart|smarter|smartest/;
  • 32. Smartest matching Perl 5: say $& if 'Which regex engine is smartest?' =~ /smart|smarter|smartest/; Perl 6: say $/ if 'Which regex engine is smartest?' ~~ /smart|smarter|smartest/;
  • 33. Smartest matching Perl 5: say $& if 'Which regex engine is smartest?' =~ /smart|smarter|smartest/; Perl 6: say $/ if 'Which regex engine is smartest?' ~~ /smart|smarter|smartest/;
  • 34. Perl5 nested structure #! /usr/bin/env perl use 5.010; # We're going to need this to extract hierarchical data structures... our @stack = []; my $LIST = qr{ # Match this... (?&NESTED) # Which is defined as... (?(DEFINE) (?<NESTED> # Keep track of recursions on a stack... (?{ local @::stack = (@::stack, []); }) # Match a list of items... [ s* (?> (?&ITEM) (?: s* , s* (?&ITEM) )*+ )? s* ] # Pop the stack and add that frame to the growing data structure... (?{ local @::stack = @::stack; my $nested = pop @stack; push @{$::stack[-1]}, $nested; }) ) # For each item, push it onto the stack if it's a leaf node... (?<ITEM> (d+) (?{ push @{$stack[-1]}, $^N }) | (?&NESTED) ) ) }x; # Match, extracting a data structure... '[1,2,[3,3,[4,4]],5]' =~ /$LIST/; # Retrieve the data structure... my $parse_tree = pop @stack; # Show it... use Data::Dumper 'Dumper'; say Dumper($parse_tree);
  • 35. Perl6 nested grammar #! /usr/bin/env perl6 use v6; # Define the structure of a list... grammar LIST { rule TOP { '[' <ITEM>* % ',' ']' } token ITEM { d+ | <TOP> } } # Define how to convert list elements to a suitable data structure... class TREE { method TOP ($/) { make [ $<ITEM>».ast ] } method ITEM ($/) { make $<TOP>.ast // +$/ } } # Parse, extracting the data structure... my $parse_tree = LIST.parse('[1,2,[3,3,[4,4]],5]', :actions(TREE)).ast; # Show what we got... say $parse_tree.perl;
  • 36. Perl6 nested regex #! /usr/bin/env perl6 use v6; '[1,2,[3,3,[4,4]],5]' ~~ /'[' [ (d+) | $<0>=<~~> ]* % ',' ']' /; say $/;
  • 37. Perl6 nested regex #! /usr/bin/env perl6 use v6; '[1,2,[3,3,[4,4]],5]' ~~ /'[' [ (d+) | $<0>=<~~> ]* % ',' ']' /; say $/;
  • 39. In Perl6 Regexen are saner. Grammars offer cleaner code.
  • 40. In Perl6 Regexen are saner. Grammars offer cleaner code. Smart matching works.
  • 41. In Perl6 Regexen are saner. Grammars offer cleaner code. Smart matching works. Objects have useful methods.
  • 42. In Perl6 Regexen are saner. Grammars offer cleaner code. Smart matching works. Objects have useful methods. It's new.
  • 43. In Perl6 Regexen are saner. Grammars offer cleaner code. Smart matching works. Objects have useful methods. It's worth learning.