1da2e3ebdSchin /***********************************************************************
2da2e3ebdSchin * *
3da2e3ebdSchin * This software is part of the ast package *
4*34f9b3eeSRoland Mainz * Copyright (c) 1986-2009 AT&T Intellectual Property *
5da2e3ebdSchin * and is licensed under the *
6da2e3ebdSchin * Common Public License, Version 1.0 *
77c2fbfb3SApril Chin * by AT&T Intellectual Property *
8da2e3ebdSchin * *
9da2e3ebdSchin * A copy of the License is available at *
10da2e3ebdSchin * http://www.opensource.org/licenses/cpl1.0.txt *
11da2e3ebdSchin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
12da2e3ebdSchin * *
13da2e3ebdSchin * Information and Software Systems Research *
14da2e3ebdSchin * AT&T Research *
15da2e3ebdSchin * Florham Park NJ *
16da2e3ebdSchin * *
17da2e3ebdSchin * Glenn Fowler <gsf@research.att.com> *
18da2e3ebdSchin * *
19da2e3ebdSchin ***********************************************************************/
20da2e3ebdSchin #pragma prototyped
21da2e3ebdSchin /*
22da2e3ebdSchin * Glenn Fowler
23da2e3ebdSchin * AT&T Research
24da2e3ebdSchin *
25da2e3ebdSchin * preprocessor and proto lexical analyzer fsm
26da2e3ebdSchin * define PROTOMAIN for standalone proto
27da2e3ebdSchin */
28da2e3ebdSchin
29da2e3ebdSchin #include "pplib.h"
30da2e3ebdSchin #include "ppfsm.h"
31da2e3ebdSchin
32da2e3ebdSchin /*
33da2e3ebdSchin * lexical FSM encoding
34da2e3ebdSchin * derived from a standalone ansi cpp by Dennis Ritchie
35da2e3ebdSchin * modified for libpp by Glenn Fowler
36da2e3ebdSchin *
37da2e3ebdSchin * fsm[] is initialized from fsminit[]. The encoding is blown out into
38da2e3ebdSchin * fsm[] for time efficiency. When in state state, and one of the
39da2e3ebdSchin * characters in ch arrives, enter nextstate. States >= TERMINAL are
40da2e3ebdSchin * either final, or at least require special action. In fsminit[] there
41da2e3ebdSchin * is a line for each <state,charset,nextstate>. Early entries are
42da2e3ebdSchin * overwritten by later ones. C_XXX is the universal set and should
43da2e3ebdSchin * always be first. Some of the fsminit[] entries are templates for
44da2e3ebdSchin * groups of states. The OP entries trigger the state copies. States
45da2e3ebdSchin * above TERMINAL are represented in fsm[] as negative values. S_TOK and
46da2e3ebdSchin * S_TOKB encode the resulting token type in the upper bits. These actions
47da2e3ebdSchin * differ in that S_TOKB has a lookahead char.
48da2e3ebdSchin *
49da2e3ebdSchin * fsm[] has three start states:
50da2e3ebdSchin *
51da2e3ebdSchin * PROTO proto (ANSI -> K&R,C++,ANSI)
52da2e3ebdSchin * QUICK standalone ppcpp()
53da2e3ebdSchin * TOKEN tokenizing pplex()
54da2e3ebdSchin *
55da2e3ebdSchin * If the next state remains the same then the fsm[] transition value is 0.
56da2e3ebdSchin * MAX+1 is a power of 2 so that fsm[state][EOF==MAX+1] actually accesses
57da2e3ebdSchin * fsm[state+1][0] which is ~S_EOB for all states. This preserves the
58da2e3ebdSchin * power of 2 fsm[] row size for efficient array indexing. Thanks to
59da2e3ebdSchin * D. G. Korn for the last two observations. The pseudo non-terminal state
60da2e3ebdSchin * fsm[TERMINAL][state+1] is used to differentiate EOB from EOF.
61da2e3ebdSchin *
62da2e3ebdSchin * The bit layout is:
63da2e3ebdSchin *
64da2e3ebdSchin * TERM arg SPLICE next
65da2e3ebdSchin * 15 14-8 7 6-0
66da2e3ebdSchin */
67da2e3ebdSchin
68da2e3ebdSchin /*
69da2e3ebdSchin * NOTE: these must be `control' characters for all native codesets
70da2e3ebdSchin * currently ok for {ascii,ebcdic1,ebcdic2,ebcdic3}
71da2e3ebdSchin */
72da2e3ebdSchin
73da2e3ebdSchin #define C_DEC 001
74da2e3ebdSchin #define C_EOF 002
75da2e3ebdSchin #define C_HEX 003
76da2e3ebdSchin #define C_LET 021
77da2e3ebdSchin #define C_OCT 022
78da2e3ebdSchin #define C_XXX 023
79da2e3ebdSchin
80da2e3ebdSchin #define OP (-1)
81da2e3ebdSchin #define END 0
82da2e3ebdSchin #define COPY 1
83da2e3ebdSchin
84da2e3ebdSchin #define copy(t,f) (memcpy(&fsm[t][1],&fsm[f][1],(MAX+1)*sizeof(short)),fsm[TERMINAL][(t)+1]=fsm[TERMINAL][(f)+1])
85da2e3ebdSchin
86da2e3ebdSchin struct fsminit /* fsm initialization row */
87da2e3ebdSchin {
88da2e3ebdSchin int state; /* if in this state */
89da2e3ebdSchin unsigned char ch[4]; /* and see one of these */
90da2e3ebdSchin int nextstate; /* enter this state if <TERMINAL*/
91da2e3ebdSchin };
92da2e3ebdSchin
93da2e3ebdSchin static struct fsminit fsminit[] =
94da2e3ebdSchin {
95da2e3ebdSchin /* proto start state */
96da2e3ebdSchin { PROTO, { C_XXX }, S_CHR, },
97da2e3ebdSchin { PROTO, { C_EOF }, S_EOF, },
98da2e3ebdSchin { PROTO, { C_DEC }, BAD1, },
99da2e3ebdSchin { PROTO, { '.' }, DOT, },
100da2e3ebdSchin { PROTO, { C_LET }, NID, },
101da2e3ebdSchin { PROTO, { 'L' }, LIT, },
102da2e3ebdSchin { PROTO, { 'd', 'e', 'f', 'i' }, RES1, },
103da2e3ebdSchin { PROTO, { 'r', 's', 't', 'v' }, RES1, },
104da2e3ebdSchin { PROTO, { 'w', 'N' }, RES1, },
105da2e3ebdSchin { PROTO, { '"', '\'' }, S_LITBEG, },
106da2e3ebdSchin { PROTO, { '/' }, COM1, },
107da2e3ebdSchin { PROTO, { '\n' }, S_NL, },
108da2e3ebdSchin { PROTO, { ' ','\t','\f','\v' }, WS1, },
109da2e3ebdSchin
110da2e3ebdSchin /* proto {do,else,extern,for,if,inline,return,static,typedef,va_start,void,while,NoN} */
111da2e3ebdSchin { RES1, { C_XXX }, S_MACRO, },
112da2e3ebdSchin { RES1, { C_LET, C_DEC }, NID, },
113da2e3ebdSchin { RES1, { 'a' }, RES1a, },
114da2e3ebdSchin { RES1, { 'e' }, RES1e, },
115da2e3ebdSchin { RES1, { 'f' }, RES1f, },
116da2e3ebdSchin { RES1, { 'h' }, RES1h, },
117da2e3ebdSchin { RES1, { 'l' }, RES1l, },
118da2e3ebdSchin { RES1, { 'n' }, RES1n, },
119da2e3ebdSchin { RES1, { 'o' }, RES1o, },
120da2e3ebdSchin { RES1, { 't' }, RES1t, },
121da2e3ebdSchin { RES1, { 'x' }, RES1x, },
122da2e3ebdSchin { RES1, { 'y' }, RES1y, },
123da2e3ebdSchin
124da2e3ebdSchin /* proto reserved {va_start} */
125da2e3ebdSchin { RES1a, { C_XXX }, S_RESERVED, },
126da2e3ebdSchin { RES1a, { C_LET, C_DEC }, NID, },
127da2e3ebdSchin { RES1a, { '_','s','t','a' }, RES1a, },
128da2e3ebdSchin { RES1a, { 'r' }, RES1a, },
129da2e3ebdSchin
130da2e3ebdSchin /* proto reserved {return} */
131da2e3ebdSchin { RES1e, { C_XXX }, S_RESERVED, },
132da2e3ebdSchin { RES1e, { C_LET, C_DEC }, NID, },
133da2e3ebdSchin { RES1e, { 't','u','r','n' }, RES1e, },
134da2e3ebdSchin
135da2e3ebdSchin /* proto reserved {if} */
136da2e3ebdSchin { RES1f, { C_XXX }, S_RESERVED, },
137da2e3ebdSchin { RES1f, { C_LET, C_DEC }, NID, },
138da2e3ebdSchin
139da2e3ebdSchin /* proto reserved {while} */
140da2e3ebdSchin { RES1h, { C_XXX }, S_RESERVED, },
141da2e3ebdSchin { RES1h, { C_LET, C_DEC }, NID, },
142da2e3ebdSchin { RES1h, { 'i','l','e' }, RES1h, },
143da2e3ebdSchin
144da2e3ebdSchin /* proto reserved {else} */
145da2e3ebdSchin { RES1l, { C_XXX }, S_RESERVED, },
146da2e3ebdSchin { RES1l, { C_LET, C_DEC }, NID, },
147da2e3ebdSchin { RES1l, { 's','e' }, RES1l, },
148da2e3ebdSchin
149da2e3ebdSchin /* proto reserved {inline} */
150da2e3ebdSchin { RES1n, { C_XXX }, S_RESERVED, },
151da2e3ebdSchin { RES1n, { C_LET, C_DEC }, NID, },
152da2e3ebdSchin { RES1n, { 'l','i','n','e' }, RES1n, },
153da2e3ebdSchin
154da2e3ebdSchin /* proto reserved {do,for,void} */
155da2e3ebdSchin { RES1o, { C_XXX }, S_RESERVED, },
156da2e3ebdSchin { RES1o, { C_LET, C_DEC }, NID, },
157da2e3ebdSchin { RES1o, { 'r','i','d','N' }, RES1o, },
158da2e3ebdSchin
159da2e3ebdSchin /* proto reserved {static} */
160da2e3ebdSchin { RES1t, { C_XXX }, S_RESERVED, },
161da2e3ebdSchin { RES1t, { C_LET, C_DEC }, NID, },
162da2e3ebdSchin { RES1t, { 'a','t','i','c' }, RES1t, },
163da2e3ebdSchin
164da2e3ebdSchin /* proto reserved {extern} */
165da2e3ebdSchin { RES1x, { C_XXX }, S_RESERVED, },
166da2e3ebdSchin { RES1x, { C_LET, C_DEC }, NID, },
167da2e3ebdSchin { RES1x, { 't','e','r','n' }, RES1x, },
168da2e3ebdSchin
169da2e3ebdSchin /* proto reserved {typedef} */
170da2e3ebdSchin { RES1y, { C_XXX }, S_RESERVED, },
171da2e3ebdSchin { RES1y, { C_LET, C_DEC }, NID, },
172da2e3ebdSchin { RES1y, { 'p','e','d','f' }, RES1y, },
173da2e3ebdSchin
174da2e3ebdSchin /* saw /, perhaps start of comment */
175da2e3ebdSchin { COM1, { C_XXX }, S_CHRB, },
176da2e3ebdSchin { COM1, { '*' }, COM2, },
177da2e3ebdSchin #if PROTOMAIN
178da2e3ebdSchin { COM1, { '/' }, COM5, },
179da2e3ebdSchin #endif
180da2e3ebdSchin
181da2e3ebdSchin /* saw / *, start of comment */
182da2e3ebdSchin { COM2, { C_XXX }, COM2, },
183da2e3ebdSchin { COM2, { '\n', C_EOF }, S_COMMENT, },
184da2e3ebdSchin { COM2, { '/' }, COM4, },
185da2e3ebdSchin { COM2, { '*' }, COM3, },
186da2e3ebdSchin { COM2, { '#', ';', ')' }, QUAL(COM2), },
187da2e3ebdSchin
188da2e3ebdSchin /* saw the * possibly ending a comment */
189da2e3ebdSchin { COM3, { C_XXX }, COM2, },
190da2e3ebdSchin { COM3, { '\n', C_EOF }, S_COMMENT, },
191da2e3ebdSchin { COM3, { '#', ';', ')' }, QUAL(COM2), },
192da2e3ebdSchin { COM3, { '*' }, COM3, },
193da2e3ebdSchin { COM3, { '/' }, S_COMMENT, },
194da2e3ebdSchin
195da2e3ebdSchin /* saw / in / * comment, possible malformed nest */
196da2e3ebdSchin { COM4, { C_XXX }, COM2, },
197da2e3ebdSchin { COM4, { '*', '\n', C_EOF }, S_COMMENT, },
198da2e3ebdSchin { COM4, { '/' }, COM4, },
199da2e3ebdSchin
200da2e3ebdSchin /* saw / /, start of comment */
201da2e3ebdSchin { COM5, { C_XXX }, COM5, },
202da2e3ebdSchin { COM5, { '\n', C_EOF }, S_COMMENT, },
203da2e3ebdSchin { COM5, { '/' }, COM6, },
204da2e3ebdSchin { COM5, { '*' }, COM7, },
205da2e3ebdSchin
206da2e3ebdSchin /* saw / in / / comment, possible malformed nest */
207da2e3ebdSchin { COM6, { C_XXX }, COM5, },
208da2e3ebdSchin { COM6, { '*', '\n', C_EOF }, S_COMMENT, },
209da2e3ebdSchin { COM6, { '/' }, COM6, },
210da2e3ebdSchin
211da2e3ebdSchin /* saw * in / /, possible malformed nest */
212da2e3ebdSchin { COM7, { C_XXX }, COM5, },
213da2e3ebdSchin { COM7, { '\n', C_EOF }, S_COMMENT, },
214da2e3ebdSchin { COM7, { '*' }, COM7, },
215da2e3ebdSchin { COM7, { '/' }, S_COMMENT, },
216da2e3ebdSchin
217da2e3ebdSchin /* normal identifier -- always a macro candidate */
218da2e3ebdSchin { NID, { C_XXX }, S_MACRO, },
219da2e3ebdSchin { NID, { C_LET, C_DEC }, NID, },
220da2e3ebdSchin
221da2e3ebdSchin /* saw ., operator or dbl constant */
222da2e3ebdSchin { DOT, { C_XXX }, S_CHRB, },
223da2e3ebdSchin { DOT, { '.' }, DOT2, },
224da2e3ebdSchin { DOT, { C_DEC }, BAD1, },
225da2e3ebdSchin
226da2e3ebdSchin /* saw .., possible ... */
227da2e3ebdSchin { DOT2, { C_XXX }, BACK(T_INVALID), },
228da2e3ebdSchin { DOT2, { '.' }, KEEP(T_VARIADIC), },
229da2e3ebdSchin
230da2e3ebdSchin /* saw L (possible start of normal wide literal) */
231da2e3ebdSchin { LIT, { C_XXX }, S_MACRO, },
232da2e3ebdSchin { LIT, { C_LET, C_DEC }, NID, },
233da2e3ebdSchin { LIT, { '"', '\'' }, QUAL(LIT1), },
234da2e3ebdSchin
235da2e3ebdSchin /* saw " or ' beginning literal */
236da2e3ebdSchin { LIT1, { C_XXX }, LIT1, },
237da2e3ebdSchin { LIT1, { '"', '\'' }, S_LITEND, },
238da2e3ebdSchin { LIT1, { '\n', C_EOF }, S_LITEND, },
239da2e3ebdSchin { LIT1, { '\\' }, LIT2, },
240da2e3ebdSchin
241da2e3ebdSchin /* saw \ in literal */
242da2e3ebdSchin { LIT2, { C_XXX }, S_LITESC, },
243da2e3ebdSchin { LIT2, { '\n', C_EOF }, S_LITEND, },
244da2e3ebdSchin
245da2e3ebdSchin /* eat malformed numeric constant */
246da2e3ebdSchin { BAD1, { C_XXX }, BACK(T_INVALID), },
247da2e3ebdSchin { BAD1, { C_LET, C_DEC, '.' }, BAD1, },
248da2e3ebdSchin { BAD1, { 'e', 'E' }, BAD2, },
249da2e3ebdSchin
250da2e3ebdSchin /* eat malformed numeric fraction|exponent */
251da2e3ebdSchin { BAD2, { C_XXX }, BACK(T_INVALID), },
252da2e3ebdSchin { BAD2, { C_LET, C_DEC, '.' }, BAD1, },
253da2e3ebdSchin { BAD2, { '+', '-' }, BAD1, },
254da2e3ebdSchin
255da2e3ebdSchin /* saw white space, eat it up */
256da2e3ebdSchin { WS1, { C_XXX }, S_WS, },
257da2e3ebdSchin { WS1, { ' ', '\t' }, WS1, },
258da2e3ebdSchin { WS1, { '\f', '\v' }, S_VS, },
259da2e3ebdSchin
260da2e3ebdSchin #if !PROTOMAIN
261da2e3ebdSchin
262da2e3ebdSchin /* quick template */
263da2e3ebdSchin { QUICK, { C_XXX }, QTOK, },
264da2e3ebdSchin { QUICK, { C_EOF, MARK }, S_CHRB, },
265da2e3ebdSchin { QUICK, { C_LET, C_DEC }, QID, },
266da2e3ebdSchin { QUICK, { 'L' }, LIT0, },
267da2e3ebdSchin { QUICK, { '"', '\'' }, S_LITBEG, },
268da2e3ebdSchin { QUICK, { '/' }, S_CHRB, },
269da2e3ebdSchin { QUICK, { '*' }, QCOM, },
270da2e3ebdSchin { QUICK, { '#' }, SHARP1, },
271da2e3ebdSchin { QUICK, { '\n' }, S_NL, },
272da2e3ebdSchin { QUICK, { '\f', '\v' }, S_VS, },
273da2e3ebdSchin
274da2e3ebdSchin /* copy QUICK to QUICK+1 through MAC0+1 */
275da2e3ebdSchin { OP, {QUICK,QUICK+1,MAC0+1}, COPY, },
276da2e3ebdSchin
277da2e3ebdSchin /* quick start state */
278da2e3ebdSchin { QUICK, { C_EOF }, S_EOF, },
279da2e3ebdSchin { QUICK, { C_DEC }, QNUM, },
280da2e3ebdSchin { QUICK, { MARK }, QTOK, },
281da2e3ebdSchin { QUICK, { '/' }, COM1, },
282da2e3ebdSchin { QUICK, { ' ', '\t' }, QUICK, },
283da2e3ebdSchin
284da2e3ebdSchin /* grab non-macro tokens */
285da2e3ebdSchin { QTOK, { C_DEC }, QNUM, },
286da2e3ebdSchin
287da2e3ebdSchin /* grab numeric and invalid tokens */
288da2e3ebdSchin { QNUM, { C_LET, C_DEC, '.' }, QNUM, },
289da2e3ebdSchin { QNUM, { 'e', 'E' }, QEXP, },
290da2e3ebdSchin
291da2e3ebdSchin /* grab exponent token */
292da2e3ebdSchin { QEXP, { C_LET, C_DEC, '.' }, QNUM, },
293da2e3ebdSchin { QEXP, { '+', '-' }, QNUM, },
294da2e3ebdSchin
295da2e3ebdSchin /* saw *, grab possible bad comment terminator */
296da2e3ebdSchin { QCOM, { C_DEC }, QNUM, },
297da2e3ebdSchin { QCOM, { '/' }, S_COMMENT, },
298da2e3ebdSchin
299da2e3ebdSchin /* saw L (possible start of wide string or first macro char) */
300da2e3ebdSchin { MAC0, { 'L' }, QID, },
301da2e3ebdSchin { MAC0, { '"', '\'' }, QUAL(LIT1), },
302da2e3ebdSchin
303da2e3ebdSchin /* macro candidate template */
304da2e3ebdSchin { MAC0+1, { 'L' }, QID, },
305da2e3ebdSchin
306da2e3ebdSchin /* copy MAC0+1 to MAC0+2 through MACN */
307da2e3ebdSchin { OP, {MAC0+1,MAC0+2,MACN}, COPY },
308da2e3ebdSchin
309da2e3ebdSchin /* saw L (possible start of wide string or macro L) */
310da2e3ebdSchin { HIT0, { C_XXX }, S_MACRO, },
311da2e3ebdSchin { HIT0, { C_LET, C_DEC }, QID, },
312da2e3ebdSchin { HIT0, { '"', '\'' }, QUAL(LIT1), },
313da2e3ebdSchin
314da2e3ebdSchin /* macro hit template */
315da2e3ebdSchin { HIT0+1, { C_XXX }, S_MACRO, },
316da2e3ebdSchin { HIT0+1, { C_LET, C_DEC }, QID, },
317da2e3ebdSchin
318da2e3ebdSchin /* copy HIT0+1 to HIT0+2 through HITN */
319da2e3ebdSchin { OP, {HIT0+1,HIT0+2,HITN}, COPY },
320da2e3ebdSchin
321da2e3ebdSchin /* saw L (possible start of wide literal) */
322da2e3ebdSchin { LIT0, { C_XXX }, S_MACRO, },
323da2e3ebdSchin { LIT0, { C_LET, C_DEC }, QID, },
324da2e3ebdSchin { LIT0, { '"', '\'' }, QUAL(LIT1), },
325da2e3ebdSchin
326da2e3ebdSchin /* (!PROTOMAIN COM1) saw /, perhaps start of comment or /= */
327da2e3ebdSchin { COM1, { '=' }, KEEP(T_DIVEQ), },
328da2e3ebdSchin
329da2e3ebdSchin /* normal start state */
330da2e3ebdSchin { TOKEN, { C_XXX }, S_HUH, },
331da2e3ebdSchin { TOKEN, { C_EOF }, S_EOF, },
332da2e3ebdSchin { TOKEN, { C_DEC }, DEC1, },
333da2e3ebdSchin { TOKEN, { '0' }, OCT1, },
334da2e3ebdSchin { TOKEN, { '.' }, DOT1, },
335da2e3ebdSchin { TOKEN, { C_LET }, NID, },
336da2e3ebdSchin { TOKEN, { 'L' }, LIT, },
337da2e3ebdSchin { TOKEN, { '"', '\'', '<' }, S_LITBEG, },
338da2e3ebdSchin { TOKEN, { '/' }, COM1, },
339da2e3ebdSchin { TOKEN, { '\n' }, S_NL, },
340da2e3ebdSchin { TOKEN, { ' ', '\t' }, WS1, },
341da2e3ebdSchin { TOKEN, { '\f', '\v' }, S_VS, },
342da2e3ebdSchin { TOKEN, { '#' }, SHARP1, },
343da2e3ebdSchin { TOKEN, { ':' }, COLON1, },
344da2e3ebdSchin { TOKEN, { '%' }, PCT1, },
345da2e3ebdSchin { TOKEN, { '&' }, AND1, },
346da2e3ebdSchin { TOKEN, { '*' }, STAR1, },
347da2e3ebdSchin { TOKEN, { '+' }, PLUS1, },
348da2e3ebdSchin { TOKEN, { '-' }, MINUS1, },
349da2e3ebdSchin { TOKEN, { '=' }, EQ1, },
350da2e3ebdSchin { TOKEN, { '!' }, NOT1, },
351da2e3ebdSchin { TOKEN, { '>' }, GT1, },
352da2e3ebdSchin { TOKEN, { '^' }, CIRC1, },
353da2e3ebdSchin { TOKEN, { '|' }, OR1, },
354da2e3ebdSchin { TOKEN, { '(', ')', '[', ']' }, S_CHR, },
355da2e3ebdSchin { TOKEN, { '{', '}', ',', ';' }, S_CHR, },
356da2e3ebdSchin { TOKEN, { '~', '?' }, S_CHR, },
357da2e3ebdSchin
358da2e3ebdSchin /* saw 0, possible oct|hex|dec|dbl constant */
359da2e3ebdSchin { OCT1, { C_XXX }, BACK(T_DECIMAL), },
360da2e3ebdSchin { OCT1, { C_LET, C_DEC }, BAD1, },
361da2e3ebdSchin { OCT1, { C_OCT }, OCT2, },
362da2e3ebdSchin { OCT1, { 'e', 'E' }, DBL2, },
363da2e3ebdSchin { OCT1, { 'l', 'L', 'u', 'U' }, QUAL(DEC2), },
364da2e3ebdSchin { OCT1, { 'x', 'X' }, HEX1, },
365da2e3ebdSchin { OCT1, { '.' }, DBL1, },
366da2e3ebdSchin
367da2e3ebdSchin /* saw 0<oct>, oct constant */
368da2e3ebdSchin { OCT2, { C_XXX }, BACK(T_OCTAL), },
369da2e3ebdSchin { OCT2, { C_LET, C_DEC }, BAD1, },
370da2e3ebdSchin { OCT2, { C_OCT }, OCT2, },
371da2e3ebdSchin { OCT2, { 'e', 'E' }, DBL2, },
372da2e3ebdSchin { OCT2, { 'l', 'L', 'u', 'U' }, QUAL(OCT3), },
373da2e3ebdSchin { OCT2, { '.' }, DBL1, },
374da2e3ebdSchin
375da2e3ebdSchin /* oct constant qualifier */
376da2e3ebdSchin { OCT3, { C_XXX }, BACK(T_OCTAL), },
377da2e3ebdSchin { OCT3, { C_LET, C_DEC, '.' }, BAD1, },
378da2e3ebdSchin { OCT3, { 'l', 'L', 'u', 'U' }, QUAL(OCT3), },
379da2e3ebdSchin
380da2e3ebdSchin /* saw 0 [xX], hex constant */
381da2e3ebdSchin { HEX1, { C_XXX }, BACK(T_HEXADECIMAL), },
382da2e3ebdSchin { HEX1, { C_LET }, BAD1, },
383da2e3ebdSchin { HEX1, { C_HEX }, HEX1, },
384da2e3ebdSchin { HEX1, { 'e', 'E' }, HEX3, },
385da2e3ebdSchin { HEX1, { 'l', 'L', 'u', 'U' }, QUAL(HEX2), },
386da2e3ebdSchin { HEX1, { '.' }, HEX4, },
387da2e3ebdSchin { HEX1, { 'p', 'P' }, HEX5, },
388da2e3ebdSchin
389da2e3ebdSchin /* hex constant qualifier */
390da2e3ebdSchin { HEX2, { C_XXX }, BACK(T_HEXADECIMAL), },
391da2e3ebdSchin { HEX2, { C_LET, C_DEC, '.' }, BAD1, },
392da2e3ebdSchin { HEX2, { 'l', 'L', 'u', 'U' }, QUAL(HEX2), },
393da2e3ebdSchin
394da2e3ebdSchin /* hex [eE][-+] botch */
395da2e3ebdSchin { HEX3, { C_XXX }, BACK(T_HEXADECIMAL), },
396da2e3ebdSchin { HEX3, { C_LET, '.', '-', '+'},BAD1, },
397da2e3ebdSchin { HEX3, { C_HEX }, HEX1, },
398da2e3ebdSchin { HEX3, { 'e', 'E' }, HEX3, },
399da2e3ebdSchin { HEX3, { 'l', 'L', 'u', 'U' }, QUAL(HEX2), },
400da2e3ebdSchin
401da2e3ebdSchin /* hex dbl fraction */
402da2e3ebdSchin { HEX4, { C_XXX }, BACK(T_HEXDOUBLE), },
403da2e3ebdSchin { HEX4, { C_LET, '.' }, BAD1, },
404da2e3ebdSchin { HEX4, { C_HEX }, HEX4, },
405da2e3ebdSchin { HEX4, { 'p', 'P' }, HEX5, },
406da2e3ebdSchin { HEX4, { 'f', 'F', 'l', 'L' }, QUAL(HEX8), },
407da2e3ebdSchin
408da2e3ebdSchin /* optional hex dbl exponent sign */
409da2e3ebdSchin { HEX5, { C_XXX }, BACK(T_INVALID), },
410da2e3ebdSchin { HEX5, { C_LET, '.' }, BAD1, },
411da2e3ebdSchin { HEX5, { '+', '-' }, HEX6, },
412da2e3ebdSchin { HEX5, { C_DEC }, HEX7, },
413da2e3ebdSchin
414da2e3ebdSchin /* mandatory hex dbl exponent first digit */
415da2e3ebdSchin { HEX6, { C_XXX }, BACK(T_INVALID), },
416da2e3ebdSchin { HEX6, { C_LET, '.' }, BAD1, },
417da2e3ebdSchin { HEX6, { C_DEC }, HEX7, },
418da2e3ebdSchin
419da2e3ebdSchin /* hex dbl exponent digits */
420da2e3ebdSchin { HEX7, { C_XXX }, BACK(T_HEXDOUBLE), },
421da2e3ebdSchin { HEX7, { C_LET, '.' }, BAD1, },
422da2e3ebdSchin { HEX7, { C_DEC }, HEX7, },
423da2e3ebdSchin { HEX7, { 'f', 'F', 'l', 'L' }, QUAL(HEX8), },
424da2e3ebdSchin
425da2e3ebdSchin /* hex dbl constant qualifier */
426da2e3ebdSchin { HEX8, { C_XXX }, BACK(T_HEXDOUBLE), },
427da2e3ebdSchin { HEX8, { C_LET, '.' }, BAD1, },
428da2e3ebdSchin { HEX8, { 'f', 'F', 'l', 'L' }, QUAL(HEX8), },
429da2e3ebdSchin
430da2e3ebdSchin /* saw <dec>, dec constant */
431da2e3ebdSchin { DEC1, { C_XXX }, BACK(T_DECIMAL), },
432da2e3ebdSchin { DEC1, { C_LET }, BAD1, },
433da2e3ebdSchin { DEC1, { C_DEC }, DEC1, },
434da2e3ebdSchin { DEC1, { 'e', 'E' }, DBL2, },
435da2e3ebdSchin { DEC1, { 'l', 'L', 'u', 'U' }, QUAL(DEC2), },
436da2e3ebdSchin { DEC1, { '.' }, DBL1, },
437da2e3ebdSchin
438da2e3ebdSchin /* dec constant qualifier */
439da2e3ebdSchin { DEC2, { C_XXX }, BACK(T_DECIMAL), },
440da2e3ebdSchin { DEC2, { C_LET, C_DEC }, BAD1, },
441da2e3ebdSchin { DEC2, { 'l', 'L', 'u', 'U' }, QUAL(DEC2), },
442da2e3ebdSchin
443da2e3ebdSchin /* saw ., operator or dbl constant */
444da2e3ebdSchin { DOT1, { C_XXX }, S_CHRB, },
445da2e3ebdSchin { DOT1, { '.' }, DOT2, },
446da2e3ebdSchin { DOT1, { C_DEC }, DBL1, },
447da2e3ebdSchin
448da2e3ebdSchin /* dbl fraction */
449da2e3ebdSchin { DBL1, { C_XXX }, BACK(T_DOUBLE), },
450da2e3ebdSchin { DBL1, { C_LET, '.' }, BAD1, },
451da2e3ebdSchin { DBL1, { C_DEC }, DBL1, },
452da2e3ebdSchin { DBL1, { 'e', 'E' }, DBL2, },
453da2e3ebdSchin { DBL1, { 'f', 'F', 'l', 'L' }, QUAL(DBL5), },
454da2e3ebdSchin
455da2e3ebdSchin /* optional dbl exponent sign */
456da2e3ebdSchin { DBL2, { C_XXX }, BACK(T_INVALID), },
457da2e3ebdSchin { DBL2, { C_LET, '.' }, BAD1, },
458da2e3ebdSchin { DBL2, { '+', '-' }, DBL3, },
459da2e3ebdSchin { DBL2, { C_DEC }, DBL4, },
460da2e3ebdSchin
461da2e3ebdSchin /* mandatory dbl exponent first digit */
462da2e3ebdSchin { DBL3, { C_XXX }, BACK(T_INVALID), },
463da2e3ebdSchin { DBL3, { C_LET, '.' }, BAD1, },
464da2e3ebdSchin { DBL3, { C_DEC }, DBL4, },
465da2e3ebdSchin
466da2e3ebdSchin /* dbl exponent digits */
467da2e3ebdSchin { DBL4, { C_XXX }, BACK(T_DOUBLE), },
468da2e3ebdSchin { DBL4, { C_LET, '.' }, BAD1, },
469da2e3ebdSchin { DBL4, { C_DEC }, DBL4, },
470da2e3ebdSchin { DBL4, { 'f', 'F', 'l', 'L' }, QUAL(DBL5), },
471da2e3ebdSchin
472da2e3ebdSchin /* dbl constant qualifier */
473da2e3ebdSchin { DBL5, { C_XXX }, BACK(T_DOUBLE), },
474da2e3ebdSchin { DBL5, { C_LET, '.' }, BAD1, },
475da2e3ebdSchin { DBL5, { 'f', 'F', 'l', 'L' }, QUAL(DBL5), },
476da2e3ebdSchin
477da2e3ebdSchin /* saw < starting include header */
478da2e3ebdSchin { HDR1, { C_XXX }, HDR1, },
479da2e3ebdSchin { HDR1, { '>', '\n', C_EOF }, S_LITEND, },
480da2e3ebdSchin
481da2e3ebdSchin /* saw <binop><space> expecting = */
482da2e3ebdSchin { BIN1, { C_XXX }, S_HUH, },
483da2e3ebdSchin { BIN1, { ' ', '\t' }, BIN1, },
484da2e3ebdSchin
485da2e3ebdSchin /* 2-char ops */
486da2e3ebdSchin
487da2e3ebdSchin { SHARP1, { C_XXX }, S_SHARP, },
488da2e3ebdSchin
489da2e3ebdSchin { PCT1, { C_XXX }, S_CHRB, },
490da2e3ebdSchin { PCT1, { '=' }, KEEP(T_MODEQ), },
491da2e3ebdSchin
492da2e3ebdSchin { AND1, { C_XXX }, S_CHRB, },
493da2e3ebdSchin { AND1, { '=' }, KEEP(T_ANDEQ), },
494da2e3ebdSchin { AND1, { '&' }, KEEP(T_ANDAND), },
495da2e3ebdSchin
496da2e3ebdSchin { STAR1, { C_XXX }, S_CHRB, },
497da2e3ebdSchin { STAR1, { '=' }, KEEP(T_MPYEQ), },
498da2e3ebdSchin { STAR1, { '/' }, S_COMMENT, },
499da2e3ebdSchin
500da2e3ebdSchin { PLUS1, { C_XXX }, S_CHRB, },
501da2e3ebdSchin { PLUS1, { '=' }, KEEP(T_ADDEQ), },
502da2e3ebdSchin { PLUS1, { '+' }, KEEP(T_ADDADD), },
503da2e3ebdSchin
504da2e3ebdSchin { MINUS1, { C_XXX }, S_CHRB, },
505da2e3ebdSchin { MINUS1, { '=' }, KEEP(T_SUBEQ), },
506da2e3ebdSchin { MINUS1, { '-' }, KEEP(T_SUBSUB), },
507da2e3ebdSchin { MINUS1, { '>' }, KEEP(T_PTRMEM), },
508da2e3ebdSchin
509da2e3ebdSchin { COLON1, { C_XXX }, S_CHRB, },
510da2e3ebdSchin { COLON1, { '=', '>' }, S_HUH, },
511da2e3ebdSchin
512da2e3ebdSchin { LT1, { C_XXX }, S_CHRB, },
513da2e3ebdSchin { LT1, { '=' }, KEEP(T_LE), },
514da2e3ebdSchin { LT1, { '<' }, LSH1, },
515da2e3ebdSchin
516da2e3ebdSchin { EQ1, { C_XXX }, S_CHRB, },
517da2e3ebdSchin { EQ1, { '=' }, KEEP(T_EQ), },
518da2e3ebdSchin
519da2e3ebdSchin { NOT1, { C_XXX }, S_CHRB, },
520da2e3ebdSchin { NOT1, { '=' }, KEEP(T_NE), },
521da2e3ebdSchin
522da2e3ebdSchin { GT1, { C_XXX }, S_CHRB, },
523da2e3ebdSchin { GT1, { '=' }, KEEP(T_GE), },
524da2e3ebdSchin { GT1, { '>' }, RSH1, },
525da2e3ebdSchin
526da2e3ebdSchin { CIRC1, { C_XXX }, S_CHRB, },
527da2e3ebdSchin { CIRC1, { '=' }, KEEP(T_XOREQ), },
528da2e3ebdSchin
529da2e3ebdSchin { OR1, { C_XXX }, S_CHRB, },
530da2e3ebdSchin { OR1, { '=' }, KEEP(T_OREQ), },
531da2e3ebdSchin { OR1, { '|' }, KEEP(T_OROR), },
532da2e3ebdSchin
533da2e3ebdSchin /* 3-char ops */
534da2e3ebdSchin
535da2e3ebdSchin { ARROW1, { C_XXX }, BACK(T_PTRMEM), },
536da2e3ebdSchin { ARROW1, { '*' }, KEEP(T_PTRMEMREF), },
537da2e3ebdSchin
538da2e3ebdSchin { LSH1, { C_XXX }, BACK(T_LSHIFT), },
539da2e3ebdSchin { LSH1, { '=' }, KEEP(T_LSHIFTEQ), },
540da2e3ebdSchin
541da2e3ebdSchin { RSH1, { C_XXX }, BACK(T_RSHIFT), },
542da2e3ebdSchin { RSH1, { '=' }, KEEP(T_RSHIFTEQ), },
543da2e3ebdSchin
544da2e3ebdSchin #endif
545da2e3ebdSchin
546da2e3ebdSchin /* end */
547da2e3ebdSchin { OP, { 0 }, END, }
548da2e3ebdSchin };
549da2e3ebdSchin
550da2e3ebdSchin short fsm[TERMINAL+1][MAX+1];
551da2e3ebdSchin
552da2e3ebdSchin char trigraph[MAX+1];
553da2e3ebdSchin
554da2e3ebdSchin #if PROTOMAIN
555da2e3ebdSchin static char spl[] = { '\\', '\r', 0 };
556da2e3ebdSchin static char aln[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_$@";
557da2e3ebdSchin #else
558da2e3ebdSchin static char spl[] = { MARK, '?', '\\', '\r', CC_sub, 0 };
559da2e3ebdSchin static char aln[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_";
560da2e3ebdSchin #endif
561da2e3ebdSchin static char* let = &aln[10];
562da2e3ebdSchin static char hex[] = "fedcbaFEDCBA9876543210";
563da2e3ebdSchin static char* dec = &hex[12];
564da2e3ebdSchin static char* oct = &hex[14];
565da2e3ebdSchin
566da2e3ebdSchin /*
567da2e3ebdSchin * runtime FSM modifications
568da2e3ebdSchin * ppfsm(FSM_INIT,0) must be called first
569da2e3ebdSchin */
570da2e3ebdSchin
571da2e3ebdSchin void
ppfsm(int op,register char * s)572da2e3ebdSchin ppfsm(int op, register char* s)
573da2e3ebdSchin {
574da2e3ebdSchin register int c;
575da2e3ebdSchin register int n;
576da2e3ebdSchin register int i;
577da2e3ebdSchin register short* rp;
578da2e3ebdSchin register struct fsminit* fp;
579da2e3ebdSchin #if !PROTOMAIN
580da2e3ebdSchin char* t;
581da2e3ebdSchin int x;
582da2e3ebdSchin #endif
583da2e3ebdSchin
584da2e3ebdSchin switch (op)
585da2e3ebdSchin {
586da2e3ebdSchin
587da2e3ebdSchin #if !PROTOMAIN
588da2e3ebdSchin
589da2e3ebdSchin case FSM_IDADD:
590da2e3ebdSchin while (c = *s++)
591da2e3ebdSchin if (!ppisid(c))
592da2e3ebdSchin {
593da2e3ebdSchin if (fsm[TOKEN][c] == ~S_HUH)
594da2e3ebdSchin {
595da2e3ebdSchin setid(c);
596da2e3ebdSchin for (i = 0; i < TERMINAL; i++)
597da2e3ebdSchin fsm[i][c] = IDSTATE(fsm[i]['_']);
598da2e3ebdSchin }
599da2e3ebdSchin else error(2, "%c: cannot add to identifier set", c);
600da2e3ebdSchin }
601da2e3ebdSchin break;
602da2e3ebdSchin
603da2e3ebdSchin case FSM_IDDEL:
604da2e3ebdSchin while (c = *s++)
605da2e3ebdSchin if (ppisid(c))
606da2e3ebdSchin {
607da2e3ebdSchin clrid(c);
608da2e3ebdSchin for (i = 0; i < TERMINAL; i++)
609da2e3ebdSchin fsm[i][c] = ~S_HUH;
610da2e3ebdSchin }
611da2e3ebdSchin break;
612da2e3ebdSchin
613da2e3ebdSchin #endif
614da2e3ebdSchin
615da2e3ebdSchin case FSM_INIT:
616da2e3ebdSchin for (fp = fsminit;; fp++)
617da2e3ebdSchin {
618da2e3ebdSchin if ((n = fp->nextstate) >= TERMINAL) n = ~n;
619da2e3ebdSchin if (fp->state == OP)
620da2e3ebdSchin {
621da2e3ebdSchin #if !PROTOMAIN
622da2e3ebdSchin switch (n)
623da2e3ebdSchin {
624da2e3ebdSchin case COPY:
625da2e3ebdSchin c = fp->ch[0];
626da2e3ebdSchin n = fp->ch[2];
627da2e3ebdSchin for (i = fp->ch[1]; i <= n; i++)
628da2e3ebdSchin copy(i, c);
629da2e3ebdSchin continue;
630da2e3ebdSchin default:
631da2e3ebdSchin break;
632da2e3ebdSchin }
633da2e3ebdSchin #endif
634da2e3ebdSchin break;
635da2e3ebdSchin }
636da2e3ebdSchin rp = fsm[fp->state];
637da2e3ebdSchin for (i = 0; i < sizeof(fp->ch) && (c = fp->ch[i]); i++)
638da2e3ebdSchin {
639da2e3ebdSchin switch (c)
640da2e3ebdSchin {
641da2e3ebdSchin case C_XXX:
642da2e3ebdSchin for (c = 0; c <= MAX; c++)
643da2e3ebdSchin rp[c] = n;
644da2e3ebdSchin /*FALLTHROUGH*/
645da2e3ebdSchin
646da2e3ebdSchin case C_EOF:
647da2e3ebdSchin fsm[TERMINAL][fp->state+1] = n < 0 ? ~n : n;
648da2e3ebdSchin continue;
649da2e3ebdSchin
650da2e3ebdSchin case C_LET:
651da2e3ebdSchin s = let;
652da2e3ebdSchin break;
653da2e3ebdSchin
654da2e3ebdSchin case C_HEX:
655da2e3ebdSchin s = hex;
656da2e3ebdSchin break;
657da2e3ebdSchin
658da2e3ebdSchin case C_DEC:
659da2e3ebdSchin s = dec;
660da2e3ebdSchin break;
661da2e3ebdSchin
662da2e3ebdSchin case C_OCT:
663da2e3ebdSchin s = oct;
664da2e3ebdSchin break;
665da2e3ebdSchin
666da2e3ebdSchin default:
667da2e3ebdSchin rp[c] = n;
668da2e3ebdSchin continue;
669da2e3ebdSchin }
670da2e3ebdSchin while (c = *s++)
671da2e3ebdSchin rp[c] = n;
672da2e3ebdSchin }
673da2e3ebdSchin }
674da2e3ebdSchin
675da2e3ebdSchin /*
676da2e3ebdSchin * install splice special cases
677da2e3ebdSchin * and same non-terminal transitions
678da2e3ebdSchin */
679da2e3ebdSchin
680da2e3ebdSchin for (i = 0; i < TERMINAL; i++)
681da2e3ebdSchin {
682da2e3ebdSchin rp = fsm[i];
683da2e3ebdSchin s = spl;
684da2e3ebdSchin while (c = *s++)
685da2e3ebdSchin if (c != MARK || !INCOMMENT(rp))
686da2e3ebdSchin {
687da2e3ebdSchin if (rp[c] >= 0) rp[c] = ~rp[c];
688da2e3ebdSchin rp[c] &= ~SPLICE;
689da2e3ebdSchin }
690da2e3ebdSchin rp[EOB] = ~S_EOB;
691da2e3ebdSchin for (c = 0; c <= MAX; c++)
692da2e3ebdSchin if (rp[c] == i)
693da2e3ebdSchin rp[c] = 0;
694da2e3ebdSchin }
695da2e3ebdSchin fsm[TERMINAL][0] = ~S_EOB;
696da2e3ebdSchin
697da2e3ebdSchin #if !PROTOMAIN
698da2e3ebdSchin
699da2e3ebdSchin /*
700da2e3ebdSchin * default character types
701da2e3ebdSchin */
702da2e3ebdSchin
703da2e3ebdSchin s = let;
704da2e3ebdSchin while (c = *s++)
705da2e3ebdSchin setid(c);
706da2e3ebdSchin s = dec;
707da2e3ebdSchin while (c = *s++)
708da2e3ebdSchin setdig(c);
709da2e3ebdSchin s = spl;
710da2e3ebdSchin do setsplice(c = *s++); while (c);
711da2e3ebdSchin
712da2e3ebdSchin /*
713da2e3ebdSchin * trigraph map
714da2e3ebdSchin */
715da2e3ebdSchin
716da2e3ebdSchin trigraph['='] = '#';
717da2e3ebdSchin trigraph['('] = '[';
718da2e3ebdSchin trigraph['/'] = '\\';
719da2e3ebdSchin trigraph[')'] = ']';
720da2e3ebdSchin trigraph['\''] = '^';
721da2e3ebdSchin trigraph['<'] = '{';
722da2e3ebdSchin trigraph['!'] = '|';
723da2e3ebdSchin trigraph['>'] = '}';
724da2e3ebdSchin trigraph['-'] = '~';
725da2e3ebdSchin #endif
726da2e3ebdSchin break;
727da2e3ebdSchin
728da2e3ebdSchin #if !PROTOMAIN
729da2e3ebdSchin
730da2e3ebdSchin case FSM_PLUSPLUS:
731da2e3ebdSchin if (pp.option & PLUSPLUS)
732da2e3ebdSchin {
733da2e3ebdSchin fsm[COLON1][':'] = ~KEEP(T_SCOPE);
734da2e3ebdSchin fsm[DOT1]['*'] = ~KEEP(T_DOTREF);
735da2e3ebdSchin fsm[MINUS1]['>'] = ARROW1;
736da2e3ebdSchin fsm[COM1]['/'] = COM5;
737da2e3ebdSchin t = "%<:";
738da2e3ebdSchin for (i = 0; i < TERMINAL; i++)
739da2e3ebdSchin {
740da2e3ebdSchin rp = fsm[i];
741da2e3ebdSchin if (!INCOMMENT(rp) && !INQUOTE(rp))
742da2e3ebdSchin {
743da2e3ebdSchin s = t;
744da2e3ebdSchin while (c = *s++)
745da2e3ebdSchin {
746da2e3ebdSchin if (rp[c] > 0) rp[c] = ~rp[c];
747da2e3ebdSchin else if (!rp[c]) rp[c] = ~i;
748da2e3ebdSchin rp[c] &= ~SPLICE;
749da2e3ebdSchin }
750da2e3ebdSchin }
751da2e3ebdSchin }
752da2e3ebdSchin s = t;
753da2e3ebdSchin while (c = *s++) setsplice(c);
754da2e3ebdSchin }
755da2e3ebdSchin else
756da2e3ebdSchin {
757da2e3ebdSchin fsm[COLON1][':'] = ~S_CHRB;
758da2e3ebdSchin fsm[DOT1]['*'] = ~S_CHRB;
759da2e3ebdSchin fsm[MINUS1]['>'] = ~KEEP(T_PTRMEM);
760da2e3ebdSchin fsm[COM1]['/'] = (pp.option & PLUSCOMMENT) ? COM5 : ~S_CHRB;
761da2e3ebdSchin }
762da2e3ebdSchin break;
763da2e3ebdSchin
764da2e3ebdSchin #if COMPATIBLE
765da2e3ebdSchin
766da2e3ebdSchin case FSM_COMPATIBILITY:
767da2e3ebdSchin if (pp.state & COMPATIBILITY)
768da2e3ebdSchin {
769da2e3ebdSchin fsm[HEX1]['e'] = HEX1;
770da2e3ebdSchin fsm[HEX1]['E'] = HEX1;
771da2e3ebdSchin fsm[QNUM]['e'] = QNUM;
772da2e3ebdSchin fsm[QNUM]['E'] = QNUM;
773da2e3ebdSchin fsm[QNUM]['u'] = ~QUAL(QNUM);
774da2e3ebdSchin fsm[QNUM]['U'] = ~QUAL(QNUM);
775da2e3ebdSchin }
776da2e3ebdSchin else
777da2e3ebdSchin {
778da2e3ebdSchin fsm[HEX1]['e'] = HEX3;
779da2e3ebdSchin fsm[HEX1]['E'] = HEX3;
780da2e3ebdSchin fsm[QNUM]['e'] = QEXP;
781da2e3ebdSchin fsm[QNUM]['E'] = QEXP;
782da2e3ebdSchin fsm[QNUM]['u'] = QNUM;
783da2e3ebdSchin fsm[QNUM]['U'] = QNUM;
784da2e3ebdSchin }
785da2e3ebdSchin break;
786da2e3ebdSchin
787da2e3ebdSchin #endif
788da2e3ebdSchin
789da2e3ebdSchin case FSM_QUOTADD:
790da2e3ebdSchin while (c = *s++)
791da2e3ebdSchin if (fsm[TOKEN][c] == ~S_HUH)
792da2e3ebdSchin for (i = 0; i < TERMINAL; i++)
793da2e3ebdSchin fsm[i][c] = fsm[i]['"'];
794da2e3ebdSchin else error(2, "%c: cannot add to quote set", c);
795da2e3ebdSchin break;
796da2e3ebdSchin
797da2e3ebdSchin case FSM_QUOTDEL:
798da2e3ebdSchin while (c = *s++)
799da2e3ebdSchin if (c != '"' && fsm[TOKEN][c] == fsm[TOKEN]['"'])
800da2e3ebdSchin for (i = 0; i < TERMINAL; i++)
801da2e3ebdSchin fsm[i][c] = fsm[i]['_'];
802da2e3ebdSchin break;
803da2e3ebdSchin
804da2e3ebdSchin case FSM_OPSPACE:
805da2e3ebdSchin n = s ? BIN1 : ~S_CHRB;
806da2e3ebdSchin fsm[COM1][' '] = fsm[COM1]['\t'] = n;
807da2e3ebdSchin fsm[AND1][' '] = fsm[AND1]['\t'] = n;
808da2e3ebdSchin fsm[STAR1][' '] = fsm[STAR1]['\t'] = n;
809da2e3ebdSchin fsm[PCT1][' '] = fsm[PCT1]['\t'] = n;
810da2e3ebdSchin fsm[PLUS1][' '] = fsm[PLUS1]['\t'] = n;
811da2e3ebdSchin fsm[MINUS1][' '] = fsm[MINUS1]['\t'] = n;
812da2e3ebdSchin fsm[CIRC1][' '] = fsm[CIRC1]['\t'] = n;
813da2e3ebdSchin fsm[OR1][' '] = fsm[OR1]['\t'] = n;
814da2e3ebdSchin fsm[LSH1][' '] = fsm[LSH1]['\t'] = s ? BIN1 : ~BACK(T_LSHIFT);
815da2e3ebdSchin fsm[RSH1][' '] = fsm[RSH1]['\t'] = s ? BIN1 : ~BACK(T_RSHIFT);
816da2e3ebdSchin break;
817da2e3ebdSchin
818da2e3ebdSchin case FSM_MACRO:
819da2e3ebdSchin if (pp.truncate && strlen(s) >= pp.truncate)
820da2e3ebdSchin {
821da2e3ebdSchin x = s[pp.truncate];
822da2e3ebdSchin s[pp.truncate] = 0;
823da2e3ebdSchin }
824da2e3ebdSchin else x = -1;
825da2e3ebdSchin i = MAC0 + ((c = *s++) != 'L');
826da2e3ebdSchin if ((n = fsm[QUICK][c]) != (i + NMAC))
827da2e3ebdSchin {
828da2e3ebdSchin n = i;
829da2e3ebdSchin if (!*s) n += NMAC;
830da2e3ebdSchin }
831da2e3ebdSchin if (fsm[QUICK][c] != n)
832da2e3ebdSchin fsm[QUICK][c] = fsm[QCOM][c] = fsm[QTOK][c] = n;
833da2e3ebdSchin if (c = *s++)
834da2e3ebdSchin {
835da2e3ebdSchin for (;;)
836da2e3ebdSchin {
837da2e3ebdSchin if ((i = n) < HIT0)
838da2e3ebdSchin {
839da2e3ebdSchin if (n < MACN) n++;
840da2e3ebdSchin if (!*s)
841da2e3ebdSchin {
842da2e3ebdSchin n += NMAC;
843da2e3ebdSchin break;
844da2e3ebdSchin }
845da2e3ebdSchin if (fsm[i][c] < HIT0)
846da2e3ebdSchin fsm[i][c] = n;
847da2e3ebdSchin if (fsm[i + NMAC][c] < HIT0)
848da2e3ebdSchin fsm[i + NMAC][c] = n;
849da2e3ebdSchin }
850da2e3ebdSchin else
851da2e3ebdSchin {
852da2e3ebdSchin if (n < HITN) n++;
853da2e3ebdSchin if (!*s) break;
854da2e3ebdSchin if (fsm[i][c] < HIT0)
855da2e3ebdSchin {
856da2e3ebdSchin n -= NMAC;
857da2e3ebdSchin fsm[i][c] = n;
858da2e3ebdSchin }
859da2e3ebdSchin }
860da2e3ebdSchin c = *s++;
861da2e3ebdSchin }
862da2e3ebdSchin if (x >= 0)
863da2e3ebdSchin {
864da2e3ebdSchin *s = x;
865da2e3ebdSchin for (n = CHAR_MIN; n <= CHAR_MAX; n++)
866da2e3ebdSchin if (ppisidig(n))
867da2e3ebdSchin fsm[HITN][n] = HITN;
868da2e3ebdSchin n = HITN;
869da2e3ebdSchin }
870da2e3ebdSchin if (fsm[i][c] < n)
871da2e3ebdSchin fsm[i][c] = n;
872da2e3ebdSchin if (i < HIT0 && fsm[i + NMAC][c] < n)
873da2e3ebdSchin fsm[i + NMAC][c] = n;
874da2e3ebdSchin }
875da2e3ebdSchin break;
876da2e3ebdSchin
877da2e3ebdSchin #endif
878da2e3ebdSchin
879da2e3ebdSchin }
880da2e3ebdSchin }
881da2e3ebdSchin
882da2e3ebdSchin #if !PROTOMAIN
883da2e3ebdSchin
884da2e3ebdSchin /*
885da2e3ebdSchin * file buffer refill
886da2e3ebdSchin * c is current input char
887da2e3ebdSchin */
888da2e3ebdSchin
889da2e3ebdSchin void
refill(register int c)890da2e3ebdSchin refill(register int c)
891da2e3ebdSchin {
892da2e3ebdSchin if (pp.in->flags & IN_eof)
893da2e3ebdSchin {
894da2e3ebdSchin pp.in->nextchr--;
895da2e3ebdSchin c = 0;
896da2e3ebdSchin }
897da2e3ebdSchin else
898da2e3ebdSchin {
899da2e3ebdSchin *((pp.in->nextchr = pp.in->buffer + PPBAKSIZ) - 1) = c;
900da2e3ebdSchin c =
901da2e3ebdSchin #if PROTOTYPE
902da2e3ebdSchin (pp.in->flags & IN_prototype) ? pppread(pp.in->nextchr) :
903da2e3ebdSchin #endif
904da2e3ebdSchin read(pp.in->fd, pp.in->nextchr, PPBUFSIZ);
905da2e3ebdSchin }
906da2e3ebdSchin if (c > 0)
907da2e3ebdSchin {
908da2e3ebdSchin if (pp.in->nextchr[c - 1] == '\n') pp.in->flags |= IN_newline;
909da2e3ebdSchin else pp.in->flags &= ~IN_newline;
910da2e3ebdSchin #if PROTOTYPE
911da2e3ebdSchin if (!(pp.in->flags & IN_prototype))
912da2e3ebdSchin #endif
913da2e3ebdSchin if (c < PPBUFSIZ && (pp.in->flags & IN_regular))
914da2e3ebdSchin {
915da2e3ebdSchin pp.in->flags |= IN_eof;
916da2e3ebdSchin close(pp.in->fd);
917da2e3ebdSchin pp.in->fd = -1;
918da2e3ebdSchin }
919da2e3ebdSchin }
920da2e3ebdSchin else
921da2e3ebdSchin {
922da2e3ebdSchin if (c < 0)
923da2e3ebdSchin {
924da2e3ebdSchin error(ERROR_SYSTEM|3, "read error");
925da2e3ebdSchin c = 0;
926da2e3ebdSchin }
927da2e3ebdSchin else if ((pp.in->flags ^ pp.in->prev->flags) & IN_c)
928da2e3ebdSchin {
929da2e3ebdSchin static char ket[] = { 0, '}', '\n', 0 };
930da2e3ebdSchin
931da2e3ebdSchin pp.in->flags ^= IN_c;
932da2e3ebdSchin pp.in->nextchr = ket + 1;
933da2e3ebdSchin c = 2;
934da2e3ebdSchin }
935da2e3ebdSchin pp.in->flags |= IN_eof;
936da2e3ebdSchin }
937da2e3ebdSchin #if CHECKPOINT
938da2e3ebdSchin pp.in->buflen = c;
939da2e3ebdSchin #endif
940da2e3ebdSchin pp.in->nextchr[c] = 0;
941da2e3ebdSchin debug((-7, "refill(\"%s\") = %d = \"%-.*s%s\"", error_info.file, c, (c > 32 ? 32 : c), pp.in->nextchr, c > 32 ? "..." : ""));
942da2e3ebdSchin if (pp.test & 0x0080)
943da2e3ebdSchin sfprintf(sfstderr, "===== refill(\"%s\") = %d =====\n%s\n===== eob(\"%s\") =====\n", error_info.file, c, pp.in->nextchr, error_info.file);
944da2e3ebdSchin }
945da2e3ebdSchin
946da2e3ebdSchin #endif
947