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

📄 lex.cc

📁 早期freebsd实现
💻 CC
📖 第 1 页 / 共 3 页
字号:
  const char *name = nm.contents();  if (!get_delimited())    return;  token_buffer += '\0';  macro_table.define(name, strsave(token_buffer.contents()));}void do_undef(){  int t = get_token(0);		// do not expand what we are undefining  if (t != VARIABLE && t != LABEL) {    lex_error("can only define variable or placename");    return;  }  token_buffer += '\0';  macro_table.define(token_buffer.contents(), 0);}class for_input : public input {  char *var;  char *body;  double to;  int by_is_multiplicative;  double by;  const char *p;  int done_newline;public:  for_input(char *, double, int, double, char *);  ~for_input();  int get();  int peek();};for_input::for_input(char *vr, double t, int bim, double b, char *bd): var(vr), to(t), by_is_multiplicative(bim), by(b), body(bd), p(body),  done_newline(0){}for_input::~for_input(){  a_delete var;  a_delete body;}int for_input::get(){  if (p == 0)    return EOF;  for (;;) {    if (*p != '\0')      return (unsigned char)*p++;    if (!done_newline) {      done_newline = 1;      return '\n';    }    double val;    if (!lookup_variable(var, &val)) {      lex_error("body of `for' terminated enclosing block");      return EOF;    }    if (by_is_multiplicative)      val *= by;    else      val += by;    define_variable(var, val);    if (val > to) {      p = 0;      return EOF;    }    p = body;    done_newline = 0;  }}int for_input::peek(){  if (p == 0)    return EOF;  if (*p != '\0')    return (unsigned char)*p;  if (!done_newline)    return '\n';  double val;  if (!lookup_variable(var, &val))    return EOF;  if (by_is_multiplicative) {    if (val * by > to)      return EOF;  }  else {    if (val + by > to)      return EOF;  }  if (*body == '\0')    return EOF;  return (unsigned char)*body;}void do_for(char *var, double from, double to, int by_is_multiplicative,	    double by, char *body){  define_variable(var, from);  if (from <= to)    input_stack::push(new for_input(var, to, by_is_multiplicative, by, body));}void do_copy(const char *filename){  errno = 0;  FILE *fp = fopen(filename, "r");  if (fp == 0) {    lex_error("can't open `%1': %2", filename, strerror(errno));    return;  }  input_stack::push(new file_input(fp, filename));}class copy_thru_input : public input {  int done;  char *body;  char *until;  const char *p;  const char *ap;  int argv[9];  int argc;  string line;  int get_line();  virtual int inget() = 0;public:  copy_thru_input(const char *b, const char *u);  ~copy_thru_input();  int get();  int peek();};class copy_file_thru_input : public copy_thru_input {  input *in;public:  copy_file_thru_input(input *, const char *b, const char *u);  ~copy_file_thru_input();  int inget();};copy_file_thru_input::copy_file_thru_input(input *i, const char *b,					   const char *u): in(i), copy_thru_input(b, u){}copy_file_thru_input::~copy_file_thru_input(){  delete in;}int copy_file_thru_input::inget(){  if (!in)    return EOF;  else    return in->get();}class copy_rest_thru_input : public copy_thru_input {public:  copy_rest_thru_input(const char *, const char *u);  int inget();};copy_rest_thru_input::copy_rest_thru_input(const char *b, const char *u): copy_thru_input(b, u){}int copy_rest_thru_input::inget(){  while (next != 0) {    int c = next->get();    if (c != EOF)      return c;    if (next->next == 0)      return EOF;    input *tem = next;    next = next->next;    delete tem;  }  return EOF;}copy_thru_input::copy_thru_input(const char *b, const char *u): done(0){  ap = 0;  body = process_body(b);  p = 0;  until = strsave(u);}copy_thru_input::~copy_thru_input(){  a_delete body;  a_delete until;}int copy_thru_input::get(){  if (ap) {    if (*ap != '\0')      return (unsigned char)*ap++;    ap = 0;  }  for (;;) {    if (p == 0) {      if (!get_line())	break;      p = body;    }    if (*p == '\0') {      p = 0;      return '\n';    }    while (*p >= ARG1 && *p <= ARG1 + 8) {      int i = *p++ - ARG1;      if (i < argc && line[argv[i]] != '\0') {	ap = line.contents() + argv[i];	return (unsigned char)*ap++;      }    }    if (*p != '\0')      return (unsigned char)*p++;  }  return EOF;}int copy_thru_input::peek(){  if (ap) {    if (*ap != '\0')      return (unsigned char)*ap;    ap = 0;  }  for (;;) {    if (p == 0) {      if (!get_line())	break;      p = body;    }    if (*p == '\0')      return '\n';    while (*p >= ARG1 && *p <= ARG1 + 8) {      int i = *p++ - ARG1;      if (i < argc && line[argv[i]] != '\0') {	ap = line.contents() + argv[i];	return (unsigned char)*ap;      }    }    if (*p != '\0')      return (unsigned char)*p;  }  return EOF;}int copy_thru_input::get_line(){  if (done)    return 0;  line.clear();  argc = 0;  int c = inget();  for (;;) {    while (c == ' ')      c = inget();    if (c == EOF || c == '\n')      break;    if (argc == 9) {      do {	c = inget();      } while (c != '\n' && c != EOF);      break;    }    argv[argc++] = line.length();    do {      line += char(c);      c = inget();    } while (c != ' ' && c != '\n');    line += '\0';  }  if (until != 0 && argc > 0 && strcmp(&line[argv[0]], until) == 0) {    done = 1;    return 0;  }  return argc > 0 || c == '\n';}class simple_file_input : public input {  const char *filename;  int lineno;  FILE *fp;public:  simple_file_input(FILE *, const char *);  ~simple_file_input();  int get();  int peek();  int get_location(const char **, int *);};simple_file_input::simple_file_input(FILE *p, const char *s): filename(s), fp(p), lineno(1){}simple_file_input::~simple_file_input(){  // don't delete the filename  fclose(fp);}int simple_file_input::get(){  int c = getc(fp);  while (illegal_input_char(c)) {    error("illegal input character code %1", c);    c = getc(fp);  }  if (c == '\n')    lineno++;  return c;}int simple_file_input::peek(){  int c = getc(fp);  while (illegal_input_char(c)) {    error("illegal input character code %1", c);    c = getc(fp);  }  if (c != EOF)    ungetc(c, fp);  return c;}int simple_file_input::get_location(const char **fnp, int *lnp){  *fnp = filename;  *lnp = lineno;  return 1;}void copy_file_thru(const char *filename, const char *body, const char *until){  errno = 0;  FILE *fp = fopen(filename, "r");  if (fp == 0) {    lex_error("can't open `%1': %2", filename, strerror(errno));    return;  }  input *in = new copy_file_thru_input(new simple_file_input(fp, filename),				       body, until);  input_stack::push(in);}void copy_rest_thru(const char *body, const char *until){  input_stack::push(new copy_rest_thru_input(body, until));}void push_body(const char *s){  input_stack::push(new char_input('\n'));  input_stack::push(new macro_input(s));}int delim_flag = 0;char *get_thru_arg(){  int c = input_stack::peek_char();  while (c == ' ') {    input_stack::get_char();    c = input_stack::peek_char();  }  if (c != EOF && csalpha(c)) {    // looks like a macro    input_stack::get_char();    token_buffer = c;    for (;;) {      c = input_stack::peek_char();      if (c == EOF || (!csalnum(c) && c != '_'))	break;      input_stack::get_char();      token_buffer += char(c);    }    context_buffer = token_buffer;    token_buffer += '\0';    char *def = macro_table.lookup(token_buffer.contents());    if (def)      return strsave(def);    // I guess it wasn't a macro after all; so push the macro name back.    // -2 because we added a '\0'    for (int i = token_buffer.length() - 2; i >= 0; i--)      input_stack::push_back(token_buffer[i]);  }  if (get_delimited()) {    token_buffer += '\0';    return strsave(token_buffer.contents());  }  else    return 0;}int lookahead_token = -1;string old_context_buffer;void do_lookahead(){  if (lookahead_token == -1) {    old_context_buffer = context_buffer;    lookahead_token = get_token(1);  }}int yylex(){  if (delim_flag) {    assert(lookahead_token == -1);    if (delim_flag == 2) {      if ((yylval.str = get_thru_arg()) != 0)	return DELIMITED;      else	return 0;    }    else {      if (get_delimited()) {	token_buffer += '\0';	yylval.str = strsave(token_buffer.contents());	return DELIMITED;      }      else	return 0;    }  }  for (;;) {    int t;    if (lookahead_token >= 0) {      t = lookahead_token;      lookahead_token = -1;    }    else      t = get_token(1);    switch (t) {    case '\n':      return ';';    case EOF:      return 0;    case DEFINE:      do_define();      break;    case UNDEF:      do_undef();      break;    case ORDINAL:      yylval.n = token_int;      return t;    case NUMBER:      yylval.x = token_double;      return t;    case COMMAND_LINE:    case TEXT:      token_buffer += '\0';      if (!input_stack::get_location(&yylval.lstr.filename,				     &yylval.lstr.lineno)) {	yylval.lstr.filename = 0;	yylval.lstr.lineno = -1;      }      yylval.lstr.str = strsave(token_buffer.contents());      return t;    case LABEL:    case VARIABLE:      token_buffer += '\0';      yylval.str = strsave(token_buffer.contents());      return t;    case LEFT:      // change LEFT to LEFT_CORNER when followed by OF      old_context_buffer = context_buffer;      lookahead_token = get_token(1);      if (lookahead_token == OF)	return LEFT_CORNER;      else	return t;    case RIGHT:      // change RIGHT to RIGHT_CORNER when followed by OF      old_context_buffer = context_buffer;      lookahead_token = get_token(1);      if (lookahead_token == OF)	return RIGHT_CORNER;      else	return t;    case UPPER:      // recognise UPPER only before LEFT or RIGHT      old_context_buffer = context_buffer;      lookahead_token = get_token(1);      if (lookahead_token != LEFT && lookahead_token != RIGHT) {	yylval.str = strsave("upper");	return VARIABLE;      }      else	return t;    case LOWER:      // recognise LOWER only before LEFT or RIGHT      old_context_buffer = context_buffer;      lookahead_token = get_token(1);      if (lookahead_token != LEFT && lookahead_token != RIGHT) {	yylval.str = strsave("lower");	return VARIABLE;      }      else	return t;    case TOP:      // recognise TOP only before OF      old_context_buffer = context_buffer;      lookahead_token = get_token(1);      if (lookahead_token != OF) {	yylval.str = strsave("top");	return VARIABLE;      }      else	return t;    case BOTTOM:      // recognise BOTTOM only before OF      old_context_buffer = context_buffer;      lookahead_token = get_token(1);      if (lookahead_token != OF) {	yylval.str = strsave("bottom");	return VARIABLE;      }      else	return t;    case CENTER:      // recognise CENTER only before OF      old_context_buffer = context_buffer;      lookahead_token = get_token(1);      if (lookahead_token != OF) {	yylval.str = strsave("center");	return VARIABLE;      }      else	return t;    case START:      // recognise START only before OF      old_context_buffer = context_buffer;      lookahead_token = get_token(1);      if (lookahead_token != OF) {	yylval.str = strsave("start");	return VARIABLE;      }      else	return t;    case END:      // recognise END only before OF      old_context_buffer = context_buffer;      lookahead_token = get_token(1);      if (lookahead_token != OF) {	yylval.str = strsave("end");	return VARIABLE;      }      else	return t;    default:      return t;    }  }}void lex_error(const char *message,	       const errarg &arg1,	       const errarg &arg2,	       const errarg &arg3){  const char *filename;  int lineno;  if (!input_stack::get_location(&filename, &lineno))    error(message, arg1, arg2, arg3);  else    error_with_file_and_line(filename, lineno, message, arg1, arg2, arg3);}void lex_warning(const char *message,		 const errarg &arg1,		 const errarg &arg2,		 const errarg &arg3){  const char *filename;  int lineno;  if (!input_stack::get_location(&filename, &lineno))    warning(message, arg1, arg2, arg3);  else    warning_with_file_and_line(filename, lineno, message, arg1, arg2, arg3);}void yyerror(const char *s){  const char *filename;  int lineno;  const char *context = 0;  if (lookahead_token == -1) {    if (context_buffer.length() > 0) {      context_buffer += '\0';      context = context_buffer.contents();    }  }  else {    if (old_context_buffer.length() > 0) {      old_context_buffer += '\0';      context = old_context_buffer.contents();    }  }  if (!input_stack::get_location(&filename, &lineno)) {    if (context) {      if (context[0] == '\n' && context[1] == '\0')	error("%1 before newline", s);      else	error("%1 before `%2'", s, context);    }    else      error("%1 at end of picture", s);  }  else {    if (context) {      if (context[0] == '\n' && context[1] == '\0')	error_with_file_and_line(filename, lineno, "%1 before newline", s);      else	error_with_file_and_line(filename, lineno, "%1 before `%2'",				 s, context);    }    else      error_with_file_and_line(filename, lineno, "%1 at end of picture", s);  }}

⌨️ 快捷键说明

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