root/ddb/db_lex.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. db_read_line
  2. db_flush_line
  3. db_read_char
  4. db_unread_char
  5. db_unread_token
  6. db_read_token
  7. db_flush_lex
  8. db_lex

    1 /*      $OpenBSD: db_lex.c,v 1.9 2006/03/13 06:23:20 jsg Exp $  */
    2 /*      $NetBSD: db_lex.c,v 1.8 1996/02/05 01:57:05 christos Exp $      */
    3 
    4 /* 
    5  * Mach Operating System
    6  * Copyright (c) 1993,1992,1991,1990 Carnegie Mellon University
    7  * All Rights Reserved.
    8  * 
    9  * Permission to use, copy, modify and distribute this software and its
   10  * documentation is hereby granted, provided that both the copyright
   11  * notice and this permission notice appear in all copies of the
   12  * software, derivative works or modified versions, and any portions
   13  * thereof, and that both notices appear in supporting documentation.
   14  * 
   15  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
   16  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
   17  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
   18  * 
   19  * Carnegie Mellon requests users of this software to return to
   20  * 
   21  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
   22  *  School of Computer Science
   23  *  Carnegie Mellon University
   24  *  Pittsburgh PA 15213-3890
   25  * 
   26  * any improvements or extensions that they make and grant Carnegie Mellon
   27  * the rights to redistribute these changes.
   28  *
   29  *      Author: David B. Golub, Carnegie Mellon University
   30  *      Date:   7/90
   31  */
   32 
   33 /*
   34  * Lexical analyzer.
   35  */
   36 #include <sys/param.h>
   37 #include <sys/proc.h>
   38 
   39 #include <uvm/uvm_extern.h>
   40 
   41 #include <machine/db_machdep.h>
   42 
   43 #include <ddb/db_lex.h>
   44 #include <ddb/db_output.h>
   45 #include <ddb/db_command.h>
   46 #include <ddb/db_sym.h>
   47 #include <ddb/db_extern.h>
   48 #include <ddb/db_var.h>
   49 
   50 char    db_line[120];
   51 char *  db_lp, *db_endlp;
   52 
   53 db_expr_t db_tok_number;
   54 char    db_tok_string[TOK_STRING_SIZE];
   55 
   56 int
   57 db_read_line(void)
   58 {
   59         int     i;
   60 
   61         i = db_readline(db_line, sizeof(db_line));
   62         if (i == 0)
   63             return (0); /* EOI */
   64         db_lp = db_line;
   65         db_endlp = db_lp + i;
   66         return (i);
   67 }
   68 
   69 void
   70 db_flush_line(void)
   71 {
   72         db_lp = db_line;
   73         db_endlp = db_line;
   74 }
   75 
   76 int     db_look_char = 0;
   77 
   78 int
   79 db_read_char(void)
   80 {
   81         int     c;
   82 
   83         if (db_look_char != 0) {
   84             c = db_look_char;
   85             db_look_char = 0;
   86         }
   87         else if (db_lp >= db_endlp)
   88             c = -1;
   89         else 
   90             c = *db_lp++;
   91         return (c);
   92 }
   93 
   94 void
   95 db_unread_char(int c)
   96 {
   97         db_look_char = c;
   98 }
   99 
  100 int     db_look_token = 0;
  101 
  102 void
  103 db_unread_token(int t)
  104 {
  105         db_look_token = t;
  106 }
  107 
  108 int
  109 db_read_token(void)
  110 {
  111         int     t;
  112 
  113         if (db_look_token) {
  114             t = db_look_token;
  115             db_look_token = 0;
  116         }
  117         else
  118             t = db_lex();
  119         return (t);
  120 }
  121 
  122 void
  123 db_flush_lex(void)
  124 {
  125         db_flush_line();
  126         db_look_char = 0;
  127         db_look_token = 0;
  128 }
  129 
  130 int
  131 db_lex(void)
  132 {
  133         int     c;
  134 
  135         c = db_read_char();
  136         while (c <= ' ' || c > '~') {
  137             if (c == '\n' || c == -1)
  138                 return (tEOL);
  139             c = db_read_char();
  140         }
  141 
  142         if (c >= '0' && c <= '9') {
  143             /* number */
  144             int r, digit = 0;
  145 
  146             if (c > '0')
  147                 r = db_radix;
  148             else {
  149                 c = db_read_char();
  150                 if (c == 'O' || c == 'o')
  151                     r = 8;
  152                 else if (c == 'T' || c == 't')
  153                     r = 10;
  154                 else if (c == 'X' || c == 'x')
  155                     r = 16;
  156                 else {
  157                     r = db_radix;
  158                     db_unread_char(c);
  159                 }
  160                 c = db_read_char();
  161             }
  162             db_tok_number = 0;
  163             for (;;) {
  164                 if (c >= '0' && c <= ((r == 8) ? '7' : '9'))
  165                     digit = c - '0';
  166                 else if (r == 16 && ((c >= 'A' && c <= 'F') ||
  167                                      (c >= 'a' && c <= 'f'))) {
  168                     if (c >= 'a')
  169                         digit = c - 'a' + 10;
  170                     else if (c >= 'A')
  171                         digit = c - 'A' + 10;
  172                 }
  173                 else
  174                     break;
  175                 db_tok_number = db_tok_number * r + digit;
  176                 c = db_read_char();
  177             }
  178             if ((c >= '0' && c <= '9') ||
  179                 (c >= 'A' && c <= 'Z') ||
  180                 (c >= 'a' && c <= 'z') ||
  181                 (c == '_'))
  182             {
  183                 db_error("Bad character in number\n");
  184                 /*NOTREACHED*/
  185             }
  186             db_unread_char(c);
  187             return (tNUMBER);
  188         }
  189         if ((c >= 'A' && c <= 'Z') ||
  190             (c >= 'a' && c <= 'z') ||
  191             c == '_' || c == '\\')
  192         {
  193             /* string */
  194             char *cp;
  195 
  196             cp = db_tok_string;
  197             if (c == '\\') {
  198                 c = db_read_char();
  199                 if (c == '\n' || c == -1) {
  200                     db_error("Bad escape\n");
  201                     /*NOTREACHED*/
  202                 }
  203             }
  204             *cp++ = c;
  205             while (1) {
  206                 c = db_read_char();
  207                 if ((c >= 'A' && c <= 'Z') ||
  208                     (c >= 'a' && c <= 'z') ||
  209                     (c >= '0' && c <= '9') ||
  210                     c == '_' || c == '\\' || c == ':')
  211                 {
  212                     if (c == '\\') {
  213                         c = db_read_char();
  214                         if (c == '\n' || c == -1) {
  215                             db_error("Bad escape\n");
  216                             /*NOTREACHED*/
  217                         }
  218                     }
  219                     *cp++ = c;
  220                     if (cp == db_tok_string+sizeof(db_tok_string)) {
  221                         db_error("String too long\n");
  222                         /*NOTREACHED*/
  223                     }
  224                     continue;
  225                 }
  226                 else {
  227                     *cp = '\0';
  228                     break;
  229                 }
  230             }
  231             db_unread_char(c);
  232             return (tIDENT);
  233         }
  234 
  235         switch (c) {
  236             case '+':
  237                 return (tPLUS);
  238             case '-':
  239                 return (tMINUS);
  240             case '.':
  241                 c = db_read_char();
  242                 if (c == '.')
  243                     return (tDOTDOT);
  244                 db_unread_char(c);
  245                 return (tDOT);
  246             case '*':
  247                 return (tSTAR);
  248             case '/':
  249                 return (tSLASH);
  250             case '=':
  251                 return (tEQ);
  252             case '%':
  253                 return (tPCT);
  254             case '#':
  255                 return (tHASH);
  256             case '(':
  257                 return (tLPAREN);
  258             case ')':
  259                 return (tRPAREN);
  260             case ',':
  261                 return (tCOMMA);
  262             case '"':
  263                 return (tDITTO);
  264             case '$':
  265                 return (tDOLLAR);
  266             case '!':
  267                 return (tEXCL);
  268             case '<':
  269                 c = db_read_char();
  270                 if (c == '<')
  271                     return (tSHIFT_L);
  272                 db_unread_char(c);
  273                 break;
  274             case '>':
  275                 c = db_read_char();
  276                 if (c == '>')
  277                     return (tSHIFT_R);
  278                 db_unread_char(c);
  279                 break;
  280             case -1:
  281                 return (tEOF);
  282         }
  283         db_printf("Bad character\n");
  284         db_flush_lex();
  285         return (tEOF);
  286 }

/* [<][>][^][v][top][bottom][index][help] */