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