⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sesl_expr.c

📁 一个用在mips体系结构中的操作系统
💻 C
字号:
/* * Copyright (C) 1996-1998 by the Board of Trustees *    of Leland Stanford Junior University. *  * This file is part of the SimOS distribution.  * See LICENSE file for terms of the license.  * */#include <stdlib.h>#include <stdio.h>#include <ctype.h>#include <string.h>#include "cpu_interface.h"#include "symbols.h"#include "sesl_lib.h"#include "sesl_expr.h"#include "sim_error.h"/*  CFL: * *     top   = exec:src:expr | exec:src:int *     expr  = *expr | &expr | (typecast) int | term *     term  = term.string | term->string | term[ int ] | term < int > | atom *     atom  = (expr) | string */#define MAX_STR_LEN 256#define BUFFER_SIZE 64int SymParseExpr(ParseInfo *pip);int SymParseTerm(ParseInfo *pip);int SymParseAtom(ParseInfo *pip);int SymParseField(ParseInfo *pip);int SymDeref(ParseInfo *pip);int SymParseTypeCast(ParseInfo *pip);char *SymParseString(ParseInfo *pip, int special);int SymParseInt(char **str, Reg *val);static char ename[MAX_STR_LEN];static char fname[MAX_STR_LEN];int SymParse(char *symexpr, ParseInfo *pip){    int offset;    char *str = symexpr;    int line;    SESL_ADDR temp_addr;        if (sscanf(str, "%[^:]%n", ename, &offset) != 1) {        ename[0] = '\0';    } else {        str += offset;    }        if (*str++ != ':') {        SymReportError("syntax error parsing execname", NULL);        return SYM_ERROR;    }        if (sscanf(str, "%[^:]%n", fname, &offset) != 1) {        fname[0] = '\0';    } else {        str += offset;    }       if (*str++ != ':') {       SymReportError("syntax error parsing source file name", NULL);       return SYM_ERROR;   }      if (isdigit(*str)) {       /* must be a line number */       if (sscanf(str, "%i%n", &line, &offset) != 1) {           SymReportError("expected a line number, got \"", str, "\"", NULL);           return SYM_ERROR;       }       if ((str[0] == '0') && (str[1] == '\0')) {           ASSERT(line == 0);           ASSERT(offset == 2);           /* WAR bug in scanf */           offset = 1;       }       str += offset;              if (!(temp_addr = SESL_Line2Addr(ename, fname, line))) {           return SYM_ERROR;       }       if (!(pip->sym = SESL_CreateSymbol(pip->execname, temp_addr, "int"))) {           return SYM_ERROR;       }       pip->value = SESL_GetAddress(pip->sym);       pip->constant = 1;          } else {       pip->execname = ename;       pip->srcfile = fname;       pip->str = str;       pip->internal = (!strcmp(ename, "SIMOS"));#ifdef __alpha       if (pip->internal) {            return SYM_ERROR;       }#endif              if (SymParseExpr(pip) != SYM_OK) {           return SYM_ERROR;       }              pip->value = SESL_GetAddress(pip->sym);       str = pip->str;   }      if (*str != '\0') {       SymReportError("extra characters at end of expression\"", str, "\"", NULL);       return SYM_ERROR;   }      return SYM_OK;}int SymParseExpr(ParseInfo *pip){   int code;      if (pip->str[0] == '*') {      pip->str++;             if ((code = SymParseExpr(pip)) != SYM_OK) {         return code;      }      if ((code = SymDeref(pip)) != SYM_OK) {         return code;      }   } else if (pip->str[0] == '&') {      pip->str++;      if ((code = SymParseExpr(pip)) != SYM_OK) {         return code;      }      if (pip->constant) {         SymReportError("cannot take address of address", NULL);         return SYM_ERROR;      }      pip->constant = 1;   } else if (pip->str[0] == '(') {      /*       *  OK here is the problem. This could be either a type cast or a        *  sub-expression. The way to figure this out is to read to the       *  matching end paren and see if the next token is anything but a       *  ".", "->", or a "[". We will just let SymParseTypeCast figure       *  it all out.       */      return SymParseTypeCast(pip);         } else {      return SymParseTerm(pip);   }   return SYM_OK;}int SymParseTerm(ParseInfo *pip){   int code;   if ((code = SymParseAtom(pip)) != SYM_OK) {      return code;   }   while (1) {      if (pip->str[0] == '.') {         pip->str++;                  if ((code = SymParseField(pip)) != SYM_OK) {            return code;         }               } else if ((pip->str[0] == '-') && (pip->str[1] == '>')) {         pip->str += 2;         if ((code = SymDeref(pip)) != SYM_OK) {            return code;         }         if ((code = SymParseField(pip)) != SYM_OK) {            return code;         }               } else if ((pip->str[0] == '[') || (pip->str[0] == '<')) {         Reg val;                  pip->str++;         if ((code = SymDeref(pip)) != SYM_OK) {            return code;         }         if ((code = SymParseInt(&(pip->str), &val)) != SYM_OK) {            return code;         }         if ((pip->str[0] != ']') && (pip->str[0] != '>')) {            SymReportError("\"]\" or \">\" expected", NULL);            return SYM_ERROR;         }         pip->str++;         pip->sym = SESL_Index(pip->sym, val);         pip->value = SESL_GetAddress(pip->sym);      } else if (pip->str[0] == ':') {         char *symb;                  pip->str++;         if (SESL_GetType(pip->sym) != SESL_TYPE_FUNC) {            SymReportError("can't use \":\" operator on non-procedure", NULL);            return SYM_ERROR;         }         if (!(symb = SymParseString(pip,0))) {            return SYM_ERROR;         }         if (!strcmp(symb, "START")) {                     } else if (!strcmp(symb, "STARTOPT")) {             pip->sym = SESL_Index(pip->sym, 12);             pip->value = SESL_GetAddress(pip->sym);         } else if (!strcmp(symb, "END")) {             pip->sym = SESL_Index(pip->sym, ((long)SESL_GetSize(pip->sym))-4);             pip->value = SESL_GetAddress(pip->sym);                     } else if ((pip->sym = SESL_FindInBlock(pip->sym, symb))) {             if (SESL_GetType(pip->sym) != SESL_TYPE_LABEL) {                 SymReportError("symbol is not a label", NULL);                 return SYM_ERROR;             }                          pip->value = SESL_GetAddress(pip->sym);         } else {             SymReportError("No such label in procedure", NULL);             return SYM_ERROR;         }         return SYM_OK;               } else {         return SYM_OK;      }   }   return SYM_OK;}int SymParseAtom(ParseInfo *pip){   int code;   int st;      if (pip->str[0] == '(') {      pip->str++;      if ((code = SymParseExpr(pip)) != SYM_OK) {          return code;      }      if (pip->str[0] != ')') {          SymReportError("\")\" expected", NULL);          return SYM_ERROR;      }      pip->str++;         } else if (isalpha(pip->str[0]) || (pip->str[0] == '_')) {       char *symb;              if (!(symb = SymParseString(pip,0))) {           return SYM_ERROR;       }              if (!(pip->sym = SESL_LookupSymbol(pip->execname, pip->srcfile, symb)))       {           SymReportError("SESL_LookupSymbol returned failure", NULL);           return SYM_ERROR;       }              st = SESL_GetType(pip->sym);              if ((st == SESL_TYPE_FUNC) || (st == SESL_TYPE_LABEL) ||           (st == SESL_TYPE_ARRAY)) {           pip->constant = 1;       } else {           pip->constant = 0;       }              pip->value = SESL_GetAddress(pip->sym);          } else if (isdigit(pip->str[0])) {       char *symb;       Reg val;       if ((SymParseInt(&(pip->str), &val)) != SYM_OK) {           return SYM_ERROR;       }       if (!(pip->sym = SESL_CreateSymbol(pip->execname, val, "int"))) {           return SYM_ERROR;       }       pip->value = SESL_GetAddress(pip->sym);       pip->constant = 1;   } else {       SymReportError("syntax error, expected \".\" or \"->\"", NULL);       return SYM_ERROR;   }      return SYM_OK;}int SymParseField(ParseInfo *pip){   char *symb;   int st;   while (SESL_CanDereference(pip->sym))   {       if (SymDeref(pip) != SYM_OK) {           return SYM_ERROR;       }   }   st = SESL_GetType(pip->sym);      if ((st != SESL_TYPE_STRUCT) && (st != SESL_TYPE_UNION)) {      SymReportError("expected a structure", NULL);      return SYM_ERROR;   }   ASSERT(!pip->constant);      if (!(symb = SymParseString(pip,0))) {      return SYM_ERROR;   }   if (!(pip->sym = SESL_FindMember(pip->sym, symb))) {       return SYM_ERROR;   }   st = SESL_GetType(pip->sym);      if (st == SESL_TYPE_ARRAY)       pip->constant = 1;   else       ASSERT(st != SESL_TYPE_FUNC);   pip->value = SESL_GetAddress(pip->sym);   return SYM_OK;}int SymDeref(ParseInfo *pip){   Reg_s value = 0;   int st;   st = SESL_GetType(pip->sym);   pip->value = SESL_GetAddress(pip->sym);   if (st == SESL_TYPE_PTR) {       if (pip->constant) {           pip->constant = 0;           if (!(pip->sym = SESL_Dereference(pip->sym, pip->value))) {               return SYM_ERROR;           }       } else if (pip->internal) {         /*          * XXX chances are that this is broken          * XXX for some configurations          */#ifdef __alpha         ASSERT (0);#else         pip->value = *(Reg_s*)pip->value;#endif       } else {           if (CPUVec.GetMemory(CPUVec.CurrentCpuNum(), pip->value,                                sizeof(value), (char *)&value) != SUCCESS) {               SymReportError("addr not mapped", NULL);               return SYM_ERROR;           }                      if (sizeof(value) == 4)               pip->value = BE2HO_4(value);           else if (sizeof(value) == 8)               pip->value = BE2HO_8(value);           else               ASSERT(0);           if (!(pip->sym = SESL_Dereference(pip->sym, pip->value))) {               return SYM_ERROR;           }       }   } else if (st == SESL_TYPE_ARRAY) {       ASSERT(pip->constant);       pip->constant = 0;       if (!(pip->sym = SESL_Dereference(pip->sym, pip->value))) {           return SYM_ERROR;       }   } else {       SymReportError("array or pointer expected", NULL);       return SYM_ERROR;   }   ASSERT(!pip->constant);   st = SESL_GetType(pip->sym);      if (st == SESL_TYPE_ARRAY)       pip->constant = 1;   else       ASSERT(st != SESL_TYPE_FUNC);   pip->value = SESL_GetAddress(pip->sym);      return SYM_OK;}int SymParseTypeCast(ParseInfo *pip){   char *str;   char *name = "";   char *scan;   int level, i;   int types[6];   int bt;      ASSERT(pip->str[0] == '(');   /* check if it is a typecast */   for (level=1, scan=pip->str+1; level && *scan; scan++) {       if (*scan == '(') {           level++;       } else if (*scan == ')') {           level--;      }   }   if ((*scan == '.') || (*scan == '[')       || (*scan == '<') || (*scan == ')') || (*scan == '\0')       || ((*scan == '-') && (*(scan+1) == '>'))) {      /* not a typecast - oh well just parse it as a term */      return SymParseTerm(pip);         }      /* its a type cast */   pip->str++;      str = SymParseString(pip,1);   if (!strlen(str) || (pip->str[0] != ')')) {       SymReportError("Syntax error in type cast", NULL);       return SYM_ERROR;   }   pip->str++;      if (SymParseExpr(pip) != SYM_OK) {       SymReportError("Attempt to cast bad expression.", NULL);       return SYM_ERROR;   }      if (!(pip->sym = SESL_Cast(pip->execname, pip->sym, str))) {       return SYM_ERROR;   }   pip->value = SESL_GetAddress(pip->sym);   return SYM_OK;}int SymParseInt(char **str, Reg *val){   while (**str == ' ') {      (*str)++;   }   if (isdigit(**str)) {      uint64 val64;      char *tmpstr = *str;#if defined(__alpha) || defined(i386)      val64 = strtoul(*str, &tmpstr, 0);#else      val64 = strtoull(*str, &tmpstr, 0);#endif      if ((val64 == 0) && (*str == tmpstr))      {          return SYM_ERROR;      }      *val = val64;      *str = tmpstr;      while (**str == ' ') {         (*str)++;      }   } else {      SymReportError("expected an int, got \"", str, "\"", NULL);      return SYM_ERROR;   }   return SYM_OK;}char *SymParseString(ParseInfo *pip, int special){   static char buf[BUFFER_SIZE];   char *dst = buf;   while (isalnum(*(pip->str)) || (*(pip->str) == '_') ||           (*(pip->str) == ' ') || (*(pip->str) == '*')) {       if (!special && ((*(pip->str) == ' ') || (*(pip->str) == '*')))           break;       if ((dst - buf) == (BUFFER_SIZE-1)) {           SymReportError("symbol overflowed internal buffers (internal error)", NULL);           return NULL;       }       *dst++ = *(pip->str)++;   }      *dst = '\0';   if (!buf[0]) {      SymReportError("expected a string", NULL);   }      return buf;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -