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

📄 lex.cc

📁 早期freebsd实现
💻 CC
📖 第 1 页 / 共 2 页
字号:
const int NCONTEXT = 4;string context_ring[NCONTEXT];int context_index = 0;void flush_context(){  for (int i = 0; i < NCONTEXT; i++)    context_ring[i] = "";  context_index = 0;}void show_context(){  int i = context_index;  fputs(" context is\n\t", stderr);  for (;;) {    int j = (i + 1) % NCONTEXT;    if (j == context_index) {      fputs(">>> ", stderr);      put_string(context_ring[i], stderr);      fputs(" <<<", stderr);      break;    }    else if (context_ring[i].length() > 0) {      put_string(context_ring[i], stderr);      putc(' ', stderr);    }    i = j;  }  putc('\n', stderr);}void add_context(const string &s){  context_ring[context_index] = s;  context_index = (context_index + 1) % NCONTEXT;}void add_context(char c){  context_ring[context_index] = c;  context_index = (context_index + 1) % NCONTEXT;}void add_quoted_context(const string &s){  string &r = context_ring[context_index];  r = '"';  for (int i = 0; i < s.length(); i++)    if (s[i] == '"')      r += "\\\"";    else      r += s[i];  r += '"';  context_index = (context_index + 1) % NCONTEXT;}void init_lex(const char *str, const char *filename, int lineno){ while (current_input != 0) {    input *tem = current_input;    current_input = current_input->next;    delete tem;  }  current_input = new top_input(str, filename, lineno, 0);  flush_context();}void get_delimited_text(){  char *filename;  int lineno;  int got_location = get_location(&filename, &lineno);  int start = get_char();  while (start == ' ' || start == '\t' || start == '\n')    start = get_char();  token_buffer.clear();  if (start == EOF) {    if (got_location)      error_with_file_and_line(filename, lineno,			       "end of input while defining macro");    else      error("end of input while defining macro");    return;  }  for (;;) {    int c = get_char();    if (c == EOF) {      if (got_location)	error_with_file_and_line(filename, lineno,				 "end of input while defining macro");      else	error("end of input while defining macro");      add_context(start + token_buffer);      return;    }    if (c == start)      break;    token_buffer += char(c);  }  add_context(start + token_buffer + start);}void interpolate_macro_with_args(const char *body){  char *argv[9];  int argc = 0;  for (int i = 0; i < 9; i++)    argv[i] = 0;  int level = 0;  int c;  do {    token_buffer.clear();    for (;;) {      c = get_char();      if (c == EOF) {	lex_error("end of input while scanning macro arguments");	break;      }      if (level == 0 && (c == ',' || c == ')')) {	if (token_buffer.length() > 0) {	  token_buffer +=  '\0';	  argv[argc] = strsave(token_buffer.contents());	}	// for `foo()', argc = 0	if (argc > 0 || c != ')' || i > 0)	  argc++;	break;      }      token_buffer += char(c);      if (c == '(')	level++;      else if (c == ')')	level--;    }  } while (c != ')' && c != EOF);  current_input = new argument_macro_input(body, argc, argv, current_input);}/* If lookup flag is non-zero the token will be looked up to seeif it is macro. If it's 1, it will looked up to see if it's a token.*/int get_token(int lookup_flag = 0){  for (;;) {    int c = get_char();    while (c == ' ' || c == '\n')      c = get_char();    switch (c) {    case EOF:      add_context("end of input");      return 0;    case '"':      {	int quoted = 0;	token_buffer.clear();	for (;;) {	  c = get_char();	  if (c == EOF) {	    lex_error("missing \"");	    break;	  }	  else if (c == '\n') {	    lex_error("newline before end of quoted text");	    break;	  }	  else if (c == '"') {	    if (!quoted)	      break;	    token_buffer[token_buffer.length() - 1] = '"';	    quoted = 0;	  }	  else {	    token_buffer += c;	    quoted = quoted ? 0 : c == '\\';	  }	}      }      add_quoted_context(token_buffer);      return QUOTED_TEXT;    case '{':    case '}':    case '^':    case '~':    case '\t':      add_context(c);      return c;    default:      {	int break_flag = 0;	int quoted = 0;	token_buffer.clear();	if (c == '\\')	  quoted = 1;	else	  token_buffer += c;	int done = 0;	while (!done) {	  c = peek_char();	  if (!quoted && lookup_flag != 0 && c == '(') {	    token_buffer += '\0';	    definition *def = macro_table.lookup(token_buffer.contents());	    if (def && def->is_macro && !def->is_simple) {	      (void)get_char();	// skip initial '('	      interpolate_macro_with_args(def->contents);	      break_flag = 1;	      break;	    }	    token_buffer.set_length(token_buffer.length() - 1);	  }	  if (quoted) {	    quoted = 0;	    switch (c) {	    case EOF:	      lex_error("`\\' ignored at end of equation");	      done = 1;	      break;	    case '\n':	      lex_error("`\\' ignored because followed by newline");	      done = 1;	      break;	    case '\t':	      lex_error("`\\' ignored because followed by tab");	      done = 1;	      break;	    case '"':	      (void)get_char();	      token_buffer += '"';	      break;	    default:	      (void)get_char();	      token_buffer += '\\';	      token_buffer += c;	      break;	    }	  }	  else {	    switch (c) {	    case EOF:	    case '{':	    case '}':	    case '^':	    case '~':	    case '"':	    case ' ':	    case '\t':	    case '\n':	      done = 1;	      break;	    case '\\':	      (void)get_char();	      quoted = 1;	      break;	    default:	      (void)get_char();	      token_buffer += char(c);	      break;	    }	  }	}	if (break_flag || token_buffer.length() == 0)	  break;	if (lookup_flag != 0) {	  token_buffer += '\0';	  definition *def = macro_table.lookup(token_buffer.contents());	  token_buffer.set_length(token_buffer.length() - 1);	  if (def) {	    if (def->is_macro) {	      current_input = new macro_input(def->contents, current_input);	      break;	    }	    else if (lookup_flag == 1) {	      add_context(token_buffer);	      return def->tok;	    }	  }	}	add_context(token_buffer);	return TEXT;      }    }  }}void do_include(){  int t = get_token(2);  if (t != TEXT && t != QUOTED_TEXT) {    lex_error("bad filename for include");    return;  }  token_buffer += '\0';  const char *filename = token_buffer.contents();  errno = 0;  FILE *fp = fopen(filename, "r");  if (fp == 0) {    lex_error("can't open included file `%1'", filename);    return;  }  current_input = new file_input(fp, filename, current_input);}void ignore_definition(){  int t = get_token();  if (t != TEXT) {    lex_error("bad definition");    return;  }  get_delimited_text();}void do_definition(int is_simple){  int t = get_token();  if (t != TEXT) {    lex_error("bad definition");    return;  }  token_buffer += '\0';  const char *name = token_buffer.contents();  definition *def = macro_table.lookup(name);  if (def == 0) {    def = new definition;    macro_table.define(name, def);  }  else if (def->is_macro) {    a_delete def->contents;  }  get_delimited_text();  token_buffer += '\0';  def->is_macro = 1;  def->contents = strsave(token_buffer.contents());  def->is_simple = is_simple;}void do_undef(){  int t = get_token();  if (t != TEXT) {    lex_error("bad undef command");    return;  }  token_buffer += '\0';  macro_table.define(token_buffer.contents(), 0);}void do_gsize(){  int t = get_token(2);  if (t != TEXT && t != QUOTED_TEXT) {    lex_error("bad argument to gsize command");    return;  }  token_buffer += '\0';  if (!set_gsize(token_buffer.contents()))    lex_error("invalid size `%1'", token_buffer.contents());}void do_gfont(){  int t = get_token(2);  if (t != TEXT && t != QUOTED_TEXT) {    lex_error("bad argument to gfont command");    return;  }  token_buffer += '\0';  set_gfont(token_buffer.contents());}void do_grfont(){  int t = get_token(2);  if (t != TEXT && t != QUOTED_TEXT) {    lex_error("bad argument to grfont command");    return;  }  token_buffer += '\0';  set_grfont(token_buffer.contents());}void do_gbfont(){  int t = get_token(2);  if (t != TEXT && t != QUOTED_TEXT) {    lex_error("bad argument to gbfont command");    return;  }  token_buffer += '\0';  set_gbfont(token_buffer.contents());}void do_space(){  int t = get_token(2);  if (t != TEXT && t != QUOTED_TEXT) {    lex_error("bad argument to space command");    return;  }  token_buffer += '\0';  char *ptr;  long n = strtol(token_buffer.contents(), &ptr, 10);  if (n == 0 && ptr == token_buffer.contents())    lex_error("bad argument `%1' to space command");  else    set_space(int(n));}void do_ifdef(){  int t = get_token();  if (t != TEXT) {    lex_error("bad ifdef");    return;  }  token_buffer += '\0';  definition *def = macro_table.lookup(token_buffer.contents());  int result = def && def->is_macro && !def->is_simple;  get_delimited_text();  if (result) {    token_buffer += '\0';    current_input = new macro_input(token_buffer.contents(), current_input);  }}void do_delim(){  int c = get_char();  while (c == ' ' || c == '\n')    c = get_char();  int d;  if (c == EOF || (d = get_char()) == EOF)    lex_error("end of file while reading argument to `delim'");  else {    if (c == 'o' && d == 'f' && peek_char() == 'f') {      (void)get_char();      start_delim = end_delim = '\0';    }    else {      start_delim = c;      end_delim = d;    }  }}void do_chartype(){  int t = get_token(2);  if (t != TEXT && t != QUOTED_TEXT) {    lex_error("bad chartype");    return;  }  token_buffer += '\0';  string type = token_buffer;  t = get_token();  if (t != TEXT && t != QUOTED_TEXT) {    lex_error("bad chartype");    return;  }  token_buffer += '\0';  set_char_type(type.contents(), strsave(token_buffer.contents()));}void do_set(){  int t = get_token(2);  if (t != TEXT && t != QUOTED_TEXT) {    lex_error("bad set");    return;  }  token_buffer += '\0';  string param = token_buffer;  t = get_token();  if (t != TEXT && t != QUOTED_TEXT) {    lex_error("bad set");    return;  }  token_buffer += '\0';  int n;  if (sscanf(&token_buffer[0], "%d", &n) != 1) {    lex_error("bad number `%1'", token_buffer.contents());    return;  }  set_param(param.contents(), n);}int yylex(){  for (;;) {    int tk = get_token(1);    switch(tk) {    case UNDEF:      do_undef();      break;    case SDEFINE:      do_definition(1);      break;    case DEFINE:      do_definition(0);      break;    case TDEFINE:      if (!nroff)	do_definition(0);      else	ignore_definition();      break;    case NDEFINE:      if (nroff)	do_definition(0);      else	ignore_definition();      break;    case GSIZE:      do_gsize();      break;    case GFONT:      do_gfont();      break;    case GRFONT:      do_grfont();      break;    case GBFONT:      do_gbfont();      break;    case SPACE:      do_space();      break;    case INCLUDE:      do_include();      break;    case IFDEF:      do_ifdef();      break;    case DELIM:      do_delim();      break;    case CHARTYPE:      do_chartype();      break;    case SET:      do_set();      break;    case QUOTED_TEXT:    case TEXT:      token_buffer += '\0';      yylval.str = strsave(token_buffer.contents());      // fall through    default:      return tk;    }  }}void lex_error(const char *message,	       const errarg &arg1,	       const errarg &arg2,	       const errarg &arg3){  char *filename;  int lineno;  if (!get_location(&filename, &lineno))    error(message, arg1, arg2, arg3);  else    error_with_file_and_line(filename, lineno, message, arg1, arg2, arg3);}void yyerror(const char *s){  char *filename;  int lineno;  if (!get_location(&filename, &lineno))    error(s);  else    error_with_file_and_line(filename, lineno, s);  show_context();}

⌨️ 快捷键说明

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