Skip to content

Instantly share code, notes, and snippets.

@mackee
Created January 21, 2019 04:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mackee/a6d29a530e303820679db7cf35da6e32 to your computer and use it in GitHub Desktop.
Save mackee/a6d29a530e303820679db7cf35da6e32 to your computer and use it in GitHub Desktop.
A visualization of PPR.pm for help us understand
#!/usr/bin/env perl
use 5.28.0;
use warnings;
use utf8;
use Path::Tiny;
use PPR;
use PPIx::Regexp::Dumper;
my $file = path("PPR/lib/PPR.pm");
my $stmt_regexp = qr{
our (?&PerlOWS) \$GRAMMAR (?&PerlOWS) = (?&PerlOWS) ((?&PerlRegex))
$PPR::GRAMMAR
}x;
my ($regexp) = grep { defined } $file->slurp =~ /$stmt_regexp/gcx;
my $tree = PPIx::Regexp->new($regexp);
my $bucket = {};
traverse($tree, $bucket);
my %decls = map { $_ => [sort { $a cmp $b } keys $bucket->{$_}->%*] } keys %$bucket;
#use DDP; p %decls;
print_tree(\%decls);
sub traverse {
my ($tree, $bucket, $name) = @_;
my $literal = "";
for my $child ($tree->children) {
if (ref $child eq "PPIx::Regexp::Token::Literal") {
$literal .= $child->content;
}
elsif (ref $child eq "PPIx::Regexp::Token::Whitespace") {
# skip
}
else {
if (length($literal) > 1 && $literal ne '\n') {
$bucket->{$name}->{'"' . $literal . '"'} = 1;
}
$literal = "";
}
if (ref $child eq "PPIx::Regexp::Token::Recursion") {
next if $child->name eq "PerlOWS";
$bucket->{$name}->{$child->content} = 1;
}
if ($child->can("children")) {
my $next_name = $name;
if (ref $child eq "PPIx::Regexp::Structure::NamedCapture") {
next if $child->name =~ /^PPR_/;
$next_name = $name ? $name . " > (?&" . $child->name . ")" : "(?&" . $child->name . ")";
#PPIx::Regexp::Dumper->new($child)->print;
}
traverse($child, $bucket, $next_name);
}
}
}
sub print_tree {
my $decls = shift;
for my $key (sort { $a cmp $b } keys %$decls) {
my $children = $decls->{$key};
say $key;
for my $i (0..scalar(@$children) - 1) {
print $i == (scalar(@$children) - 1) ? "`-- " : "|-- ";
say $children->[$i];
}
say "";
}
}
(?&PerlAnonymousArray)
|-- "\["
`-- (?&PerlExpression)
(?&PerlAnonymousHash)
|-- "\{"
`-- (?&PerlExpression)
(?&PerlAnonymousSubroutine)
|-- "\("
|-- "\)"
|-- "sub"
|-- (?&PerlAttributes)
|-- (?&PerlBlock)
`-- (?&PerlParenthesesList)
(?&PerlArrayAccess)
|-- "->"
|-- "\$\*"
|-- "\*"
|-- (?&PerlArrayIndexer)
|-- (?&PerlHashIndexer)
|-- (?&PerlParenthesesList)
`-- (?&PerlVariableArray)
(?&PerlArrayAccessNoSpace)
|-- "->"
|-- "\$\*"
|-- "\*"
|-- (?&PerlArrayIndexer)
|-- (?&PerlHashIndexer)
|-- (?&PerlParenthesesList)
`-- (?&PerlVariableArrayNoSpace)
(?&PerlArrayAccessNoSpaceNoArrow)
|-- (?&PerlArrayIndexer)
|-- (?&PerlHashIndexer)
|-- (?&PerlParenthesesList)
`-- (?&PerlVariableArray)
(?&PerlArrayIndexer)
|-- "\["
`-- (?&PerlExpression)
(?&PerlAssignment)
|-- (?&PerlAssignmentOperator)
`-- (?&PerlConditionalExpression)
(?&PerlAttributes)
|-- (?&PPR_quotelike_body)
|-- (?&PerlIdentifier)
`-- (?&PerlNWS)
(?&PerlBareword)
|-- "::"
|-- "END"
|-- "__"
|-- "for"
|-- "given"
|-- "if"
|-- "no"
|-- "sub"
|-- "unless"
|-- "until"
|-- "use"
|-- "when"
|-- "while"
|-- (?&PPR_named_op)
`-- (?&PerlEndOfLine)
(?&PerlBinaryExpression)
|-- (?&PerlInfixBinaryOperator)
`-- (?&PerlPrefixPostfixTerm)
(?&PerlBlock)
|-- "\{"
`-- (?&PerlStatementSequence)
(?&PerlBuiltinFunction)
|-- "ach"
|-- "ack"
|-- "ad"
|-- "addr"
|-- "al"
|-- "aller"
|-- "alues"
|-- "ate"
|-- "ay"
|-- "bm"
|-- "by"
|-- "byn"
|-- "cala"
|-- "call"
|-- "ccept"
|-- "ce"
|-- "cket"
|-- "close"
|-- "cntl"
|-- "ct"
|-- "ctl"
|-- "cv"
|-- "def"
|-- "dex"
|-- "dir"
|-- "do"
|-- "ec"
|-- "ed"
|-- "eername"
|-- "ek"
|-- "ell"
|-- "en"
|-- "ent"
|-- "erv"
|-- "erven"
|-- "et"
|-- "eys"
|-- "fined"
|-- "get"
|-- "gid"
|-- "gr"
|-- "grp"
|-- "hex"
|-- "hos"
|-- "host"
|-- "ie"
|-- "ileno"
|-- "in"
|-- "index"
|-- "intf"
|-- "iority"
|-- "ipe"
|-- "it"
|-- "join"
|-- "kdir"
|-- "larm"
|-- "lect"
|-- "leep"
|-- "less"
|-- "li"
|-- "lin"
|-- "line"
|-- "lob"
|-- "login"
|-- "lose"
|-- "mask"
|-- "mdir"
|-- "mes"
|-- "mode"
|-- "mport"
|-- "mtime"
|-- "nam"
|-- "name"
|-- "nd"
|-- "net"
|-- "next"
|-- "ntarray"
|-- "ock"
|-- "open"
|-- "or"
|-- "oto"
|-- "ototype"
|-- "pen"
|-- "pipe"
|-- "qrt"
|-- "quir"
|-- "quotemeta"
|-- "rand"
|-- "rcv"
|-- "read"
|-- "roto"
|-- "seek"
|-- "serv"
|-- "set"
|-- "sg"
|-- "shift"
|-- "sta"
|-- "sten"
|-- "sts"
|-- "tan2"
|-- "tinue"
|-- "turn"
|-- "umber"
|-- "ump"
|-- "utdown"
|-- "val"
|-- "vers"
|-- "went"
|-- "winddir"
`-- "write"
(?&PerlCall)
|-- "\("
|-- "\)"
|-- (?&PPR_filetest_name)
|-- (?&PPR_indirect_obj)
|-- (?&PPR_non_reserved_identifier)
|-- (?&PerlBlock)
|-- (?&PerlBuiltinFunction)
|-- (?&PerlCall)
|-- (?&PerlComma)
|-- (?&PerlCommaList)
|-- (?&PerlExpression)
|-- (?&PerlNWS)
|-- (?&PerlPrefixPostfixTerm)
|-- (?&PerlQualifiedIdentifier)
`-- (?&PerlVariableScalar)
(?&PerlCommaList)
|-- (?&PerlAssignment)
`-- (?&PerlComma)
(?&PerlContextualQuotelikeM) > (?&PerlContextualMatch)
|-- "=>"
|-- "for"
|-- "if"
|-- "unless"
|-- "until"
|-- "while"
|-- (?&PerlInfixBinaryOperator)
`-- (?&PerlLowPrecedenceInfixOperator)
(?&PerlContextualQuotelikeM) > (?&PerlContextualMatch) > (?&PerlQuotelikeM) > (?&PerlMatch)
|-- "\/"
|-- "\/\/"
`-- (?&PPR_quotelike_body_interpolated)
(?&PerlContextualRegex)
|-- (?&PerlContextualMatch)
`-- (?&PerlQuotelikeQR)
(?&PerlControlBlock)
|-- "BEGIN"
|-- "CHECK"
|-- "END"
|-- "INIT"
|-- "\\"
|-- "continue"
|-- "default"
|-- "else"
|-- "elsif"
|-- "for"
|-- "given"
|-- "if"
|-- "my"
|-- "our"
|-- "while"
|-- (?&PPR_three_part_list)
|-- (?&PerlBlock)
|-- (?&PerlParenthesesList)
|-- (?&PerlPodSequence)
|-- (?&PerlQuotelikeQW)
|-- (?&PerlVariableArray)
|-- (?&PerlVariableHash)
`-- (?&PerlVariableScalar)
(?&PerlDiamondOperator)
|-- "<<>>"
|-- "=>"
|-- "for"
|-- "if"
|-- "unless"
|-- "until"
|-- "while"
|-- (?&PPR_balanced_angles)
|-- (?&PerlInfixBinaryOperator)
`-- (?&PerlLowPrecedenceInfixOperator)
(?&PerlDoBlock)
|-- "do"
`-- (?&PerlBlock)
(?&PerlDocument)
|-- "\x{FEFF}"
`-- (?&PerlStatementSequence)
(?&PerlEvalBlock)
|-- "eval"
`-- (?&PerlBlock)
(?&PerlExpression)
|-- (?&PerlLowPrecedenceInfixOperator)
`-- (?&PerlLowPrecedenceNotExpression)
(?&PerlFormat)
|-- "\$"
|-- "\."
|-- "\@"
|-- "format"
|-- (?&PPR_newline_and_heredoc)
|-- (?&PerlArrayAccessNoSpace)
|-- (?&PerlEndOfLine)
|-- (?&PerlNWS)
|-- (?&PerlQualifiedIdentifier)
`-- (?&PerlScalarAccessNoSpace)
(?&PerlHashAccess)
|-- "->"
|-- "\$\*"
|-- "\*"
|-- (?&PerlArrayIndexer)
|-- (?&PerlHashIndexer)
|-- (?&PerlParenthesesList)
`-- (?&PerlVariableHash)
(?&PerlHashIndexer)
|-- "\{"
|-- (?&PerlExpression)
`-- (?&PerlIdentifier)
(?&PerlHeredoc)
|-- "<<"
|-- "\$"
|-- "\@"
|-- "\\"
|-- (?&PerlArrayAccessNoSpace)
`-- (?&PerlScalarAccessNoSpace)
(?&PerlHeredoc) > (?&_heredoc_terminator)
|-- "\\"
`-- (?&PerlIdentifier)
(?&PerlInfixBinaryOperator)
|-- "<=>"
|-- ">="
|-- "\^"
|-- "cmp"
|-- "eq"
`-- "ne"
(?&PerlLabel)
`-- (?&PerlIdentifier)
(?&PerlList)
|-- (?&PerlCommaList)
`-- (?&PerlParenthesesList)
(?&PerlLiteral)
|-- (?&PerlBareword)
|-- (?&PerlNumber)
|-- (?&PerlQuotelikeQR)
|-- (?&PerlQuotelikeQW)
`-- (?&PerlString)
(?&PerlLowPrecedenceInfixOperator)
|-- "and"
`-- "or"
(?&PerlLowPrecedenceNotExpression)
|-- "not"
`-- (?&PerlCommaList)
(?&PerlLvalue)
|-- "\("
|-- "\\"
|-- (?&PerlComma)
`-- (?&PerlIdentifier)
(?&PerlNWS)
|-- "END"
|-- "__"
`-- (?&PPR_newline_and_heredoc)
(?&PerlNullaryBuiltinFunction)
|-- "end"
|-- "ent"
|-- "fork"
|-- "get"
|-- "hos"
|-- "ntarray"
|-- "roto"
|-- "serv"
|-- "times"
`-- "wa"
(?&PerlNumber)
|-- "\."
|-- (?&PPR_b_digit_seq)
|-- (?&PPR_digit_seq)
|-- (?&PPR_o_digit_seq)
`-- (?&PPR_x_digit_seq)
(?&PerlOWS)
|-- "END"
|-- "__"
`-- (?&PPR_newline_and_heredoc)
(?&PerlOldQualifiedIdentifier)
`-- "::"
(?&PerlPackageDeclaration)
|-- "\}"
|-- "package"
|-- (?&PerlBlock)
|-- (?&PerlNWS)
|-- (?&PerlQualifiedIdentifier)
`-- (?&PerlVersionNumber)
(?&PerlParenthesesList)
|-- "\("
`-- (?&PerlExpression)
(?&PerlPod)
`-- "=cut"
(?&PerlPodSequence)
`-- (?&PerlPod)
(?&PerlPostfixUnaryOperator)
`-- "\+\+"
(?&PerlPrefixPostfixTerm)
|-- "->"
|-- "\*"
|-- (?&PerlArrayIndexer)
|-- (?&PerlHashIndexer)
|-- (?&PerlParenthesesList)
|-- (?&PerlPostfixUnaryOperator)
|-- (?&PerlPrefixUnaryOperator)
|-- (?&PerlQualifiedIdentifier)
|-- (?&PerlTerm)
`-- (?&PerlVariableScalar)
(?&PerlPrefixUnaryOperator)
|-- "--"
|-- "\+\+"
`-- (?&PPR_filetest_name)
(?&PerlQualifiedIdentifier)
`-- "::"
(?&PerlQuotelike)
|-- (?&PerlContextualMatch)
|-- (?&PerlQuotelikeQR)
|-- (?&PerlQuotelikeQW)
|-- (?&PerlQuotelikeQX)
|-- (?&PerlQuotelikeS)
|-- (?&PerlQuotelikeTR)
`-- (?&PerlString)
(?&PerlQuotelikeQ)
|-- "\\"
`-- (?&PPR_quotelike_body)
(?&PerlQuotelikeQQ)
|-- "\\"
|-- "qq"
`-- (?&PPR_quotelike_body_interpolated)
(?&PerlQuotelikeQR)
|-- "qr"
`-- (?&PPR_quotelike_body_interpolated)
(?&PerlQuotelikeQW)
|-- "qw"
`-- (?&PPR_quotelike_body)
(?&PerlQuotelikeQX)
|-- "\\"
|-- "qx"
|-- (?&PPR_quotelike_body)
`-- (?&PPR_quotelike_body_interpolated)
(?&PerlQuotelikeS) > (?&PerlSubstitution)
|-- (?&PPR_quotelike_body_interpolated)
|-- (?&PPR_quotelike_body_interpolated_unclosed)
`-- (?&PPR_quotelike_s_e_check)
(?&PerlQuotelikeTR) > (?&PerlTransliteration)
|-- "tr"
|-- (?&PPR_quotelike_body_interpolated)
`-- (?&PPR_quotelike_body_interpolated_unclosed)
(?&PerlRegex)
|-- (?&PerlMatch)
`-- (?&PerlQuotelikeQR)
(?&PerlReturnExpression)
|-- "return"
`-- (?&PerlExpression)
(?&PerlReturnStatement)
|-- "\}"
|-- "return"
`-- (?&PerlExpression)
(?&PerlScalarAccess)
|-- "->"
|-- "\$\*"
|-- "\*"
|-- (?&PerlArrayIndexer)
|-- (?&PerlHashIndexer)
|-- (?&PerlParenthesesList)
`-- (?&PerlVariableScalar)
(?&PerlScalarAccessNoSpace)
|-- "->"
|-- "\$\*"
|-- "\*"
|-- (?&PerlArrayIndexer)
|-- (?&PerlHashIndexer)
|-- (?&PerlParenthesesList)
`-- (?&PerlVariableScalarNoSpace)
(?&PerlScalarAccessNoSpaceNoArrow)
|-- (?&PerlArrayIndexer)
|-- (?&PerlHashIndexer)
|-- (?&PerlParenthesesList)
`-- (?&PerlVariableScalarNoSpace)
(?&PerlScalarExpr) > (?&PerlConditionalExpression)
|-- "\?"
|-- (?&PerlAssignment)
|-- (?&PerlBinaryExpression)
`-- (?&PerlConditionalExpression)
(?&PerlStatement)
|-- "AUTOLOAD"
|-- "DESTROY"
|-- "\("
|-- "\)"
|-- "\.\.\."
|-- "\}"
|-- "package"
|-- "sub"
|-- "use"
|-- (?&PerlAttributes)
|-- (?&PerlBlock)
|-- (?&PerlComma)
|-- (?&PerlControlBlock)
|-- (?&PerlExpression)
|-- (?&PerlFormat)
|-- (?&PerlInfixBinaryOperator)
|-- (?&PerlKeyword)
|-- (?&PerlLabel)
|-- (?&PerlNWS)
|-- (?&PerlOldQualifiedIdentifier)
|-- (?&PerlParenthesesList)
|-- (?&PerlPodSequence)
|-- (?&PerlQualifiedIdentifier)
|-- (?&PerlStatementModifier)
`-- (?&PerlVersionNumber)
(?&PerlStatementModifier)
|-- "for"
|-- "if"
|-- "unless"
|-- "until"
|-- "while"
`-- (?&PerlExpression)
(?&PerlStatementSequence)
|-- (?&PerlPodSequence)
`-- (?&PerlStatement)
(?&PerlString)
|-- "\\"
|-- "qq"
|-- (?&PPR_quotelike_body)
|-- (?&PPR_quotelike_body_interpolated)
|-- (?&PerlHeredoc)
`-- (?&PerlVString)
(?&PerlSubroutineDeclaration)
|-- "AUTOLOAD"
|-- "DESTROY"
|-- "\("
|-- "\)"
|-- "sub"
|-- (?&PerlAttributes)
|-- (?&PerlBlock)
|-- (?&PerlOldQualifiedIdentifier)
`-- (?&PerlParenthesesList)
(?&PerlTerm)
|-- "do"
|-- "my"
|-- "return"
|-- "state"
|-- (?&PerlAnonymousArray)
|-- (?&PerlAnonymousHash)
|-- (?&PerlAnonymousSubroutine)
|-- (?&PerlArrayIndexer)
|-- (?&PerlAttributes)
|-- (?&PerlBlock)
|-- (?&PerlCall)
|-- (?&PerlContextualMatch)
|-- (?&PerlDiamondOperator)
|-- (?&PerlExpression)
|-- (?&PerlHashIndexer)
|-- (?&PerlLiteral)
|-- (?&PerlLvalue)
|-- (?&PerlNullaryBuiltinFunction)
|-- (?&PerlParenthesesList)
|-- (?&PerlQualifiedIdentifier)
|-- (?&PerlQuotelikeQX)
|-- (?&PerlQuotelikeS)
|-- (?&PerlQuotelikeTR)
|-- (?&PerlTypeglob)
`-- (?&PerlVariable)
(?&PerlTermPostfixDereference)
|-- "->"
|-- "\*"
|-- (?&PerlArrayIndexer)
|-- (?&PerlHashIndexer)
|-- (?&PerlParenthesesList)
|-- (?&PerlQualifiedIdentifier)
`-- (?&PerlVariableScalar)
(?&PerlTypeglob)
|-- "->"
|-- "\$\*"
|-- "\*"
|-- "\^"
|-- "\{\^"
|-- "\}"
|-- "]["
|-- (?&PerlArrayIndexer)
|-- (?&PerlBlock)
|-- (?&PerlHashIndexer)
|-- (?&PerlOldQualifiedIdentifier)
|-- (?&PerlParenthesesList)
`-- (?&PerlVariableScalar)
(?&PerlUseStatement)
|-- "\}"
|-- "use"
|-- (?&PerlComma)
|-- (?&PerlExpression)
|-- (?&PerlInfixBinaryOperator)
|-- (?&PerlNWS)
|-- (?&PerlPodSequence)
|-- (?&PerlQualifiedIdentifier)
`-- (?&PerlVersionNumber)
(?&PerlVString)
|-- "\."
`-- (?&PPR_digit_seq)
(?&PerlVariable)
|-- (?&PerlArrayAccess)
|-- (?&PerlHashAccess)
`-- (?&PerlScalarAccess)
(?&PerlVariableArray)
|-- "::"
|-- "\$"
|-- "\@"
|-- "\^"
|-- "\{\^"
|-- "\}"
|-- "]["
|-- (?&PerlBlock)
`-- (?&PerlOldQualifiedIdentifier)
(?&PerlVariableArrayNoSpace)
|-- "::"
|-- "\@"
|-- "\^"
|-- "\{\^"
|-- "\}"
|-- "]["
|-- (?&PerlBlock)
`-- (?&PerlOldQualifiedIdentifier)
(?&PerlVariableDeclaration)
|-- "my"
|-- "state"
|-- (?&PerlAttributes)
|-- (?&PerlLvalue)
`-- (?&PerlQualifiedIdentifier)
(?&PerlVariableHash)
|-- "::"
|-- "\$"
|-- "\^"
|-- "\{\^"
|-- "\}"
|-- "]["
|-- (?&PerlBlock)
`-- (?&PerlOldQualifiedIdentifier)
(?&PerlVariableScalar)
|-- "::"
|-- "\$"
|-- "\$\$"
|-- "\$\{"
|-- "\$^"
|-- "\^"
|-- "\{"
|-- "\{\^"
|-- "\}"
|-- "]["
|-- (?&PerlBlock)
`-- (?&PerlOldQualifiedIdentifier)
(?&PerlVariableScalarNoSpace)
|-- "::"
|-- "\$"
|-- "\$\$"
|-- "\$\{"
|-- "\$^"
|-- "\^"
|-- "\{"
|-- "\{\^"
|-- "\}"
|-- "]["
|-- (?&PerlBlock)
`-- (?&PerlOldQualifiedIdentifier)
(?&PerlVersionNumber)
|-- "\."
|-- (?&PPR_digit_seq)
`-- (?&PerlVString)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment