Annotation of src/usr.bin/bc/scan.l, Revision 1.14
1.1 otto 1: %{
1.14 ! otto 2: /* $OpenBSD: scan.l,v 1.13 2003/11/17 11:20:13 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.14 ! otto 21: static const char rcsid[] = "$OpenBSD: scan.l,v 1.13 2003/11/17 11:20:13 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"
29: #include "y.tab.h"
30:
31: int lineno;
32:
1.2 deraadt 33: static char *strbuf = NULL;
1.1 otto 34: static size_t strbuf_sz = 1;
35: static bool dot_seen;
36:
37: static void init_strbuf(void);
38: static void add_str(const char *);
39:
40: %}
41:
42: DIGIT [0-9A-F]
1.14 ! otto 43: ALPHA [a-z_]
! 44: ALPHANUM [a-z_0-9]
! 45:
1.1 otto 46: %x comment string number
47:
48: %%
49:
50: "/*" BEGIN(comment);
51: <comment>{
52: "*/" BEGIN(INITIAL);
53: \n lineno++;
54: \* ;
55: [^*\n]+ ;
1.5 otto 56: <<EOF>> fatal("end of file in comment");
1.1 otto 57: }
58:
59: \" BEGIN(string); init_strbuf();
60: <string>{
1.7 otto 61: [^"\n\\\[\]]+ add_str(yytext);
62: \[ add_str("\\[");
63: \] add_str("\\]");
64: \\ add_str("\\\\");
1.1 otto 65: \n add_str("\n"); lineno++;
66: \" BEGIN(INITIAL); yylval.str = strbuf; return STRING;
1.5 otto 67: <<EOF>> fatal("end of file in string");
1.1 otto 68: }
69:
70: {DIGIT}+ {
71: BEGIN(number);
72: dot_seen = false;
73: init_strbuf();
74: add_str(yytext);
75: }
76: \. {
77: BEGIN(number);
78: dot_seen = true;
79: init_strbuf();
80: add_str(".");
81: }
82: <number>{
83: {DIGIT}+ add_str(yytext);
84: \. {
85: if (dot_seen) {
86: BEGIN(INITIAL);
87: yylval.str = strbuf;
88: unput('.');
89: return NUMBER;
90: } else {
91: dot_seen = true;
92: add_str(".");
93: }
94: }
95: \\\n[ \t]* lineno++;
96: [^0-9A-F\.] {
1.6 otto 97: BEGIN(INITIAL);
98: unput(yytext[0]);
99: if (strcmp(strbuf, ".") == 0)
100: return DOT;
1.1 otto 101: else {
102: yylval.str = strbuf;
103: return NUMBER;
104: }
105: }
106: }
107:
108: "auto" return AUTO;
1.2 deraadt 109: "break" return BREAK;
1.8 otto 110: "continue" return CONTINUE;
1.1 otto 111: "define" return DEFINE;
1.8 otto 112: "else" return ELSE;
1.1 otto 113: "ibase" return IBASE;
114: "if" return IF;
1.10 otto 115: "last" return DOT;
1.1 otto 116: "for" return FOR;
117: "length" return LENGTH;
118: "obase" return OBASE;
1.11 otto 119: "print" return PRINT;
1.1 otto 120: "quit" return QUIT;
121: "return" return RETURN;
122: "scale" return SCALE;
123: "sqrt" return SQRT;
124: "while" return WHILE;
125:
126: "^" return EXPONENT;
127: "*" return MULTIPLY;
128: "/" return DIVIDE;
129: "%" return REMAINDER;
1.13 otto 130:
131: "!" return BOOL_NOT;
132: "&&" return BOOL_AND;
133: "||" return BOOL_OR;
1.1 otto 134:
135: "+" return PLUS;
136: "-" return MINUS;
137:
138: "++" return INCR;
139: "--" return DECR;
140:
1.4 deraadt 141: "=" yylval.str = ""; return ASSIGN_OP;
1.1 otto 142: "+=" yylval.str = "+"; return ASSIGN_OP;
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:
149: "==" return EQUALS;
150: "<=" return LESS_EQ;
151: ">=" return GREATER_EQ;
152: "!=" return UNEQUALS;
153: "<" return LESS;
154: ">" return GREATER;
155:
156: "," return COMMA;
157: ";" return SEMICOLON;
158:
159: "(" return LPAR;
160: ")" return RPAR;
161:
162: "[" return LBRACKET;
163: "]" return RBRACKET;
164:
165: "{" return LBRACE;
166: "}" return RBRACE;
167:
1.14 ! otto 168: {ALPHA}{ALPHANUM}* {
! 169: /* alloc an extra byte for the type marker */
! 170: char *p = malloc(yyleng + 2);
! 171: if (p == NULL)
! 172: err(1, NULL);
! 173: strlcpy(p, yytext, yyleng + 1);
! 174: yylval.astr = p;
! 175: return LETTER;
! 176: }
1.1 otto 177:
178: \\\n lineno++;
179: \n lineno++; return NEWLINE;
180:
1.12 otto 181: #[^\n]* ;
1.1 otto 182: [ \t] ;
1.14 ! otto 183: <<EOF>> return QUIT;
1.5 otto 184: . yyerror("illegal character");
1.1 otto 185:
186: %%
187:
188: static void
189: init_strbuf(void)
190: {
191: if (strbuf == NULL) {
192: strbuf = malloc(strbuf_sz);
193: if (strbuf == NULL)
1.9 otto 194: err(1, NULL);
1.1 otto 195: }
196: strbuf[0] = '\0';
197: }
198:
199: static void
200: add_str(const char *str)
201: {
202: size_t arglen;
203:
204: arglen = strlen(str);
205:
1.14 ! otto 206: if (strlen(strbuf) + arglen + 1 > strbuf_sz) {
1.1 otto 207: size_t newsize;
1.3 deraadt 208: char *p;
1.1 otto 209:
210: newsize = strbuf_sz + arglen + 1;
211: p = realloc(strbuf, newsize);
212: if (p == NULL) {
213: free(strbuf);
1.9 otto 214: err(1, NULL);
1.1 otto 215: }
216: strbuf_sz = newsize;
217: strbuf = p;
218: }
219: strlcat(strbuf, str, strbuf_sz);
220: }
221:
222: void
223: abort_line(int sig)
224: {
225: if (isatty(fileno(yyin))) {
226: YY_FLUSH_BUFFER;
227: printf("[\n]P\n");
228: }
229: }