2 /********************************************
4 copyright 1991, Michael D. Brennan
6 This is a source file for mawk, an implementation of
7 the AWK programming language.
9 Mawk is distributed without warranty under the terms of
10 the GNU General Public License, version 2, 1991.
11 ********************************************/
14 *Revision 1.3 1996/09/02 18:47:36 mike
15 *Make ^* and ^+ syntax errors.
17 *Revision 1.2 1993/07/23 13:21:32 mike
20 * Revision 1.1.1.1 1993/07/03 18:58:26 mike
23 * Revision 3.4 1991/08/13 09:09:59 brennan
26 * Revision 3.3 91/08/04 15:45:03 brennan
27 * no longer attempt to recover mem on failed REcompile
28 * Its not worth the effort
30 * Revision 3.2 91/08/03 07:24:06 brennan
31 * check for empty machine stack (missing operand) wasn't quite right
33 * Revision 3.1 91/06/07 10:33:16 brennan
36 * Revision 1.7 91/06/05 08:58:47 brennan
37 * change RE_free to free
39 * Revision 1.6 91/06/03 07:07:17 brennan
40 * moved parser stacks inside REcompile
41 * removed unnecessary copying
45 /* op precedence parser for regular expressions */
54 /* 1 */ "missing '('",
55 /* 2 */ "missing ')'",
56 /* 3 */ "bad class -- [], [^] or [",
57 /* 4 */ "missing operand",
58 /* 5 */ "resource exhaustion -- regular expression too large" ,
59 /* 6 */ "syntax error ^* or ^+"
61 /* E5 is very unlikely to occur */
64 /* This table drives the operator precedence parser */
65 static short table[8][8] = {
67 /* 0 | CAT * + ? ( ) */
68 /* 0 */ {0, L, L, L, L, L, L, E1},
69 /* | */ {G, G, L, L, L, L, L, G},
70 /* CAT*/ {G, G, G, L, L, L, L, G},
71 /* * */ {G, G, G, G, G, G, E7, G},
72 /* + */ {G, G, G, G, G, G, E7, G},
73 /* ? */ {G, G, G, G, G, G, E7, G},
74 /* ( */ {E2, L, L, L, L, L, L, EQ},
75 /* ) */ {G , G, G, G, G, G, E7, G} } ;
81 static jmp_buf err_buf ; /* used to trap on error */
96 MACHINE m_stack[STACKSZ] ;
103 register MACHINE *m_ptr ;
104 register struct op *op_ptr ;
107 /* do this first because it also checks if we have a
113 STATE *p = (STATE *) RE_malloc(sizeof(STATE)) ;
118 if (setjmp(err_buf)) return (PTR) 0 ;
119 /* we used to try to recover memory left on machine stack ;
120 but now m_ptr is in a register so it won't be right unless
121 we force it out of a register which isn't worth the trouble */
123 /* initialize the stacks */
124 m_ptr = m_stack - 1 ;
128 t = RE_lex(m_stack) ;
143 case 0: /* end of reg expr */
144 if (op_ptr->token == 0)
147 if (m_ptr == m_stack) return (PTR) m_ptr->start ;
150 /* machines still on the stack */
151 RE_panic("values still on machine stack") ;
155 /* otherwise fall thru to default
156 which is operator case */
160 if ((op_ptr->prec = table[op_ptr->token][t]) == G)
165 if (op_ptr->token <= T_CAT) /*binary op*/
167 /* if not enough values on machine stack
168 then we have a missing operand */
169 if (m_ptr < m_stack) RE_error_trap(-E4) ;
171 switch (op_ptr->token)
174 RE_cat(m_ptr, m_ptr + 1) ;
178 RE_or(m_ptr, m_ptr + 1) ;
194 /*nothing on ( or ) */
200 while (op_ptr->prec != L);
202 continue ; /* back thru switch at top */
205 if (op_ptr->prec < 0)
207 if (op_ptr->prec == E7) RE_panic("parser returns E7") ;
208 else RE_error_trap(-op_ptr->prec) ;
211 if (++op_ptr == op_stack + STACKSZ)
218 } /* end of switch */
220 if (m_ptr == m_stack + (STACKSZ - 1))
226 t = RE_lex(m_ptr + 1) ;
231 /* getting here means a logic flaw or unforeseen case */
236 fprintf(stderr, "REcompile() - panic: %s\n", s) ;