NAME

Mpp::Lexer - Makepp lexer for finding commands and redirections in a rule

DESCRIPTION

Mpp::Lexer is responsible for lexical analysis of shell commands. It finds file redirections as prerequisites or targets. It also splits pipelines or series of commands checking each one, whether there is a command parser for it.

Ideally, rule options should indicate whether back-quotes should be expanded and/or parsed. Currently, they are neither.

This class should handle all POSIX-like shells (bash, ksh, zsh) well enough, but not rather different ones like csh.

METHODS

new

my $lexer=new Mpp::Lexer;

Returns a new Mpp::Lexer object.

lex_rule

$lexer->lex_rule($actions, $rule);

For each action in $actions, first deal with shell stuff, for example:

  1. Break the actions into commands (split on ;, &, &&, | and ||)

  2. Deal with I/O redirectors

  3. Determine which environment variables are set by each action [partially done]

  4. Parse back-quoted expressions, which get replaced by -backquote which parsers should ignore. In Makeppfiles use "SOMEOPT ;= $(shell someconfig --opt)" instead, because then makepp is aware of whatever the command got replaced by.

  5. For "cd" commands, determine the directory into which it changes

For each remaining command, call parse_command().

$actions represents $rule's newline-separated actions, which are not derived from the rule itself so as to avoid duplicated expansion work.

Return value is TRUE on success.

parse_command

$lexer->parse_command($command, $rule, $dir, $setenv_hash, \$found);

Parse $command as if it is executed in directory $dir (relative to $rule->build_cwd), and update $rule accordingly. $setenv_hash is the environmental settings that are set by the rule itself, with shell variables not expanded.

In this base class, calls find_command_parser to determine which command parser to use. If the result is FALSE, then do nothing more. (This can't happen for an object of the base class, since we always use a plain Mpp/CommandParser.) Otherwise, the resulting object's parse_command method is called, and we return that method's return value.

Return value is TRUE on success, zero if no meaningful command parsing was performed, and undefined if a metadependency failed to build or if scanning failed.

find_command_parser

my $command_parser=$lexer->find_command_parser($command, $rule, $dir, \$found);

The first word of $command is looked up in %parsers from the Makeppfile's namespace. If it isn't found, then undef is returned. Otherwise, the resulting coderef is called with the command, rule and directory. If the return value is a reference to an object of type Mpp::CommandParser, then it is returned. Otherwise, 0 is returned. There is no way to indicate a scanning failure if 0 is returned, for backward compatibility.

add_dependency

add_optional_dependency

add_simple_dependency

Like the corresponding methods in Mpp::CommandParser, except that it's an ordinary function, and the parameter list is prepended with the command's directory name, directory Mpp::File object, and Rule object.

add_target

Like the corresponding methods in Mpp::CommandParser, except that it's an ordinary function, and the parameter list is prepended with the command's directory name and Rule object.

add_env_dependency

Like the corresponding methods in Mpp::CommandParser, except that it's an ordinary function, and the parameter list is prepended with the Rule object.