1 #ifndef lint 2 static char sccsid[] = "@(#)parser1.c 3.18 04/24/85"; 3 #endif 4 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 11 #include "parser.h" 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 { 38 for (; p_statement(flag) >= 0; p_clearerr()) 39 ; 40 } 41 42 p_statement(flag) 43 char flag; 44 { 45 switch (token) { 46 case T_EOL: 47 (void) s_gettok(); 48 return 0; 49 case T_IF: 50 return p_if(flag); 51 default: 52 return p_expression(flag); 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: 74 p_error("if: Numeric value required."); 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 110 p_expression(flag) 111 char flag; 112 { 113 struct value t; 114 char *cmd; 115 int p_function(), p_assign(); 116 117 switch (token) { 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) { 132 val_free(t); 133 return 0; 134 } 135 } 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; 143 } 144 if (cmd) 145 str_free(cmd); 146 val_free(t); 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 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 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 } 193