Skip to content

Instantly share code, notes, and snippets.

@librasteve
Last active December 1, 2023 14:11
Show Gist options
  • Save librasteve/86641c9e2d5f8b95b6e8752cc41ffa07 to your computer and use it in GitHub Desktop.
Save librasteve/86641c9e2d5f8b95b6e8752cc41ffa07 to your computer and use it in GitHub Desktop.
The Elves go to Grammar School
# The Elves go to Grammar School
#!/usr/bin/env raku
use v6.d;
use lib '../lib';
use Data::Dump::Tree;
use Grammar::Tracer;
my ($address,$match);
my @street-types = <Street St Avenue Ave Av Road Rd Lane Ln Boulevard Blvd>;
role Address::Grammar::Base {
token street {
^^ [<number> ','? <.ws>]? <plain-words> <.ws> <street-type> '.'? $$
}
token number {
\d*
}
token plain-words {
<plain-word>+ % \h
}
token plain-word {
\w+ <?{ "$/" !~~ /@street-types/ }>
}
token street-type {
@street-types
}
token town { <whole-line> }
token city { <whole-line> }
token county { <whole-line> }
token country { <whole-line> }
token whole-line {
^^ \V* $$
}
}
grammar AddressUSA::Grammar does Address::Grammar::Base {
token TOP {
<street> \v
<city> \v
<state-zip> \v?
[ <country> \v? ]?
}
token state-zip {
^^ <state> <.ws>? <zipcode> $$ #<.ws> is [\h* | \v]
}
token state {
\w \w
}
token zipcode {
\d ** 5
}
}
class AddressUSA {
has Str $.street;
has Str $.city;
has Str $.state;
has Str $.zipcode;
has Str $.country = 'USA';
}
class AddressUSA::Actions {
method TOP($/) {
my %a;
%a<street> = $_ with $<street>.made;
%a<city> = $_ with $<city>.made;
%a<state> = $_ with $<state-zip><state>.made;
%a<zipcode> = $_ with $<state-zip><zipcode>.made;
%a<country> = $_ with $<country>.made;
make AddressUSA.new: |%a
}
method street($/) { make ~$/ }
method city($/) { make ~$/ }
method state($/) { make ~$/ }
method zipcode($/) { make ~$/ }
method country($/) { make ~$/ }
}
$address = q:to/END/;
123, Main St.,
Springfield,
IL 62704
USA
END
$address ~~ s:g/','$$//;
$address ~~ s:g/<['\-%]>//;
$address .= chomp;
$match = AddressUSA::Grammar.parse($address, :actions(AddressUSA::Actions));
say ~$match;
say $match;
ddt $match.made;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment