db_lex.c revision 139747
1139747Simp/*- 24Srgrimes * Mach Operating System 34Srgrimes * Copyright (c) 1991,1990 Carnegie Mellon University 44Srgrimes * All Rights Reserved. 58876Srgrimes * 64Srgrimes * Permission to use, copy, modify and distribute this software and its 74Srgrimes * documentation is hereby granted, provided that both the copyright 84Srgrimes * notice and this permission notice appear in all copies of the 94Srgrimes * software, derivative works or modified versions, and any portions 104Srgrimes * thereof, and that both notices appear in supporting documentation. 118876Srgrimes * 128876Srgrimes * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS 134Srgrimes * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 144Srgrimes * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 158876Srgrimes * 164Srgrimes * Carnegie Mellon requests users of this software to return to 178876Srgrimes * 184Srgrimes * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 194Srgrimes * School of Computer Science 204Srgrimes * Carnegie Mellon University 214Srgrimes * Pittsburgh PA 15213-3890 228876Srgrimes * 234Srgrimes * any improvements or extensions that they make and grant Carnegie the 244Srgrimes * rights to redistribute these changes. 254Srgrimes */ 264Srgrimes/* 274Srgrimes * Author: David B. Golub, Carnegie Mellon University 284Srgrimes * Date: 7/90 294Srgrimes */ 304Srgrimes/* 314Srgrimes * Lexical analyzer. 324Srgrimes */ 33116176Sobrien 34116176Sobrien#include <sys/cdefs.h> 35116176Sobrien__FBSDID("$FreeBSD: head/sys/ddb/db_lex.c 139747 2005-01-06 01:34:41Z imp $"); 36116176Sobrien 372056Swollman#include <sys/param.h> 3812734Sbde 392056Swollman#include <ddb/ddb.h> 404Srgrimes#include <ddb/db_lex.h> 414Srgrimes 4212720Sphkstatic char db_line[120]; 4312720Sphkstatic char * db_lp, *db_endlp; 444Srgrimes 4592756Salfredstatic int db_lex(void); 4692756Salfredstatic void db_flush_line(void); 4792756Salfredstatic int db_read_char(void); 4892756Salfredstatic void db_unread_char(int); 492112Swollman 504Srgrimesint 514Srgrimesdb_read_line() 524Srgrimes{ 534Srgrimes int i; 544Srgrimes 554Srgrimes i = db_readline(db_line, sizeof(db_line)); 564Srgrimes if (i == 0) 574Srgrimes return (0); /* EOI */ 584Srgrimes db_lp = db_line; 594Srgrimes db_endlp = db_lp + i; 604Srgrimes return (i); 614Srgrimes} 624Srgrimes 6312515Sphkstatic void 644Srgrimesdb_flush_line() 654Srgrimes{ 664Srgrimes db_lp = db_line; 674Srgrimes db_endlp = db_line; 684Srgrimes} 694Srgrimes 7012515Sphkstatic int db_look_char = 0; 714Srgrimes 7212515Sphkstatic int 734Srgrimesdb_read_char() 744Srgrimes{ 754Srgrimes int c; 764Srgrimes 774Srgrimes if (db_look_char != 0) { 784Srgrimes c = db_look_char; 794Srgrimes db_look_char = 0; 804Srgrimes } 814Srgrimes else if (db_lp >= db_endlp) 824Srgrimes c = -1; 838876Srgrimes else 844Srgrimes c = *db_lp++; 854Srgrimes return (c); 864Srgrimes} 874Srgrimes 8812515Sphkstatic void 894Srgrimesdb_unread_char(c) 90798Swollman int c; 914Srgrimes{ 924Srgrimes db_look_char = c; 934Srgrimes} 944Srgrimes 9512515Sphkstatic int db_look_token = 0; 964Srgrimes 974Srgrimesvoid 984Srgrimesdb_unread_token(t) 994Srgrimes int t; 1004Srgrimes{ 1014Srgrimes db_look_token = t; 1024Srgrimes} 1034Srgrimes 1044Srgrimesint 1054Srgrimesdb_read_token() 1064Srgrimes{ 1074Srgrimes int t; 1084Srgrimes 1094Srgrimes if (db_look_token) { 1104Srgrimes t = db_look_token; 1114Srgrimes db_look_token = 0; 1124Srgrimes } 1134Srgrimes else 1144Srgrimes t = db_lex(); 1154Srgrimes return (t); 1164Srgrimes} 1174Srgrimes 11837504Sbdedb_expr_t db_tok_number; 1194Srgrimeschar db_tok_string[TOK_STRING_SIZE]; 1204Srgrimes 12137504Sbdedb_expr_t db_radix = 16; 1224Srgrimes 1234Srgrimesvoid 1244Srgrimesdb_flush_lex() 1254Srgrimes{ 1264Srgrimes db_flush_line(); 1274Srgrimes db_look_char = 0; 1284Srgrimes db_look_token = 0; 1294Srgrimes} 1304Srgrimes 1312112Swollmanstatic int 1324Srgrimesdb_lex() 1334Srgrimes{ 1344Srgrimes int c; 1354Srgrimes 1364Srgrimes c = db_read_char(); 1374Srgrimes while (c <= ' ' || c > '~') { 1384Srgrimes if (c == '\n' || c == -1) 1394Srgrimes return (tEOL); 1404Srgrimes c = db_read_char(); 1414Srgrimes } 1424Srgrimes 1434Srgrimes if (c >= '0' && c <= '9') { 1444Srgrimes /* number */ 145798Swollman int r, digit = 0; 1464Srgrimes 1474Srgrimes if (c > '0') 1484Srgrimes r = db_radix; 1494Srgrimes else { 1504Srgrimes c = db_read_char(); 1514Srgrimes if (c == 'O' || c == 'o') 1524Srgrimes r = 8; 1534Srgrimes else if (c == 'T' || c == 't') 1544Srgrimes r = 10; 1554Srgrimes else if (c == 'X' || c == 'x') 1564Srgrimes r = 16; 1574Srgrimes else { 1584Srgrimes r = db_radix; 1594Srgrimes db_unread_char(c); 1604Srgrimes } 1614Srgrimes c = db_read_char(); 1624Srgrimes } 1634Srgrimes db_tok_number = 0; 1644Srgrimes for (;;) { 1654Srgrimes if (c >= '0' && c <= ((r == 8) ? '7' : '9')) 1664Srgrimes digit = c - '0'; 1674Srgrimes else if (r == 16 && ((c >= 'A' && c <= 'F') || 1684Srgrimes (c >= 'a' && c <= 'f'))) { 1694Srgrimes if (c >= 'a') 1704Srgrimes digit = c - 'a' + 10; 1714Srgrimes else if (c >= 'A') 1724Srgrimes digit = c - 'A' + 10; 1734Srgrimes } 1744Srgrimes else 1754Srgrimes break; 1764Srgrimes db_tok_number = db_tok_number * r + digit; 1774Srgrimes c = db_read_char(); 1784Srgrimes } 1794Srgrimes if ((c >= '0' && c <= '9') || 1804Srgrimes (c >= 'A' && c <= 'Z') || 1814Srgrimes (c >= 'a' && c <= 'z') || 1824Srgrimes (c == '_')) 1834Srgrimes { 1844Srgrimes db_error("Bad character in number\n"); 1854Srgrimes db_flush_lex(); 1864Srgrimes return (tEOF); 1874Srgrimes } 1884Srgrimes db_unread_char(c); 1894Srgrimes return (tNUMBER); 1904Srgrimes } 1914Srgrimes if ((c >= 'A' && c <= 'Z') || 1924Srgrimes (c >= 'a' && c <= 'z') || 1934Srgrimes c == '_' || c == '\\') 1944Srgrimes { 1954Srgrimes /* string */ 1964Srgrimes char *cp; 1974Srgrimes 1984Srgrimes cp = db_tok_string; 1994Srgrimes if (c == '\\') { 2004Srgrimes c = db_read_char(); 2014Srgrimes if (c == '\n' || c == -1) 2024Srgrimes db_error("Bad escape\n"); 2034Srgrimes } 2044Srgrimes *cp++ = c; 2054Srgrimes while (1) { 2064Srgrimes c = db_read_char(); 2074Srgrimes if ((c >= 'A' && c <= 'Z') || 2084Srgrimes (c >= 'a' && c <= 'z') || 2094Srgrimes (c >= '0' && c <= '9') || 21092011Sdfr c == '_' || c == '\\' || c == ':' || c == '.') 2114Srgrimes { 2124Srgrimes if (c == '\\') { 2134Srgrimes c = db_read_char(); 2144Srgrimes if (c == '\n' || c == -1) 2154Srgrimes db_error("Bad escape\n"); 2164Srgrimes } 2174Srgrimes *cp++ = c; 2184Srgrimes if (cp == db_tok_string+sizeof(db_tok_string)) { 2194Srgrimes db_error("String too long\n"); 2204Srgrimes db_flush_lex(); 2214Srgrimes return (tEOF); 2224Srgrimes } 2234Srgrimes continue; 2244Srgrimes } 2254Srgrimes else { 2264Srgrimes *cp = '\0'; 2274Srgrimes break; 2284Srgrimes } 2294Srgrimes } 2304Srgrimes db_unread_char(c); 2314Srgrimes return (tIDENT); 2324Srgrimes } 2334Srgrimes 2344Srgrimes switch (c) { 2354Srgrimes case '+': 2364Srgrimes return (tPLUS); 2374Srgrimes case '-': 2384Srgrimes return (tMINUS); 2394Srgrimes case '.': 2404Srgrimes c = db_read_char(); 2414Srgrimes if (c == '.') 2424Srgrimes return (tDOTDOT); 2434Srgrimes db_unread_char(c); 2444Srgrimes return (tDOT); 2454Srgrimes case '*': 2464Srgrimes return (tSTAR); 2474Srgrimes case '/': 2484Srgrimes return (tSLASH); 2494Srgrimes case '=': 2504Srgrimes return (tEQ); 2514Srgrimes case '%': 2524Srgrimes return (tPCT); 2534Srgrimes case '#': 2544Srgrimes return (tHASH); 2554Srgrimes case '(': 2564Srgrimes return (tLPAREN); 2574Srgrimes case ')': 2584Srgrimes return (tRPAREN); 2594Srgrimes case ',': 2604Srgrimes return (tCOMMA); 2614Srgrimes case '"': 2624Srgrimes return (tDITTO); 2634Srgrimes case '$': 2644Srgrimes return (tDOLLAR); 2654Srgrimes case '!': 2664Srgrimes return (tEXCL); 2674Srgrimes case '<': 2684Srgrimes c = db_read_char(); 2694Srgrimes if (c == '<') 2704Srgrimes return (tSHIFT_L); 2714Srgrimes db_unread_char(c); 2724Srgrimes break; 2734Srgrimes case '>': 2744Srgrimes c = db_read_char(); 2754Srgrimes if (c == '>') 2764Srgrimes return (tSHIFT_R); 2774Srgrimes db_unread_char(c); 2784Srgrimes break; 2794Srgrimes case -1: 2804Srgrimes return (tEOF); 2814Srgrimes } 2824Srgrimes db_printf("Bad character\n"); 2834Srgrimes db_flush_lex(); 2844Srgrimes return (tEOF); 2854Srgrimes} 286