#ifndef _PARSER_H #define _PARSER_H #include #define TOKEN_MAX 64 #define CMD_ARGS_MAX 64 #define TOKEN_CLASS_OPAREN 0 #define TOKEN_CLASS_CPAREN 1 #define TOKEN_CLASS_WORD 2 #define TOKEN_CLASS_SEMICOLON 3 #define TOKEN_CLASS_REDIR 4 struct token { struct list_node_link tokens_link; char buffer[TOKEN_MAX]; int class; }; #define PREC_NONE 0 #define PREC_LOWEST 1 #define PREC_SEQ 2 #define PREC_REDIR 3 #define AST_NODE_CLASS_CMD 0 #define AST_NODE_CLASS_SUBSHELL 1 #define AST_NODE_CLASS_SEQ 2 #define AST_NODE_CLASS_REDIR 3 struct ast_node; struct ast_cmd { char* name; char* args[CMD_ARGS_MAX]; int arg_count; }; struct ast_subshell { struct ast_node* inner; }; struct ast_seq { struct ast_node* left; struct ast_node* right; }; struct ast_redir { struct ast_node* source; char* file_path; }; struct ast_node { int class; union { struct ast_cmd cmd; struct ast_subshell subshell; struct ast_seq seq; struct ast_redir redir; } u; }; struct parser; typedef struct ast_node* (*nud_func_t) (struct parser* parser, struct token* token); typedef struct ast_node* (*led_func_t) (struct parser* parser, struct token* token, struct ast_node* left); struct parse_rule { nud_func_t nud; led_func_t led; int precedence; }; struct parser { struct token* current; struct token* next; }; struct ast_node* word_nud (struct parser* parser, struct token* token); struct ast_node* oparen_nud (struct parser* parser, struct token* token); struct ast_node* semicolon_led (struct parser* parser, struct token* token, struct ast_node* left); struct ast_node* redir_led (struct parser* parser, struct token* token, struct ast_node* left); void tokenize (struct list_node_link** tokens, const char* text); void parse_and_execute (struct list_node_link* tokens); #endif // _PARSER_H