Annotation of src/usr.bin/bc/scan.l, Revision 1.15
1.1 otto 1: %{
1.15 ! otto 2: /* $OpenBSD: scan.l,v 1.14 2003/12/02 09:00:07 otto Exp $ */
1.1 otto 3:
4: /*
5: * Copyright (c) 2003, Otto Moerbeek <otto@drijf.net>
6: *
7: * Permission to use, copy, modify, and distribute this software for any
8: * purpose with or without fee is hereby granted, provided that the above
9: * copyright notice and this permission notice appear in all copies.
10: *
11: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18: */
19:
20: #ifndef lint
1.15 ! otto 21: static const char rcsid[] = "$OpenBSD: scan.l,v 1.14 2003/12/02 09:00:07 otto Exp $";
1.1 otto 22: #endif /* not lint */
23:
24: #include <err.h>
25: #include <stdbool.h>
26: #include <string.h>
27:
28: #include "extern.h"
1.15 ! otto 29: #include "pathnames.h"
1.1 otto 30: #include "y.tab.h"
31:
32: int lineno;
33:
1.2 deraadt 34: static char *strbuf = NULL;
1.1 otto 35: static size_t strbuf_sz = 1;
36: static bool dot_seen;
37:
38: static void init_strbuf(void);
39: static void add_str(const char *);
40:
41: %}
42:
43: DIGIT [0-9A-F]
1.14 otto 44: ALPHA [a-z_]
45: ALPHANUM [a-z_0-9]
46:
1.1 otto 47: %x comment string number
48:
49: %%
50:
51: "/*" BEGIN(comment);
52: <comment>{
53: "*/" BEGIN(INITIAL);
54: \n lineno++;
55: \* ;
56: [^*\n]+ ;
1.5 otto 57: <<EOF>> fatal("end of file in comment");
1.1 otto 58: }
59:
60: \" BEGIN(string); init_strbuf();
61: <string>{
1.7 otto 62: [^"\n\\\[\]]+ add_str(yytext);
63: \[ add_str("\\[");
64: \] add_str("\\]");
65: \\ add_str("\\\\");
1.1 otto 66: \n add_str("\n"); lineno++;
67: \" BEGIN(INITIAL); yylval.str = strbuf; return STRING;
1.5 otto 68: <<EOF>> fatal("end of file in string");
1.1 otto 69: }
70:
71: {DIGIT}+ {
72: BEGIN(number);
73: dot_seen = false;
74: init_strbuf();
75: add_str(yytext);
76: }
77: \. {
78: BEGIN(number);
79: dot_seen = true;
80: init_strbuf();
81: add_str(".");
82: }
83: <number>{
84: {DIGIT}+ add_str(yytext);
85: \. {
86: if (dot_seen) {
87: BEGIN(INITIAL);
88: yylval.str = strbuf;
89: unput('.');
90: return NUMBER;
91: } else {
92: dot_seen = true;
93: add_str(".");
94: }
95: }
96: \\\n[ \t]* lineno++;
97: [^0-9A-F\.] {
1.6 otto 98: BEGIN(INITIAL);
99: unput(yytext[0]);
100: if (strcmp(strbuf, ".") == 0)
101: return DOT;
1.1 otto 102: else {
103: yylval.str = strbuf;
104: return NUMBER;
105: }
106: }
107: }
108:
109: "auto" return AUTO;
1.2 deraadt 110: "break" return BREAK;
1.8 otto 111: "continue" return CONTINUE;
1.1 otto 112: "define" return DEFINE;
1.8 otto 113: "else" return ELSE;
1.1 otto 114: "ibase" return IBASE;
115: "if" return IF;
1.10 otto 116: "last" return DOT;
1.1 otto 117: "for" return FOR;
118: "length" return LENGTH;
119: "obase" return OBASE;
1.11 otto 120: "print" return PRINT;
1.1 otto 121: "quit" return QUIT;
122: "return" return RETURN;
123: "scale" return SCALE;
124: "sqrt" return SQRT;
125: "while" return WHILE;
126:
127: "^" return EXPONENT;
128: "*" return MULTIPLY;
129: "/" return DIVIDE;
130: "%" return REMAINDER;
1.13 otto 131:
132: "!" return BOOL_NOT;
133: "&&" return BOOL_AND;
134: "||" return BOOL_OR;
1.1 otto 135:
136: "+" return PLUS;
137: "-" return MINUS;
138:
139: "++" return INCR;
140: "--" return DECR;
141:
1.4 deraadt 142: "=" yylval.str = ""; return ASSIGN_OP;
1.1 otto 143: "+=" yylval.str = "+"; return ASSIGN_OP;
144: "-=" yylval.str = "-"; return ASSIGN_OP;
145: "*=" yylval.str = "*"; return ASSIGN_OP;
146: "/=" yylval.str = "/"; return ASSIGN_OP;
147: "%=" yylval.str = "%"; return ASSIGN_OP;
148: "^=" yylval.str = "^"; return ASSIGN_OP;
149:
150: "==" return EQUALS;
151: "<=" return LESS_EQ;
152: ">=" return GREATER_EQ;
153: "!=" return UNEQUALS;
154: "<" return LESS;
155: ">" return GREATER;
156:
157: "," return COMMA;
158: ";" return SEMICOLON;
159:
160: "(" return LPAR;
161: ")" return RPAR;
162:
163: "[" return LBRACKET;
164: "]" return RBRACKET;
165:
166: "{" return LBRACE;
167: "}" return RBRACE;
168:
1.14 otto 169: {ALPHA}{ALPHANUM}* {
170: /* alloc an extra byte for the type marker */
171: char *p = malloc(yyleng + 2);
172: if (p == NULL)
173: err(1, NULL);
174: strlcpy(p, yytext, yyleng + 1);
175: yylval.astr = p;
176: return LETTER;
177: }
1.1 otto 178:
179: \\\n lineno++;
180: \n lineno++; return NEWLINE;
181:
1.12 otto 182: #[^\n]* ;
1.1 otto 183: [ \t] ;
1.14 otto 184: <<EOF>> return QUIT;
1.5 otto 185: . yyerror("illegal character");
1.1 otto 186:
187: %%
188:
189: static void
190: init_strbuf(void)
191: {
192: if (strbuf == NULL) {
193: strbuf = malloc(strbuf_sz);
194: if (strbuf == NULL)
1.9 otto 195: err(1, NULL);
1.1 otto 196: }
197: strbuf[0] = '\0';
198: }
199:
200: static void
201: add_str(const char *str)
202: {
203: size_t arglen;
204:
205: arglen = strlen(str);
206:
1.14 otto 207: if (strlen(strbuf) + arglen + 1 > strbuf_sz) {
1.1 otto 208: size_t newsize;
1.3 deraadt 209: char *p;
1.1 otto 210:
211: newsize = strbuf_sz + arglen + 1;
212: p = realloc(strbuf, newsize);
213: if (p == NULL) {
214: free(strbuf);
1.9 otto 215: err(1, NULL);
1.1 otto 216: }
217: strbuf_sz = newsize;
218: strbuf = p;
219: }
220: strlcat(strbuf, str, strbuf_sz);
221: }
222:
223: void
224: abort_line(int sig)
225: {
226: if (isatty(fileno(yyin))) {
227: YY_FLUSH_BUFFER;
228: printf("[\n]P\n");
229: }
230: }
1.15 ! otto 231:
! 232: int
! 233: yywrap(void)
! 234: {
! 235: static int state;
! 236: static YY_BUFFER_STATE buf;
! 237:
! 238: if (fileindex == 0 && sargc > 0 && strcmp(sargv[0], _PATH_LIBB) == 0) {
! 239: filename = sargv[fileindex++];
! 240: yyin = fopen(filename, "r");
! 241: lineno = 1;
! 242: if (yyin == NULL)
! 243: err(1, "cannot open %s", filename);
! 244: return (0);
! 245: }
! 246: if (state == 0 && cmdexpr[0] != '\0') {
! 247: buf = yy_scan_string(cmdexpr);
! 248: state++;
! 249: lineno = 1;
! 250: filename = "command line";
! 251: return (0);
! 252: } else if (state == 1) {
! 253: yy_delete_buffer(buf);
! 254: free(cmdexpr);
! 255: state++;
! 256: }
! 257: if (fileindex < sargc) {
! 258: filename = sargv[fileindex++];
! 259: yyin = fopen(filename, "r");
! 260: lineno = 1;
! 261: if (yyin == NULL)
! 262: err(1, "cannot open %s", filename);
! 263: return (0);
! 264: } else if (fileindex == sargc) {
! 265: fileindex++;
! 266: yyin = stdin;
! 267: lineno = 1;
! 268: filename = "stdin";
! 269: return (0);
! 270: }
! 271: return (1);
! 272: }
! 273: