xref: /original-bsd/old/awk/awk.lx.l (revision e0c0d005)
1 /*	awk.lx.l	4.4	90/06/25	*/
2 
3 %X str chc reg comment
4 
5 %{
6 #include	<string.h>
7 #include	"awk.h"
8 #include	"awk.def"
9 extern int	yylval;
10 extern int	mustfld;
11 extern int	ldbg;
12 extern char	*lexprog;
13 
14 #undef YY_INPUT
15 #define YY_INPUT(buf,result,max_size)				\
16 {								\
17 	if ( lexprog )						\
18 		{						\
19 		result = strlen( lexprog );			\
20 		if ( result > max_size )			\
21 			{					\
22 			result = max_size;			\
23 			strncpy( buf, lexprog, result );	\
24 			}					\
25 		else						\
26 			strcpy( buf, lexprog );			\
27 		lexprog += result;				\
28 		}						\
29 	else							\
30 		result = read( fileno(yyin), buf, max_size );	\
31 }
32 
33 int	lineno	= 1;
34 #define	RETURN(x)	{if (ldbg) ptoken(x); return(x); }
35 #define	CADD	cbuf[clen++]=yytext[0]; if(clen>=CBUFLEN-1) {yyerror("string too long", cbuf); BEGIN INITIAL;}
36 #define	CBUFLEN	150
37 char	cbuf[CBUFLEN];
38 int	clen, cflag;
39 %}
40 
41 A	[a-zA-Z_]
42 B	[a-zA-Z0-9_]
43 D	[0-9]
44 WS	[ \t]
45 
46 %%
47 	static int sc_flag = 0;
48 
49 	if ( sc_flag ) {
50 		BEGIN INITIAL;
51 		sc_flag = 0;
52 		RETURN('}');
53 	}
54 
55 ^\n		lineno++;
56 ^{WS}*#.*\n	lineno++;	/* strip comment lines */
57 {WS}		;
58 <INITIAL,reg>"\\"\n	lineno++;
59 "||"		RETURN(BOR);
60 BEGIN	RETURN(XBEGIN);
61 END		RETURN(XEND);
62 PROGEND	RETURN(EOF);
63 "&&"		RETURN(AND);
64 "!"		RETURN(NOT);
65 "!="		{ yylval = NE; RETURN(RELOP); }
66 "~"		{ yylval = MATCH; RETURN(MATCHOP); }
67 "!~"		{ yylval = NOTMATCH; RETURN(MATCHOP); }
68 "<"		{ yylval = LT; RETURN(RELOP); }
69 "<="		{ yylval = LE; RETURN(RELOP); }
70 "=="		{ yylval = EQ; RETURN(RELOP); }
71 ">="		{ yylval = GE; RETURN(RELOP); }
72 ">"		{ yylval = GT; RETURN(RELOP); }
73 ">>"		{ yylval = APPEND; RETURN(RELOP); }
74 "++"		{ yylval = INCR; RETURN(INCR); }
75 "--"		{ yylval = DECR; RETURN(DECR); }
76 "+="		{ yylval = ADDEQ; RETURN(ASGNOP); }
77 "-="		{ yylval = SUBEQ; RETURN(ASGNOP); }
78 "*="		{ yylval = MULTEQ; RETURN(ASGNOP); }
79 "/="		{ yylval = DIVEQ; RETURN(ASGNOP); }
80 "%="		{ yylval = MODEQ; RETURN(ASGNOP); }
81 "="		{ yylval = ASSIGN; RETURN(ASGNOP); }
82 
83 "$"{D}+	{	if (atoi(yytext+1)==0) {
84 				yylval = (hack)lookup("$record", symtab, 0);
85 				RETURN(STRING);
86 			} else {
87 				yylval = fieldadr(atoi(yytext+1));
88 				RETURN(FIELD);
89 			}
90 		}
91 "$"{WS}*	{ RETURN(INDIRECT); }
92 NF		{ mustfld=1; yylval = (hack)setsymtab(yytext, EMPTY, 0.0, NUM, symtab); RETURN(VAR); }
93 ({D}+("."?){D}*|"."{D}+)((e|E)("+"|-)?{D}+)?	{
94 		yylval = (hack)setsymtab(yytext, EMPTY, atof(yytext), CON|NUM, symtab); RETURN(NUMBER); }
95 "}"{WS}*\n	{ sc_flag = 1; lineno++; RETURN(';'); }
96 "}"		{ sc_flag = 1; RETURN(';'); }
97 ;\n		{ lineno++; RETURN(';'); }
98 \n		{ lineno++; RETURN(NL); }
99 while	RETURN(WHILE);
100 for		RETURN(FOR);
101 if		RETURN(IF);
102 else		RETURN(ELSE);
103 next		RETURN(NEXT);
104 exit		RETURN(EXIT);
105 break	RETURN(BREAK);
106 continue	RETURN(CONTINUE);
107 print	{ yylval = PRINT; RETURN(PRINT); }
108 printf	{ yylval = PRINTF; RETURN(PRINTF); }
109 sprintf	{ yylval = SPRINTF; RETURN(SPRINTF); }
110 split	{ yylval = SPLIT; RETURN(SPLIT); }
111 substr	RETURN(SUBSTR);
112 index	RETURN(INDEX);
113 in		RETURN(IN);
114 getline	RETURN(GETLINE);
115 length	{ yylval = FLENGTH; RETURN(FNCN); }
116 log		{ yylval = FLOG; RETURN(FNCN); }
117 int		{ yylval = FINT; RETURN(FNCN); }
118 exp		{ yylval = FEXP; RETURN(FNCN); }
119 sqrt		{ yylval = FSQRT; RETURN(FNCN); }
120 {A}{B}*	{ yylval = (hack)setsymtab(yytext, tostring(""), 0.0, STR|NUM, symtab); RETURN(VAR); }
121 \"		{ BEGIN str; clen=0; }
122 
123 #		{ BEGIN comment; }
124 <comment>\n	{ BEGIN INITIAL; lineno++; RETURN(NL); }
125 <comment>.	;
126 
127 .		{ yylval = yytext[0]; RETURN(yytext[0]); }
128 
129 <reg>"["	{ BEGIN chc; clen=0; cflag=0; }
130 <reg>"[^"	{ BEGIN chc; clen=0; cflag=1; }
131 
132 <reg>"?"	RETURN(QUEST);
133 <reg>"+"	RETURN(PLUS);
134 <reg>"*"	RETURN(STAR);
135 <reg>"|"	RETURN(OR);
136 <reg>"."	RETURN(DOT);
137 <reg>"("	RETURN('(');
138 <reg>")"	RETURN(')');
139 <reg>"^"	RETURN('^');
140 <reg>"$"	RETURN('$');
141 <reg>\\{D}{D}{D}	{ sscanf(yytext+1, "%o", &yylval); RETURN(CHAR); }
142 <reg>\\.	{	if (yytext[1]=='n') yylval = '\n';
143 			else if (yytext[1] == 't') yylval = '\t';
144 			else yylval = yytext[1];
145 			RETURN(CHAR);
146 		}
147 <reg>"/"	{ BEGIN INITIAL; unput('/'); }
148 <reg>\n		{ yyerror("newline in regular expression"); lineno++; BEGIN INITIAL; }
149 <reg>.		{ yylval = yytext[0]; RETURN(CHAR); }
150 
151 <str>\"		{ char *s; BEGIN INITIAL; cbuf[clen]=0; s = tostring(cbuf);
152 		cbuf[clen] = ' '; cbuf[++clen] = 0;
153 		yylval = (hack)setsymtab(cbuf, s, 0.0, CON|STR, symtab); RETURN(STRING); }
154 <str>\n		{ yyerror("newline in string"); lineno++; BEGIN INITIAL; }
155 <str>"\\\""	{ cbuf[clen++]='"'; }
156 <str,chc>"\\"n	{ cbuf[clen++]='\n'; }
157 <str,chc>"\\"t	{ cbuf[clen++]='\t'; }
158 <str,chc>"\\\\"	{ cbuf[clen++]='\\'; }
159 <str>.		{ CADD; }
160 
161 <chc>"\\""]"	{ cbuf[clen++]=']'; }
162 <chc>"]"	{ BEGIN reg; cbuf[clen]=0; yylval = (hack)tostring(cbuf);
163 		if (cflag==0) { RETURN(CCL); }
164 		else { RETURN(NCCL); } }
165 <chc>\n		{ yyerror("newline in character class"); lineno++; BEGIN INITIAL; }
166 <chc>.		{ CADD; }
167 
168 %%
169 
170 startreg()
171 {
172 	BEGIN reg;
173 }
174 
175 ptoken(n)
176 {
177 	extern struct tok {
178 		char *tnm;
179 		int yval;
180 	} tok[];
181 	extern int yylval;
182 
183 	printf("lex:");
184 	if (n < 128) {
185 		printf(" %c\n",n);
186 		return;
187 	}
188 	if (n <= 256 || n >= LASTTOKEN) {
189 		printf("? %o\n",n);
190 		return;
191 	}
192 	printf(" %s",tok[n-257].tnm);
193 	switch (n) {
194 
195 	case RELOP:
196 	case MATCHOP:
197 	case ASGNOP:
198 	case STRING:
199 	case FIELD:
200 	case VAR:
201 	case NUMBER:
202 	case FNCN:
203 		printf(" (%s)", yytext);
204 		break;
205 
206 	case CHAR:
207 		printf(" (%o)", yylval);
208 		break;
209 	}
210 	putchar('\n');
211 }
212