| Category: | |
| Author/Contact Info | |
| Description: | This tool translates the default output of B::Concise into Prolog. The basic predicates are optree/1 which contains an optree and opcode/4. Sample input:
Sample output optree( opcode( leavesub, '23 refs', opcode( lineseq, '', opcode( nextstate, 'Common::Blarg -1428 Blarg.pm:172', [], opcode( ex_const, '', [], opcode( nextstate, 'Common::Blarg -1426 Blarg.pm:173', [], opcode( null, '', opcode( cond_expr, 'other->8', opcode( eq, '', opcode( rv2av, 't2', opcode( gv, '*_', [], [] ), opcode( const, 'IV 2', [], [] ) ), opcode( sassign, '', opcode( ex_aelem, '', opcode( ex_rv2av, '', opcode( aelemfast, '*_', [], [] ), opcode( ex_const, '', [], [] ) ), opcode( aelem, ' sKRM*', opcode( rv2av, 't3', opcode( aelem, '', opcode( padav, '@stuff:FAKE', [], opcode( rv2sv, '', opcode( scope, '', opcode( ex_nextstate, '', [], opcode( ex_aelem, '', opcode( ex_rv2av, '', opcode( aelemfast, '*_', [], [] ), opcode( ex_const, '', [], [] ) ), [] ) ), [] ), [] ) ), [] ), opcode( padsv, '$attrib_num:FAKE', [], [] ) ), [] ) ), opcode( aelem, '', opcode( rv2av, 't5', opcode( aelem, '', opcode( padav, '@stuff:FAKE', [], opcode( rv2sv, '', opcode( scope, '', opcode( ex_nextstate, '', [], opcode( ex_aelem, '', opcode( ex_rv2av, '', opcode( aelemfast, '*_', [], [] ), opcode( ex_const, '', [], [] ) ), [] ) ), [] ), [] ) ), [] ), opcode( padsv, '$attrib_num:FAKE', [], [] ) ), [] ) ) ), [] ), [] ) ) ) ), [] ), [] ) ). |
use strict;
use warnings;
no warnings 'recursion';
$/ = '';
while (<>) {
# Remove first two lines.
s/\A((?:(?>.+)\n)(?:(?>.+)\n))// or die;
my $header = $1;
$header =~ s/^/%% /gm;
# All the leading goo is turned into spaces.
s/^(?>\S+)((?>(?:\s{3})*))(?>\s*)<.>/' ' x length $1/meg;
# The trailing goo is also turned into spaces.
s!\s*[\w/,]*(?>\s+)->(?>\S+)$!!mg;
# Quote anything in parentheses.
s<\((.+)\)>
{
my $thing = $1;
$thing =~ s/([\\'"])/\\$1/g;
qq[ '$thing'];
}ge;
# Quote whatever is in brackets.
s<\[(.+)\]>
{
my $thing = $1;
$thing =~ s/([\\'"%])/\\$1/g;
qq[ '$thing'];
}ge;
# Remove trailing lines
s/\s+\z//;
$_ .= "\n";
$_ = concise_2prolog( $_, 'ROOT' );
print "${header}optree( $_ ).\n\n\n";
}
print <<'FOOTER';
%% Local Variables: ***
%% mode: prolog ***
%% End: ***
FOOTER
sub concise_2prolog {
local $_ = shift @_;
### "$_[0]=<" . join( '', map length( /^(\s+)/ ? $1 : '' ) . $_, /
+(.*\n)/g ) . ">\n";
my $times = 0;
s[# Preceded by a newline or the start of the string
(?:(?<=\n)|(?<=\A))
(?: # First line
(^\ *) # Capture leading space in $1
([-\w]*) # Capture the opcode name in $2
(.*)\n # Capture the args in $3
)
# The children are more indented in $4.
((?:^\1\ .+\n)*)
# The siblings are equally indented in $5.
((?:^\1.+\n)*)
]{
my $opcode = $2;
my $args = $3;
my $children = $4;
my $siblings = $5;
### $siblings
$opcode =~ s/-/_/g;
# Unquote the args.
if ( $args ) {
$args =~ s/^\s*\'//;
$args =~ s/\'\s*\z//;
$args =~ s/'/\\'/g;
}
else {
$args ||= '',
}
if ( $children ) {
$children = concise_2prolog( $children, 'CHILD' );
}
else {
### NO CHILDREN
$children = '[]';
}
if ( $siblings ) {
$siblings = concise_2prolog( $siblings, 'SIBLING' );
}
else {
### NO SIBLINGS
$siblings = '[]';
}
qq<\nopcode( "$opcode", "$args", $children, $siblings )>;
}gxem
or do {
### FAILED
};
### $times
return $_ || '[]';
}
|
|
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: B::Concise -> Prolog
by diotalevi (Canon) on Apr 02, 2007 at 03:02 UTC |