Commit ed1d3aeb authored by Sander Mathijs van Veen's avatar Sander Mathijs van Veen

Merge branch 'master' of ssh://vo20.nl/git/uva

parents 76dd1345 04b26d4e
CC=gcc
CC=clang # gcc
RM=rm -Rfv
LFLAGS= -lm
......@@ -21,6 +21,7 @@ shell: input.yacc.o input.lex.o main.o
test: shell
echo -n 'exit' | ./shell
echo -n 'cd ../' | ./shell
echo -n 'help' | ./shell
echo -n 'cat input.l' | ./shell
echo -n 'cat input.l | grep "id"' | ./shell
echo -n '!!' | ./shell
......@@ -33,7 +34,7 @@ input.yacc.h: input.yacc.c
input.lex.c: input.l
`which flex35 2>/dev/null || which flex 2>/dev/null` \
-C --header-file=input.lex.h -o $@ -d $<
--interactive --header-file=input.lex.h -o $@ -d $<
input.lex.h: input.lex.c
......
/*
* input.l
* Shell input lexer (flex format).
*
* Shell input lexer
* Sander van Veen (6167969) / Taddeus Kroes (6054129).
* <sandervv@gmail.com> / <taddeuskroes@hotmail.com>
*/
%{
......@@ -13,18 +14,18 @@
#include "input.l.h"
#include "input.yacc.h"
// Column / line counters (used in error reporting)
int line_no = 1, column_no = 0;
extern int current_line(void){ return line_no; }
extern int current_column(void){ return column_no; }
extern void reset_line(void){ line_no = 1; }
extern void reset_column(void){ column_no = 0; }
%}
%option nounput
%option noyywrap
%option nounput
%x id
%x num
......@@ -57,13 +58,19 @@ exit {
return EXIT;
}
/* Help shell builtin */
help {
column_no += 4;
return HELP;
}
/* Change directory builtin */
cd {
column_no += 2;
return CD;
}
/* Identifiers: source */
/* Identifiers: source, cat, echo */
{id} {
column_no += yyleng;
yylval.str = strdup(yytext);
......@@ -83,14 +90,14 @@ cd {
}
/* Path or path with filename: ./a/, ../, config/, /tmp/, /tmp/file */
[^ ]*\/[^ ]* {
\.*{id}?\/[^\t\n ]* {
column_no += yyleng;
yylval.str = strdup(yytext);
return PATH;
}
/* Argument (filenames and such): hello.txt, .config */
[\/{id}][^ ]+ {
{id}[^\t\n |]+ {
column_no += yyleng;
yylval.str = strdup(yytext);
return ARGUMENT;
......@@ -98,22 +105,18 @@ cd {
#[^\n]+ { /* ignore comments */ }
/* End of file is a separator */
\0 {
line_no++;
reset_column();
return EOS;
}
/* White space */
\n {
line_no++;
reset_column();
shell_entry();
return EOL;
}
/* White space */
{wsp} { column_no++; }
{wsp} {
column_no++;
}
. {
column_no++;
......
/*
* Shell function declarations.
*
* Sander van Veen (6167969) / Taddeus Kroes (6054129).
* <sandervv@gmail.com> / <taddeuskroes@hotmail.com>
*/
#include "input.yacc.h"
/*
* Helper functions for line/column counter manipulation (which are used for the
* lexer's error reporting).
*/
extern int current_line(void);
extern int current_column(void);
extern void reset_line();
extern void reset_column();
extern int yyparse();
extern void reset_line();
extern void reset_column();
/*
* Helper functions for shell output messages.
*/
void shell_debug(const char *msg, ...);
void shell_error(const char *msg);
void shell_entry();
/*
* Singly linked list of arguments.
*/
typedef struct shell_args {
char *arg;
struct shell_args *next;
} shell_args;
/*
* A shell command contains a function identifier and an argument list (list
* could be empty).
*/
typedef enum {FN_CD, FN_HELP, FN_EXIT, FN_EXEC} shell_func;
typedef struct shell_cmd {
shell_func func;
shell_args *args;
} shell_cmd;
/*
* Helper functions for creating / manipulating argument objects.
*/
void shell_push_args(const char *value);
void shell_append_args(const char *value);
shell_args *shell_pop_args();
void shell_free_args(shell_args *args);
/*
* Builtin shell commands.
*/
void shell_change_dir(const char *path);
void shell_exit();
void shell_help();
void shell_pipe();
void shell_repeat(int prev);
void shell_exec(shell_args *args);
void shell_exec_process(shell_args *args);
/*
* Doubly linked list containing all executed commands.
*/
typedef struct shell_history_log {
shell_cmd *cmd;
struct shell_history_log *prev;
struct shell_history_log *next;
} shell_history_log;
/*
* Shell history manipulation functions.
*/
void shell_history_add(shell_cmd *cmd);
shell_cmd *shell_history_get(int prev);
void shell_history_clear();
void shell_history_append(shell_func type, shell_args *args);
void start_shell_entry();
void start_shell_pipe();
%{
/*
* Shell input grammar (yacc/bison format)
* Shell input grammar (yacc/bison format).
*
* Sander van Veen (6167969) / Taddeus Kroes (6054129).
* <sandervv@gmail.com> / <taddeuskroes@hotmail.com>
*/
#define YYDEBUG 1
#define YYERROR_VERBOSE 1
#include <stdio.h>
#include <string.h>
// #include "input.func.h"
#include "input.yacc.h"
#include "input.lex.h"
#include "input.l.h"
void yyerror(const char *str) {
fflush(stdout);
fflush(stderr);
fprintf(stderr, "error: parser reported \"%s\" (line %d, column %d)\n", str,
current_line(), current_column());
......@@ -23,9 +26,10 @@ void yyerror(const char *str) {
%}
%token COMMENT IDENTIFIER ARGUMENT STRING INTEGER
%token EOL EOS CD EXIT PATH
%token EOL EOS CD EXIT PATH HELP
%type <str> PATH INTEGER
%type <str> PATH INTEGER IDENTIFIER ARGUMENT STRING
%type <str> Argument
%union {
char * str;
......@@ -35,29 +39,31 @@ void yyerror(const char *str) {
%%
Start: /* empty */
| Commands
Start: Commands
;
Commands: Command /*{ printf("cmd: %s\n", $1); }*/
/* | Command EOS*/
| Commands EOL { start_shell_entry(); } Command
| Commands '|' { start_shell_pipe(); } Command
Commands: Command
| Commands EOL Command
| Commands '|' { shell_pipe(); } Command
;
Command: Builtin
| IDENTIFIER
| IDENTIFIER Arguments
Command: /* Empty */
| Builtin
| IDENTIFIER { shell_push_args($1); }
{ shell_exec(shell_pop_args()); }
| IDENTIFIER { shell_push_args($1); }
Arguments { shell_exec(shell_pop_args()); }
;
Builtin: EXIT { puts("Exit shell"); }
| CD PATH { printf("CD %s\n", $2); }
| '!' '!' { puts("Repeat last"); }
| '!' INTEGER { printf("Repeat %d\n", atoi($2)); }
Builtin: EXIT { shell_exit(); }
| HELP { shell_help(); }
| CD Argument { shell_change_dir($2); }
| '!' '!' { shell_repeat(1); }
| '!' INTEGER { shell_repeat(atoi($2)); }
;
Arguments: Argument
| Arguments ' ' Argument
Arguments: Argument { shell_append_args($1); }
| Arguments Argument { shell_append_args($2); }
;
Argument: STRING
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment