-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathparser.y
162 lines (135 loc) · 3 KB
/
parser.y
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
%{
/*-
* parse.y
* Minishell "yacc" source
* Describes valid input grammar
* Exports "obtain_order" input interface function.
*
* Copyright (c) 1993-2002-2019, Francisco Rosales <frosal@fi.upm.es>
* Todos los derechos reservados.
*
* Publicado bajo Licencia de Proyecto Educativo Práctico
* <http://laurel.datsi.fi.upm.es/~ssoo/LICENCIA/LPEP>
*
* Queda prohibida la difusión total o parcial por cualquier
* medio del material entregado al alumno para la realización
* de este proyecto o de cualquier material derivado de este,
* incluyendo la solución particular que desarrolle el alumno.
*
* DO NOT MODIFY THIS FILE
*/
#include <stddef.h> /* NULL */
#include <stdlib.h> /* malloc */
#include <string.h> /* strlen */
#include <unistd.h> /* write */
extern int yyparse(void);
extern int yylex(void);
void yyerror(char *s)
{
write(2,s,strlen(s));
write(2,"\n",1);
}
int yywrap(void)
{
return 1;
}
static char *** argvv;
static int argvc;
static int argc;
static char * filev[3];
static int bg;
static void freevv(char ***ppp);
static void pipeline(void);
static void command(char *arg);
%}
%start minish
%token TXT
%right '|'
%union { char * txt; }
%type <txt> TXT
%%
minish : { return(0); }
| line end { return(argvc+1); }
| error end { yyerrok; return(-1); }
;
line :
| pipel redir backg
;
pipel : comma { pipeline(); }
| pipel '|' comma { pipeline(); }
;
comma : TXT { command($1); }
| comma TXT { command($2); }
;
redir :
| '<' TXT redir { if(filev[0]) YYERROR; filev[0] = $2; }
| '>' TXT redir { if(filev[1]) YYERROR; filev[1] = $2; }
| '>' '&' TXT redir { if(filev[2]) YYERROR; filev[2] = $3; }
;
backg :
| '&' { bg = 1; }
;
end : '\n'
;
%%
#define zfree(p) { if(p) { free(p); p = NULL; } }
static void freev(char **pp)
{
for (; *pp; pp++)
zfree(*pp);
}
#define zfreev(pp) { if(pp) { freev(pp); free(pp); pp = NULL; } }
static void freevv(char ***ppp)
{
for (; *ppp; ppp++)
zfreev(*ppp);
}
#define zfreevv(ppp) { if(ppp) { freevv(ppp); free(ppp); ppp = NULL; } }
static void pipeline(void)
{
argvc++;
}
#define argv argvv[argvc]
static void command(char *arg)
{
if (!argvv) {
argvc = 0;
argvv = calloc(1, sizeof(char **));
}
if (!argv) {
argvv = realloc(argvv, (argvc + 2) * sizeof(char **));
argvv[argvc + 1] = NULL;
argc = 0;
argv = calloc(1, sizeof(char *));
}
argv = realloc(argv, (argc + 2) * sizeof(char *));
argv[argc++] = arg;
argv[argc] = NULL;
}
/*
* Input interface function
* Returns:
* -1, at syntax error
* 0, at end of file on input
* >0, number of commands in the pipeline + 1
*/
int obtain_order(char ****argvvp, char *filep[3], int *bgp)
/* argvvp is reference of a NULL terminated array of argvs */
/* filep is reference to an array of 3 char* */
/* bgp is reference to an integer */
{
int ret;
zfreevv(argvv);
argvc = 0;
zfree(filev[0]);
zfree(filev[1]);
zfree(filev[2]);
bg = 0;
ret = yyparse();
*argvvp = argvv;
filep[0] = filev[0];
filep[1] = filev[1];
filep[2] = filev[2];
*bgp = bg;
return ret;
}