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

📄 token.c

📁 MicroChip的12BIt和14Bit的PIC系列单片机的汇编器
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * picasm -- token.c * * Include handling, macro expansion, lexical analysis * * Timo Rossi <trossi@iki.fi> *  */#include <stdio.h>#include <string.h>#include <stdlib.h>#include <ctype.h>#include "picasm.h"/* * keyword table for tokenizer * * this must be in sync with the token definitions in picasm.h */static char Keyword_Table[] = {  "include\0"  "macro\0"  "endm\0"  "exitm\0"  "if\0"  "else\0"  "endif\0"  "equ\0"  "set\0"  "end\0"  "org\0"  "ds\0"  "edata\0"  "config\0"  "picid\0"  "device\0"  "defined\0"  "streq\0"  "isstr\0"  "chrval\0"  "opt\0"  "local\0"  "endlocal\0"  "error\0"	    /* 12/14-bit PIC instruction mnemonics */  "addlw\0"  "addwf\0"  "andlw\0"  "andwf\0"  "bcf\0"  "bsf\0"  "btfsc\0"  "btfss\0"  "call\0"  "clrf\0"  "clrw\0"  "clrwdt\0"  "comf\0"  "decf\0"  "decfsz\0"  "goto\0"  "incf\0"  "incfsz\0"  "iorlw\0"  "iorwf\0"  "movlw\0"  "movf\0"  "movwf\0"  "nop\0"  "option\0"  "retfie\0"  "retlw\0"  "return\0"  "rlf\0"  "rrf\0"  "sleep\0"  "sublw\0"  "subwf\0"  "swapf\0"  "tris\0"  "xorlw\0"  "xorwf\0"  "\0"};/* tokenizer definitions & variables */int tok_char;int token_type, line_buf_off;char token_string[TOKSIZE];long token_int_val;int ifskip_mode; /* TRUE when skipping code inside if..endif *//* * include file handling */voidbegin_include(char *fname){  struct inc_file *p;  p = mem_alloc(sizeof(struct inc_file));  p->type = INC_FILE;  p->v.f.fname = mem_alloc(strlen(fname)+1);  strcpy(p->v.f.fname, fname);  p->linenum = 0;  p->cond_nest_count = cond_nest_count;  if((p->v.f.fp = fopen(p->v.f.fname, "r")) == NULL) {    if(current_file == NULL) {      fatal_error("Can't open '%s'", p->v.f.fname);    } else {      error(0, "Can't open include file '%s'", p->v.f.fname);      free(p->v.f.fname);      free(p);      line_buf_ptr = NULL;      tok_char = ' ';      return;    }  }  p->next = current_file;  current_file = p;  line_buf_ptr = NULL;  tok_char = ' ';}/* * Move to previous level of include/macro */voidend_include(void){  struct inc_file *p;  struct macro_arg *arg1, *arg2;  if(current_file != NULL) {    if(cond_nest_count != current_file->cond_nest_count) {      error(0, "conditional assembly not terminated by ENDIF");      cond_nest_count = current_file->cond_nest_count;    }    p = current_file->next;    if(current_file->type == INC_FILE) {      fclose(current_file->v.f.fp);      free(current_file->v.f.fname);    } else { /* free macro arguments */      arg1 = current_file->v.m.args;      while(arg1 != NULL) {	arg2 = arg1->next;	free(arg1);	arg1 = arg2;      }    }    free(current_file);    current_file = p;  }}/* * Expand a macro */voidexpand_macro(struct symbol *sym){  struct inc_file *minc;  struct macro_arg *arg;  char *cp;  int narg;  int parcnt, d_char;  write_listing_line(0); /* list the macro call line */  minc = mem_alloc(sizeof(struct inc_file));  minc->type = INC_MACRO;  minc->v.m.sym = sym;  minc->v.m.ml = sym->v.text;  minc->linenum = 0;  minc->cond_nest_count = cond_nest_count;  minc->v.m.args = NULL;  minc->v.m.uniq_id = unique_id_count++;  arg = NULL;  for(narg = 1;;narg++) {    while(tok_char != '\n' && isspace(tok_char)) /* skip whitespace */      read_src_char();    if(tok_char == '\n' || tok_char == '\0' ||       tok_char == ';' || tok_char == EOF)      break;    cp = line_buf_ptr-1;    /*     * Macro parameters are separated by commas. However, strings and     * character constants (using double and single quotes)     * can be used even if they contain commas. Also commas     * inside parenthesis (such as function parameter delimiters)     * don't count as macro parameter separators.     *     */    parcnt = 0; /* parenthesis nesting count */    while(!isspace(tok_char) &&	  tok_char != '\n' && tok_char != '\0' &&	  tok_char != ';' && tok_char != EOF) {      if(parcnt == 0 && tok_char == ',')	break;      if(tok_char == '(') {	parcnt++;      } else if(tok_char == ')') {	parcnt--;      } else if(tok_char == '"' || tok_char == '\'') {	/* quoted string or character constant */	d_char = tok_char;	do {	  read_src_char();	}	while(tok_char != d_char && tok_char != '\n' &&	      tok_char != '\0' && tok_char != EOF);	if(tok_char != d_char)	  break;      }      read_src_char();    }    if(narg >= 10)      warning("Too many macro arguments (max. 9)");    if(arg == NULL) {      arg = mem_alloc(sizeof(struct macro_arg)		      +(line_buf_ptr-cp-1));      minc->v.m.args = arg;    } else {      arg->next = mem_alloc(sizeof(struct macro_arg)			    +(line_buf_ptr-cp-1));      arg = arg->next;    }    strncpy(arg->text, cp, line_buf_ptr-cp-1);    arg->text[line_buf_ptr-cp-1] = '\0';    arg->next = NULL;    /* skip whitespace */    while(tok_char != '\n' && isspace(tok_char))      read_src_char();    if(tok_char != ',')      break;    read_src_char();  }  if(tok_char != ';' && tok_char != '\n' &&     tok_char != '\0' && tok_char != EOF)    error(0, "Extraneous characters after a valid source line");  minc->next = current_file;  current_file = minc;  line_buf_ptr = NULL;  tok_char = ' ';  get_token();}/* * Read a character from source file. * Handles includes and macros. */voidread_src_char(void){  char *scp, *pcp, *dcp;  int parm;  struct macro_arg *arg;  static char tmpbuf[12];  if(line_buf_ptr == NULL || *line_buf_ptr == '\0') {    if(current_file == NULL) {      tok_char = EOF;      return;    }getc1:    if(current_file->type == INC_MACRO)	{      if(current_file->v.m.ml == NULL) {	end_include();	goto getc1;      }      scp = current_file->v.m.ml->text;      dcp = line_buffer;      while(*scp != '\0' && dcp < &line_buffer[sizeof(line_buffer)]) {	if(*scp == '\\') {	  scp++;	  if(*scp >= '1' && *scp <= '9') { /* macro arg */	    parm = *scp - '1'; /* macro arg #, starting from 0 */	    for(arg = current_file->v.m.args;		arg != NULL && parm > 0; arg = arg->next, parm--);	    if(arg != NULL) {	      for(pcp = arg->text; *pcp != '\0' &&		  dcp < &line_buffer[sizeof(line_buffer)];)		*dcp++ = *pcp++;	    }	    scp++;	  } else if(*scp == '0' || *scp == '@') {	    sprintf(tmpbuf, "%03d", current_file->v.m.uniq_id);	    for(pcp = tmpbuf; *pcp != '\0' &&		dcp < &line_buffer[sizeof(line_buffer)];)	      *dcp++ = *pcp++;	    scp++;	  } else if(*scp == '#') { /* number of arguments */	    for(parm = 0, arg = current_file->v.m.args;		arg != NULL; arg = arg->next, parm++);	    sprintf(tmpbuf, "%d", parm);	    for(pcp = tmpbuf; *pcp != '\0' &&		dcp < &line_buffer[sizeof(line_buffer)];)	      *dcp++ = *pcp++;	    scp++;	  } else	    *dcp++ = *scp;	} else	  *dcp++ = *scp++;      }      if(dcp == &line_buffer[sizeof(line_buffer)]) {	error(0, "Line buffer overflow");	dcp--;      }      *dcp = '\0'; /* NUL-terminate the line */      current_file->v.m.ml = current_file->v.m.ml->next;    } else {      if(fgets(line_buffer, sizeof(line_buffer)-1,	       current_file->v.f.fp) == NULL) {	if(current_file->next != NULL) {	  end_include();	  goto getc1;	}	tok_char = EOF;	return;      }    }    current_file->linenum++;    line_buf_ptr = line_buffer;  }  tok_char = ((unsigned char)(*line_buf_ptr++));}/* * Lexical analyzer * Returns the next token from the source file */voidget_token(void){  int tp, base;  char *cp;  for(;;) {    /*     * skip spaces     */    while(tok_char != '\n' && isspace(tok_char))      read_src_char();    if(tok_char == EOF)	{      token_type = TOK_EOF;      token_string[0] = '\0';      return;    }    if(tok_char != ';')      break;    /* comment */    line_buf_ptr = NULL;    tok_char = '\n';  } /* for(;;) *//* * character constant (integer) * (does not currently handle the quote character) */  if(tok_char == '\'') {    read_src_char();    token_string[0] = tok_char;    read_src_char();    if(tok_char != '\'')      goto invalid_token;    read_src_char();    token_string[1] = '\0';    token_int_val = (long)((unsigned char)token_string[0]);    token_type = TOK_INTCONST;    return;  }  if(tok_char == '"') { /* string constant (include filename) */    read_src_char();

⌨️ 快捷键说明

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