The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

Shell::Parser - Simple shell script parser

VERSION

Version 0.04

SYNOPSIS

use Shell::Parser;

my $parser = new Shell::Parser syntax => 'bash', handlers => {
    
};
$parser->parse(...);
$parser->eof;

DESCRIPTION

This module implements a rudimentary shell script parser in Perl. It was primarily written as a backend for Syntax::Highlight::Shell, in order to simplify the creation of the later.

METHODS

new()

Creates and returns a new Shell::Parser object. Options can be provided as key/value pairs.

Options

  • handlers - sets the parsing events handlers. See "handlers()" for more information.

  • syntax - selects the shell syntax. See "syntax()" for more information.

Examples

my $parser = new Shell::Parser syntax => 'bash', 
    handlers => { default => \&default_handler };
parse()

Parse the shell code given in argument.

Examples

$parser->parse(qq{echo "hello world"\n});
$parser->parse(<<'SHELL');
    for pat; do 
        echo "greping for $pat"
        ps aux | grep $pat
    done
SHELL
eof()

Tells the parser that there is no more data.

Note that this method is a no-op for now, but this may change in the future.

handlers()

Assign handlers to parsing events using a hash or a hashref. Available events:

  • assign - handler for assignments: VARIABLE=VALUE

  • builtin - handler for shell builtin commands: alias, jobs, read...

  • command - handler for external commands (not implemented)

  • comment - handler for comments: # an impressive comment

  • keyword - handler for shell reserved words: for, if, case...

  • metachar - handler for shell metacharacters: ;, &, |...

  • variable - handler for variable expansion: $VARIABLE

  • text - handler for anything else

There is also a default handler, which will be used for any handler which has not been explicitely defined.

Examples

# set the default event handler
$parser->handlers(default => \&default_handler);

# set the 'builtin' and 'keywords' events handlers
$parser->handlers({ builtin => \&handle_internals, keywords => \&handle_internals });

See also "Handlers" for more information on how event handlers receive their data in argument.

syntax()

Selects the shell syntax. Use one of:

  • bourne - the standard Bourne shell

  • csh - the C shell

  • tcsh - the TENEX C shell

  • korn88 - the Korn shell, 1988 version

  • korn93 - the Korn shell 1993 version

  • bash - GNU Bourne Again SHell

  • zsh - the Z shell

Returns the current syntax when called with no argument, or the previous syntax when affecting a new one.

HANDLERS

During parsing, the functions defined as handlers for the corresponding events will be called with the following arguments:

  • a reference to the current Shell::Parser object

  • a hash with the following keys:

    • token - the actual shell token

    • type - the type of the token

Therefore, a typical handler function will begin with something like this:

sub my_handler {
    my $self = shift;
    my %args = @_;
    
    # do stuff
    # ...
}

EXAMPLE

Here is an example that shows how the tokens are given to the events handlers. It uses the script eg/parsedump.pl:

#!/usr/bin/perl
use strict;
use Shell::Parser;

my $parser = new Shell::Parser handlers => { default => \&dumpnode };
$parser->parse(join '', <>);

sub dumpnode {
    my $self = shift;
    my %args = @_;
    print "$args{type}: <$args{token}>\n"
}

Running this Perl script with the following shell script in argument:

#!/bin/sh
if [ "$text" != "" ]; then grep "$text" file.txt; fi

will produce the following trace:

comment: <#!/bin/sh>
text: <
>
keyword: <if>
text: < >
text: <[>
text: < >
text: <"$text">
text: < >
assign: <!=>
text: < >
text: <"">
text: < >
text: <]>
metachar: <;>
text: < >
keyword: <then>
text: < >
text: <grep>
text: < >
text: <"$text">
text: < >
text: <file.txt>
metachar: <;>
text: < >
keyword: <fi>
text: <
>

DIAGNOSTICS

Can't deal with ref of any kind for now

(F) You gave a reference to parse(), which is not handled at this time.

No such handler: %s

(E) You gave an unknown handler name. Please check "handlers()" for the available handlers.

Unknown syntax '%s'

(E) You gave an unknown syntax. Please check "syntax()" for the available syntaxes.

CAVEATS

  • Running Shell::Parser with the -W flag gives many warnings, but most come from Text::ParseWords.

  • Comments curently contains the newline character that terminate them. This is not very intuituive and will be corrected in later versions.

  • The command event is currently unimplemented.

  • Here-documents are currently not parsed.

AUTHOR

SEeacute>bastien Aperghis-Tramoni, <sebastien@aperghis.net>

BUGS

Please report any bugs or feature requests to bug-shell-parser@rt.cpan.org, or through the web interface at https://rt.cpan.org/NoAuth/ReportBug.html?Queue=Shell-Parser. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

COPYRIGHT & LICENSE

Copyright 2004 Sébastien Aperghis-Tramoni, All Rights Reserved.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.