db_lex.c revision 116176
18876Srgrimes/*
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 116176 2003-06-10 22:09:23Z obrien $");
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