1 /*
2 * Copyright (c) 1983, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Edward Wang at The University of California, Berkeley.
7 *
8 * %sccs.include.redist.c%
9 */
10
11 #ifndef lint
12 static char sccsid[] = "@(#)parser1.c 8.1 (Berkeley) 06/06/93";
13 #endif /* not lint */
14
15 #include "parser.h"
16
p_start()17 p_start()
18 {
19 char flag = 1;
20
21 (void) s_gettok();
22 for (;;) {
23 p_statementlist(flag);
24 if (token == T_EOF || p_abort())
25 break;
26 flag = 0;
27 p_synerror();
28 while (token != T_EOL && token != T_EOF) {
29 if (token == T_STR)
30 str_free(token_str);
31 (void) s_gettok();
32 }
33 if (token == T_EOL)
34 (void) s_gettok();
35 p_clearerr();
36 }
37 }
38
p_statementlist(flag)39 p_statementlist(flag)
40 char flag;
41 {
42 for (; p_statement(flag) >= 0; p_clearerr())
43 ;
44 }
45
p_statement(flag)46 p_statement(flag)
47 char flag;
48 {
49 switch (token) {
50 case T_EOL:
51 (void) s_gettok();
52 return 0;
53 case T_IF:
54 return p_if(flag);
55 default:
56 return p_expression(flag);
57 }
58 }
59
p_if(flag)60 p_if(flag)
61 char flag;
62 {
63 struct value t;
64 char true = 0;
65
66 top:
67 (void) s_gettok();
68
69 if (p_expr(&t, flag) < 0) {
70 p_synerror();
71 return -1;
72 }
73 switch (t.v_type) {
74 case V_NUM:
75 true = !true && t.v_num != 0;
76 break;
77 case V_STR:
78 p_error("if: Numeric value required.");
79 str_free(t.v_str);
80 case V_ERR:
81 flag = 0;
82 break;
83 }
84
85 if (token != T_THEN) {
86 p_synerror();
87 return -1;
88 }
89
90 (void) s_gettok();
91 p_statementlist(flag && true);
92 if (p_erred())
93 return -1;
94
95 if (token == T_ELSIF)
96 goto top;
97
98 if (token == T_ELSE) {
99 (void) s_gettok();
100 p_statementlist(flag && !true);
101 if (p_erred())
102 return -1;
103 }
104
105 if (token == T_ENDIF) {
106 (void) s_gettok();
107 return 0;
108 }
109
110 p_synerror();
111 return -1;
112 }
113
p_expression(flag)114 p_expression(flag)
115 char flag;
116 {
117 struct value t;
118 char *cmd;
119 int p_function(), p_assign();
120
121 switch (token) {
122 case T_NUM:
123 t.v_type = V_NUM;
124 t.v_num = token_num;
125 (void) s_gettok();
126 break;
127 case T_STR:
128 t.v_type = V_STR;
129 t.v_str = token_str;
130 (void) s_gettok();
131 break;
132 default:
133 if (p_expr(&t, flag) < 0)
134 return -1;
135 if (token == T_EOF) {
136 val_free(t);
137 return 0;
138 }
139 }
140 if (token != T_ASSIGN && p_convstr(&t) < 0)
141 return -1;
142 cmd = t.v_type == V_STR ? t.v_str : 0;
143 if ((*(token == T_ASSIGN ? p_assign : p_function))(cmd, &t, flag) < 0) {
144 if (cmd)
145 str_free(cmd);
146 return -1;
147 }
148 if (cmd)
149 str_free(cmd);
150 val_free(t);
151 if (token == T_EOL)
152 (void) s_gettok();
153 else if (token != T_EOF) {
154 p_synerror();
155 return -1;
156 }
157 return 0;
158 }
159
p_convstr(v)160 p_convstr(v)
161 register struct value *v;
162 {
163 if (v->v_type != V_NUM)
164 return 0;
165 if ((v->v_str = str_itoa(v->v_num)) == 0) {
166 p_memerror();
167 v->v_type = V_ERR;
168 return -1;
169 }
170 v->v_type = V_STR;
171 return 0;
172 }
173
p_synerror()174 p_synerror()
175 {
176 if (!cx.x_synerred) {
177 cx.x_synerred = cx.x_erred = 1;
178 error("Syntax error.");
179 }
180 }
181
182 /*VARARGS1*/
p_error(msg,a,b,c)183 p_error(msg, a, b, c)
184 char *msg;
185 {
186 if (!cx.x_erred) {
187 cx.x_erred = 1;
188 error(msg, a, b, c);
189 }
190 }
191
p_memerror()192 p_memerror()
193 {
194 cx.x_erred = cx.x_abort = 1;
195 error("Out of memory.");
196 }
197