1/***********************************************************************
2*                                                                      *
3*               This software is part of the ast package               *
4*          Copyright (c) 1986-2009 AT&T Intellectual Property          *
5*                      and is licensed under the                       *
6*                  Common Public License, Version 1.0                  *
7*                    by AT&T Intellectual Property                     *
8*                                                                      *
9*                A copy of the License is available at                 *
10*            http://www.opensource.org/licenses/cpl1.0.txt             *
11*         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
12*                                                                      *
13*              Information and Software Systems Research               *
14*                            AT&T Research                             *
15*                           Florham Park NJ                            *
16*                                                                      *
17*                 Glenn Fowler <gsf@research.att.com>                  *
18*                                                                      *
19***********************************************************************/
20#pragma prototyped
21/*
22 * Glenn Fowler
23 * AT&T Research
24 *
25 * preprocessor lexical analyzer definitions
26 */
27
28#ifndef _PPFSM_H
29#define _PPFSM_H
30
31#define BITSTATE	16		/* bitsof(state)		*/
32#define BITNONTERM	7		/* bitsof(non-terminal-state)	*/
33#define BITTERM		7		/* bitsof(terminal-state)	*/
34#define NMAC		19		/* number of MAC states		*/
35
36#define SPLICE		(1<<BITTERM)
37
38#define	CODE(tok,act)	((((tok)-N_PP)<<(BITTERM+1))|(act))
39#define TERM(st)	((st)&((1<<(BITTERM+1))-1))
40#define NEXT(st)	(((st)>>(BITTERM+1))&((1<<BITNONTERM)-1))
41#define QUAL(st)	(((st)<<(BITTERM+1))|(S_QUAL))
42#define	TYPE(st)	(NEXT(st)+N_PP)
43
44#define BACK(tok)	CODE(tok,S_TOKB)
45#define KEEP(tok)	CODE(tok,S_TOK)
46
47#undef	MAX
48#define MAX		255
49
50#undef	EOB
51#define EOB		0
52#undef	EOF
53#define EOF		(MAX+1)
54
55/*
56 * FSM states
57 *
58 * NOTE: preserve the ranges
59 */
60
61#define INDEX(p)	(((p)-fsm[0])/(MAX+1))
62
63#define IDSTATE(x)	(((x)>=0&&INQMACRO(fsm[x]))?QID:(x))
64
65#define INCOMMENT(p)	((p)>=fsm[COM2]&&(p)<=fsm[COM7])
66#define INCOMMENTXX(p)	((p)>=fsm[COM5]&&(p)<=fsm[COM7])
67#define INQMACRO(p)	((p)>=fsm[MAC0]&&(p)<=fsm[LIT0])
68#define INTMACRO(p)	((p)>=fsm[NID]&&(p)<=fsm[LIT])
69#define INQUOTE(p)	((p)>=fsm[LIT1]&&(p)<=fsm[LIT2])
70#define INOPSPACE(p)	((p)==fsm[BIN1])
71#define INSPACE(p)	((p)==fsm[WS1])
72
73/*
74 * proto non-terminal states
75 */
76
77#define PROTO		0
78#define RES1		(PROTO+1)
79#define RES1a		(PROTO+2)
80#define RES1e		(PROTO+3)
81#define RES1f		(PROTO+4)
82#define RES1h		(PROTO+5)
83#define RES1l		(PROTO+6)
84#define RES1n		(PROTO+7)
85#define RES1o		(PROTO+8)
86#define RES1t		(PROTO+9)
87#define RES1x		(PROTO+10)
88#define RES1y		(PROTO+11)
89#define COM1		(PROTO+12)
90#define COM2		(PROTO+13)
91#define COM3		(PROTO+14)
92#define COM4		(PROTO+15)
93#define COM5		(PROTO+16)
94#define COM6		(PROTO+17)
95#define COM7		(PROTO+18)
96#define NID		(PROTO+19)
97#define LIT		(PROTO+20)
98#define LIT1		(PROTO+21)
99#define LIT2		(PROTO+22)
100#define BAD1		(PROTO+23)
101#define BAD2		(PROTO+24)
102#define DOT		(PROTO+25)
103#define DOT2		(PROTO+26)
104#define WS1		(PROTO+27)
105
106#if PROTOMAIN
107
108#define TERMINAL	(PROTO+28)	/* PROTOMAIN */
109
110#else
111
112/*
113 * quick non-terminal states
114 */
115
116#define QUICK		(PROTO+28)
117#define QTOK		(QUICK+1)
118#define QNUM		(QUICK+2)
119#define QEXP		(QUICK+3)
120#define QCOM		(QUICK+4)
121#define QID		(QUICK+5)
122#define MAC0		(QUICK+6)
123#define MACN		(MAC0+NMAC-1)
124#define HIT0		(MACN+1)
125#define HITN		(HIT0+NMAC-1)
126#define LIT0		(HITN+1)
127#define SHARP1		(HITN+2)
128
129/*
130 * tokenize non-terminal states
131 */
132
133#define TOKEN		(HITN+3)
134#define OCT1		(TOKEN+1)
135#define OCT2		(TOKEN+2)
136#define OCT3		(TOKEN+3)
137#define NOT1		(TOKEN+4)
138#define PCT1		(TOKEN+5)
139#define AND1		(TOKEN+6)
140#define STAR1		(TOKEN+7)
141#define PLUS1		(TOKEN+8)
142#define MINUS1		(TOKEN+9)
143#define ARROW1		(TOKEN+10)
144#define COLON1		(TOKEN+11)
145#define LT1		(TOKEN+12)
146#define LSH1		(TOKEN+13)
147#define EQ1		(TOKEN+14)
148#define RSH1		(TOKEN+15)
149#define GT1		(TOKEN+16)
150#define CIRC1		(TOKEN+17)
151#define OR1		(TOKEN+18)
152#define DEC1		(TOKEN+19)
153#define DEC2		(TOKEN+20)
154#define HEX1		(TOKEN+21)
155#define HEX2		(TOKEN+22)
156#define HEX3		(TOKEN+23)
157#define HEX4		(TOKEN+24)
158#define HEX5		(TOKEN+25)
159#define HEX6		(TOKEN+26)
160#define HEX7		(TOKEN+27)
161#define HEX8		(TOKEN+28)
162#define DBL1		(TOKEN+29)
163#define DBL2		(TOKEN+30)
164#define DBL3		(TOKEN+31)
165#define DBL4		(TOKEN+32)
166#define DBL5		(TOKEN+33)
167#define DOT1		(TOKEN+34)
168#define HDR1		(TOKEN+35)
169#define BIN1		(TOKEN+36)
170
171#define TERMINAL	(TOKEN+37)
172
173#endif
174
175/*
176 * quick terminal states grouped together
177 */
178
179#define S_CHRB		(TERMINAL+0)
180#define S_COMMENT	(TERMINAL+1)
181#define S_EOB		(TERMINAL+2)
182#define S_LITBEG	(TERMINAL+3)
183#define S_LITEND	(TERMINAL+4)
184#define S_LITESC	(TERMINAL+5)
185#define S_MACRO		(TERMINAL+6)
186#define S_NL		(TERMINAL+7)
187#define S_QUAL		(TERMINAL+8)
188#define S_SHARP		(TERMINAL+9)
189#define S_VS		(TERMINAL+10)
190
191/*
192 * and the remaining terminal states
193 */
194
195#define S_CHR		(TERMINAL+11)
196#define S_HUH		(TERMINAL+12)
197#define S_TOK		(TERMINAL+13)
198#define S_TOKB		(TERMINAL+14)
199#define S_WS		(TERMINAL+15)
200
201#define S_RESERVED	(S_HUH)
202
203/*
204 * the last terminal state (for tracing)
205 */
206
207#define LAST		(S_WS)
208
209/*
210 * pseudo terminal states
211 */
212
213#define S_EOF		(0)
214
215/*
216 * common lex macros
217 *
218 * NOTE: common local variable names assumed
219 */
220
221#define GET(p,c,tp,xp)	\
222	do \
223	{ \
224		if ((c = GETCHR()) == EOB && pp.in->type == IN_FILE) \
225			FGET(p, c, tp, xp); \
226	} while (0)
227
228#define FGET(p,c,tp,xp)	\
229	do \
230	{ \
231		if (op > xp + PPTOKSIZ) \
232		{ \
233			if (!INCOMMENT(rp) && !(pp.state & (NOTEXT|SKIPCONTROL))) \
234				error(2, "long token truncated"); \
235			op = xp + PPTOKSIZ; \
236		} \
237		if ((pp.in->flags & IN_flush) && pp.level == 1 && !INMACRO(rp) && (!pp.comment || !INCOMMENT(rp)) && (c = op - pp.outbuf) > 0 && *(op - 1) == '\n') \
238		{ \
239			PPWRITE(c); \
240			op = tp = pp.outp = pp.outbuf; \
241		} \
242		SYNCIN(); \
243		refill(p); \
244		CACHEIN(); \
245		if ((c = GETCHR()) == EOB) BACKIN(); \
246	} while (0)
247
248#define POP()		\
249	do \
250	{ \
251		debug((-7, "POP  in=%s next=%s state=%s", ppinstr(cur), pptokchr(*prv->nextchr), pplexstr(INDEX(rp)))); \
252		ip = (pp.in = prv)->nextchr; \
253	} while (0)
254
255/*
256 * fsm implementaion globals
257 */
258
259#define fsm		_pp_fsmtab
260#define refill		_pp_refill
261#define trigraph	_pp_trigraph
262
263/*
264 * first index is state, second is char, value is next state
265 * except for fsm[TERMINAL] where second is state+1 for EOF transition
266 */
267
268extern short		fsm[TERMINAL+1][MAX+1];
269
270/*
271 * the index is char, value is trigraph value for <?><?><char>, 0 if invalid
272 */
273
274extern char		trigraph[MAX+1];
275
276extern void		refill(int);
277
278#endif
279