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