|
|
1.1 root 1: /*
2: * Copyright (c) 1983 Regents of the University of California.
3: * 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: * Redistribution and use in source and binary forms are permitted provided
9: * that: (1) source distributions retain this entire copyright notice and
10: * comment, and (2) distributions including binaries display the following
11: * acknowledgement: ``This product includes software developed by the
12: * University of California, Berkeley and its contributors'' in the
13: * documentation or other materials provided with the distribution and in
14: * all advertising materials mentioning features or use of this software.
15: * Neither the name of the University nor the names of its contributors may
16: * be used to endorse or promote products derived from this software without
17: * specific prior written permission.
18: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
19: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
20: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
21: */
22:
23: #ifndef lint
24: static char sccsid[] = "@(#)parser1.c 3.22 (Berkeley) 6/6/90";
25: #endif /* not lint */
26:
27: #include "parser.h"
28:
29: p_start()
30: {
31: char flag = 1;
32:
33: (void) s_gettok();
34: for (;;) {
35: p_statementlist(flag);
36: if (token == T_EOF || p_abort())
37: break;
38: flag = 0;
39: p_synerror();
40: while (token != T_EOL && token != T_EOF) {
41: if (token == T_STR)
42: str_free(token_str);
43: (void) s_gettok();
44: }
45: if (token == T_EOL)
46: (void) s_gettok();
47: p_clearerr();
48: }
49: }
50:
51: p_statementlist(flag)
52: char flag;
53: {
54: for (; p_statement(flag) >= 0; p_clearerr())
55: ;
56: }
57:
58: p_statement(flag)
59: char flag;
60: {
61: switch (token) {
62: case T_EOL:
63: (void) s_gettok();
64: return 0;
65: case T_IF:
66: return p_if(flag);
67: default:
68: return p_expression(flag);
69: }
70: }
71:
72: p_if(flag)
73: char flag;
74: {
75: struct value t;
76: char true = 0;
77:
78: top:
79: (void) s_gettok();
80:
81: if (p_expr(&t, flag) < 0) {
82: p_synerror();
83: return -1;
84: }
85: switch (t.v_type) {
86: case V_NUM:
87: true = !true && t.v_num != 0;
88: break;
89: case V_STR:
90: p_error("if: Numeric value required.");
91: str_free(t.v_str);
92: case V_ERR:
93: flag = 0;
94: break;
95: }
96:
97: if (token != T_THEN) {
98: p_synerror();
99: return -1;
100: }
101:
102: (void) s_gettok();
103: p_statementlist(flag && true);
104: if (p_erred())
105: return -1;
106:
107: if (token == T_ELSIF)
108: goto top;
109:
110: if (token == T_ELSE) {
111: (void) s_gettok();
112: p_statementlist(flag && !true);
113: if (p_erred())
114: return -1;
115: }
116:
117: if (token == T_ENDIF) {
118: (void) s_gettok();
119: return 0;
120: }
121:
122: p_synerror();
123: return -1;
124: }
125:
126: p_expression(flag)
127: char flag;
128: {
129: struct value t;
130: char *cmd;
131: int p_function(), p_assign();
132:
133: switch (token) {
134: case T_NUM:
135: t.v_type = V_NUM;
136: t.v_num = token_num;
137: (void) s_gettok();
138: break;
139: case T_STR:
140: t.v_type = V_STR;
141: t.v_str = token_str;
142: (void) s_gettok();
143: break;
144: default:
145: if (p_expr(&t, flag) < 0)
146: return -1;
147: if (token == T_EOF) {
148: val_free(t);
149: return 0;
150: }
151: }
152: if (token != T_ASSIGN && p_convstr(&t) < 0)
153: return -1;
154: cmd = t.v_type == V_STR ? t.v_str : 0;
155: if ((*(token == T_ASSIGN ? p_assign : p_function))(cmd, &t, flag) < 0) {
156: if (cmd)
157: str_free(cmd);
158: return -1;
159: }
160: if (cmd)
161: str_free(cmd);
162: val_free(t);
163: if (token == T_EOL)
164: (void) s_gettok();
165: else if (token != T_EOF) {
166: p_synerror();
167: return -1;
168: }
169: return 0;
170: }
171:
172: p_convstr(v)
173: register struct value *v;
174: {
175: if (v->v_type != V_NUM)
176: return 0;
177: if ((v->v_str = str_itoa(v->v_num)) == 0) {
178: p_memerror();
179: v->v_type = V_ERR;
180: return -1;
181: }
182: v->v_type = V_STR;
183: return 0;
184: }
185:
186: p_synerror()
187: {
188: if (!cx.x_synerred) {
189: cx.x_synerred = cx.x_erred = 1;
190: error("Syntax error.");
191: }
192: }
193:
194: /*VARARGS1*/
195: p_error(msg, a, b, c)
196: char *msg;
197: {
198: if (!cx.x_erred) {
199: cx.x_erred = 1;
200: error(msg, a, b, c);
201: }
202: }
203:
204: p_memerror()
205: {
206: cx.x_erred = cx.x_abort = 1;
207: error("Out of memory.");
208: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.