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