All pastes #1310941 Raw Edit

parser.h

public text v1 · immutable
#1310941 ·published 2009-01-17 17:24 UTC
rendered paste body
#ifndef __PARSER_H
#define __PARSER_H

/*
 Include this header to use the parser.
 
 For an example of the usage see
 CUseParser.c
 UseParser.cpp
 
 For an example of the build run make and see the commands it executes
 (see README for details)
 
 If you want to see the structure of the generated parse tree, run
 ./DisplayStructure
*/


#ifdef _WIN32
#  ifndef WIN32
#    define WIN32
#  endif
#endif


#ifdef __cplusplus
#else
/*
 use this to simulate the bool type in C++; e.g.:
 
 bool flag = false;
 if (flag) ...
 else      ...
 
*/
typedef enum
{
	false,
	true
} bool;
#endif


/*
 a string literal list
 
 string literals can be made up of multiple strings
 (next_part points to the next part of a string or
 is NULL if there are no more parts)
 
 Some parts might need environment variable expansion (expand == true);
 if that is the case, "string" points to the environment variable name
 
 The next string literal is pointed to by next_word
 (NULL if there are no more list elements)
 
 The parser guarantees that '=' will be a single part of a string
 (e.g. "name=value" will contain three parts: "name" "=" "value"
 (except for quoted strings in the original command line))
 this can ease implementing an internal command similar to export,
 although the parser does not provide full functionality for this.
 You are not required to implement export.
 
 To tell if a string literal represents an internal command, first
 concatenate all its parts (expanding them if necessary) and then
 compare the result using string comparison.
*/
typedef struct word_t
{
	const char * string;
	bool expand;
	struct word_t * next_part;
	struct word_t * next_word;
} word_t;


/*
 Describes a simple command
 
 aux can be used to point to additional information you might need;
 freeing the memory aux points to is your responsibility. aux will
 be initialized to NULL. Do not modify these structures, please use
 aux.
 
 verb points to a single string literal (possibly made up of parts)
 that is the executable name or the internal command name.
 
 params points to a list of parameters (possibly none) in the order
 they were entered in the command line.
 
 in out and err point to the names of the redirections for the command;
 they can point to a single literal, no literal (the command does not
 have that redirection) or multiple literals (the user entered multiple
 redirections for a command; e.g. cat >out1 >out2). You can handle the
 latter as you wish (e.g. only consider the first redirection). Within
 any of these lists, the literals are in the original order.
 
 Some string literals can be found in both the out list and the err list
 (those entered as "command &> out").
 
 up points to the command_t structure that points to this simple_command_t
 (up != NULL)
*/
typedef struct
{
	word_t * verb;
	word_t * params;
	word_t * in;
	word_t * out;
	word_t * err;
	struct command_t * up;
	void * aux;
} simple_command_t;


/*
 operators
 
 OP_NONE means no operator
 (the scmd field points to a simple command and cmd1 == cmd2 == NULL)
 
 the rest of the operators mean scmd == NULL
 
 OP_DUMMY is a dummy value that can be used to count the number of operators
*/
typedef enum
{
	OP_NONE,
	OP_SEQUENTIAL,
	OP_PARALLEL,
	OP_CONDITIONAL_ZERO,
	OP_CONDITIONAL_NZERO,
	OP_PIPE,
	OP_DUMMY
} operator_t;


/*
 describes a command tree (a node of the parse tree)
 
 if (op == OP_NONE)
    scmd != NULL
    cmd1 == cmd2 == NULL
    scmd points to a command to be executed
 else
    scmd == NULL
    cmd1 != NULL
    cmd2 != NULL
    cmd1 op cmd2 must be executed, according to the rules for op
 
 You can use aux the same way as for simple_command_t
 
 up points to the command_t that points to this structure
 (the father of the current node in the parse tree)
 The root of the tree has up == NULL
 
 The parsed expressions do not contain parantheses, this means that
 the following holds:
 for any op_lower that has a lower priority than op, there is no
 parent in the tree with op == op_lower
 In particular, if op == OP_PIPE descendants
 can only have OP_PIPE or OP_NONE
*/
typedef struct command_t
{
	struct command_t * up;
	struct command_t * cmd1;
	struct command_t * cmd2;
	operator_t op;
	simple_command_t * scmd;
	void * aux;
} command_t;


#ifdef __cplusplus
extern "C"
{
#endif


/*
 You must define this function; it will be called by the parser
 when a parse error occurs; str describes the error (not a useful
 description) and where points to some location before the error
 was discovered (the character number, starting at 0)
*/
void parse_error(const char * str, const int where);


/*
 Call this to parse a line
 
 line must point to a string containig a single line
 The line must end with "\r\n\0" or "\n\0" or "\0"
 (*root) must point to NULL ((*root) == NULL)
 
 parse_line returns true if there was no error parsing the line
 and false if there was an error parsing or the arguments were invalid
 
 if parse_line returns true:
    if line was empty (or contained just blanks) (*root) is NULL
    else (*root) points to the root of the parse tree
*/
bool parse_line(const char * line, command_t ** root);


/*
 should be called to free the parse tree
 call this even if parse_line() returned false
*/
void free_parse_memory();

#ifdef __cplusplus
}
#endif


#ifdef __PARSER_H_INTERNAL_INCLUDE

/*
 parser and lexer common internal stuff
*/

typedef void * GenericPointer;

typedef struct
{
	word_t * red_i;
	word_t * red_o;
	word_t * red_e;
} redirect_t;


#ifdef __cplusplus
extern "C"
{
#endif

int yylex();
void globalParseAnotherString(const char * str);
void globalEndParsing();
void pointerToMallocMemory(const void * ptr);

#ifdef __cplusplus
}
#endif

#endif

/*
 Parser written by Maximilian Machedon, based on a previous version.
*/
#endif