Commit | Line | Data |
---|---|---|
60de5df9 | 1 | /* |
46e9ea25 KB |
2 | * Copyright (c) 1983 Regents of the University of California. |
3 | * All rights reserved. | |
4 | * | |
3dd3a9e5 KB |
5 | * This code is derived from software contributed to Berkeley by |
6 | * Edward Wang at The University of California, Berkeley. | |
7 | * | |
87f529ec | 8 | * %sccs.include.redist.c% |
60de5df9 EW |
9 | */ |
10 | ||
46e9ea25 | 11 | #ifndef lint |
3dd3a9e5 | 12 | static char sccsid[] = "@(#)parser1.c 3.22 (Berkeley) %G%"; |
46e9ea25 KB |
13 | #endif /* not lint */ |
14 | ||
a7b2e18a | 15 | #include "parser.h" |
b0c08430 EW |
16 | |
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 | ||
39 | p_statementlist(flag) | |
40 | char flag; | |
41 | { | |
63f7da95 EW |
42 | for (; p_statement(flag) >= 0; p_clearerr()) |
43 | ; | |
b0c08430 EW |
44 | } |
45 | ||
46 | p_statement(flag) | |
47 | char flag; | |
48 | { | |
b0c08430 EW |
49 | switch (token) { |
50 | case T_EOL: | |
b0c08430 EW |
51 | (void) s_gettok(); |
52 | return 0; | |
53 | case T_IF: | |
b0c08430 EW |
54 | return p_if(flag); |
55 | default: | |
f0e3c264 | 56 | return p_expression(flag); |
b0c08430 EW |
57 | } |
58 | } | |
59 | ||
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: | |
fbbe9777 | 78 | p_error("if: Numeric value required."); |
b0c08430 EW |
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 | ||
f0e3c264 | 114 | p_expression(flag) |
b0c08430 EW |
115 | char flag; |
116 | { | |
117 | struct value t; | |
118 | char *cmd; | |
bb4a0c0b | 119 | int p_function(), p_assign(); |
b0c08430 | 120 | |
b0c08430 | 121 | switch (token) { |
b0c08430 EW |
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) { | |
474b372d | 136 | val_free(t); |
b0c08430 EW |
137 | return 0; |
138 | } | |
139 | } | |
bb4a0c0b EW |
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; | |
b0c08430 | 147 | } |
f8e2d916 EW |
148 | if (cmd) |
149 | str_free(cmd); | |
474b372d | 150 | val_free(t); |
b0c08430 EW |
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 | ||
0180c2d9 EW |
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 | ||
b0c08430 EW |
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*/ | |
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 | ||
192 | p_memerror() | |
193 | { | |
194 | cx.x_erred = cx.x_abort = 1; | |
195 | error("Out of memory."); | |
196 | } |