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

📄 linetok.c

📁 < 虚拟机设计与实现>>的 windows版本
💻 C
📖 第 1 页 / 共 2 页
字号:
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+  2007.04.05 所做工作 
  修正了源代码中的一处错误。                            +
    processNumConst 中的
   (*tptr).text[i] = current;
   (*tptr).text[i + 1] = '\0';
   (*tptr).type = TOK_INT_CONST;
   return;      
在处理0a之类的数据时问题,应改为
				(*tptr).text[i] = '0';
				(*tptr).text[i + 1] = '\0';
				(*tptr).type = TOK_INT_CONST;
				(*tptr).val = stringToU8((*tptr).text);
				goBackOneChar();
				return;

   增加了一个 void processComment(struct Token *tptr, char ch); 及相关处理。
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/

#include "linetok.h"

#include "lnscan.h"
#include "exenv.h"
#include "error.h"

static char tokenBuffer[LINE_SIZE];	/*whole line of assembler text*/
static int ntChars;					/*number chars + null char */
static int itChars;					/*index into buffer*/
static struct Line * lineptr;			/*ptr to Line fed to constructor*/

char *TokStr[] = {"TOK_IDENTIFIER", "TOK_INT_REG",    "TOK_FLT_REG",
                  "TOK_DBL_REG",    "TOK_CHAR_CONST", "TOK_INT_CONST",
				  "TOK_FLT_CONST",  "TOK_COMMA",      "TOK_NO_MORE",
				  "TOK_BAD"};

/*called by proces----- functions*/
char getNextLineChar();
void goBackOneChar();
char skipLineWhiteSpace();

/*called by getNextLineToken*/
void processRegister(struct Token *tptr);
void processCharConst(struct Token *tptr);
void processIdentifier(struct Token *tptr, char ch);
void processNumConst(struct Token *tptr, char ch);
void processComment(struct Token *tptr, char ch);

void LineTokenizer_init(struct Line *ln)
{
	LINE_TOK_DEBUG2("LinkeTokenizer(): fed \"%s\" at line (%lu)\n", (*ln).src, (*ln).line);
	lineptr = ln;
	strcpy(tokenBuffer, (*ln).src);
	ntChars = strlen(tokenBuffer) + 1; /*include null char*/
	itChars = -1; 
	return;

}

/*
	Gameplan:  
	
	i) skip white space ( space or tab )
	ii) look at first char ( determines tok type )
			$ = register ( $R1, $F1, $D1 )
			' = char constant ( 'a' )
			a-z, A-Z, @, _, ?, .  = identifier
			0-9, +, - = numeric constant
			, = comma
			'\0' = end of string
	iii) keep reading until
			-hit end of line
			-reach char not belonging to tok type
	iv) populate token attributes and return
*/
struct Token getNextLineToken()
{
	struct Token token;
	char current;
	
	/* still need to set text,type,val/fval*/
	token.line = (*lineptr).line; 
	token.fName = (*lineptr).fName;
	token.val  = 0; 
	token.fval = 0.0; 

	current = skipLineWhiteSpace();

	if (current == '$')
	{ 
		processRegister(&token); 
	}
	else if (current == '#')
	{
		processComment(&token, current);
	}
	else if (current == '\'')
	{ 
		processCharConst(&token); 
	}
	else if ( ((current >= 'a') && (current <= 'z')) ||
		      ((current >= 'A') && (current <= 'Z')) ||
			  (current == '@') ||
			  (current == '_') ||
			  (current == '?') ||
			  (current == '.') )
	{ 
		processIdentifier(&token, current); 
	}
	else if ( ((current >= '0') && (current <= '9')) ||
		      (current == '-') ||
			  (current == '+') )
	{ 
		processNumConst(&token, current); 
	}
	else if (current == ',')
	{
		token.text[0] = current;
		token.text[1] = '\0';
		token.type = TOK_COMMA; 
	}
	else if (current == EOL)
	{
		LINE_TOK_DEBUG2("getNextLineToken(): hit EOL line (%lu) index(%d)\n", token.line, itChars);
		strcpy(token.text, "EOL");
		token.type = TOK_NO_MORE; 
	}
	else
	{
		token.text[0] = current;
		token.text[1] = '\0';
		token.type = TOK_BAD; 
	}

	return token;

}

char skipLineWhiteSpace()
{
	char ch;

	ch = getNextLineChar();
	while ((ch == ' ') || (ch == '\t'))
	{
		ch = getNextLineChar();
	}
	return ch;

}

char getNextLineChar()
{
	itChars++; /* can be in range 0,1, ..., (ntChars-1)*/

	if (itChars >= ntChars - 1)
	{
		return EOL;
	}

	return tokenBuffer[itChars];

}

void processRegister(struct Token *tptr)
{
	char current;
	char peek;

	current = getNextLineChar();
	switch (current)
	{
	/*INT_REGISTER-----------------------------------------*/
	case 'R':
	case 'r':
		current = getNextLineChar();

		switch (current)
		{
		case '1': /* $R1- */
		    peek = getNextLineChar();
			switch (peek)
			{
			case '0':
			    strcpy((*tptr).text, "$R10");
				(*tptr).type = TOK_INT_REG;
				(*tptr).val = $R10;
				break;

			case '1':
			    strcpy((*tptr).text, "$R11");
				(*tptr).type = TOK_INT_REG;
				(*tptr).val = $R11;
				break;

			case '2':
			    strcpy((*tptr).text, "$R12");
				(*tptr).type = TOK_INT_REG;
				(*tptr).val = $R12;
				break;

			case '3':
			    strcpy((*tptr).text, "$R13");
				(*tptr).type = TOK_INT_REG;
				(*tptr).val = $R13;
				break;

			case '4':
			    strcpy((*tptr).text, "$R14");
				(*tptr).type = TOK_INT_REG;
				(*tptr).val = $R14;
				break;

			case '5':
			    strcpy((*tptr).text, "$R15");
				(*tptr).type = TOK_INT_REG;
				(*tptr).val = $R15;
				break;

			case '6':
			    strcpy((*tptr).text, "$R16");
				(*tptr).type = TOK_INT_REG;
				(*tptr).val = $R16;
				break;

			case '7':
			    strcpy((*tptr).text, "$R17");
				(*tptr).type = TOK_INT_REG;
				(*tptr).val = $R17;
				break;

		    case '8':
			    strcpy((*tptr).text, "$R18");
				(*tptr).type = TOK_INT_REG;
				(*tptr).val = $R18;
			    break;

			case '9':
				strcpy((*tptr).text, "$R19");
				(*tptr).type = TOK_INT_REG;
				(*tptr).val = $R19;
				break;

			default:
				strcpy((*tptr).text, "$R1");
				(*tptr).type = TOK_INT_REG;
				(*tptr).val = $R1;
				goBackOneChar();
			}   /*end of $R1 sub-switch*/
			break;
				
		case '2': /* $R2- */
			peek = getNextLineChar();
            switch(peek)
			{
			case '0':
			    strcpy((*tptr).text, "$R20");
				(*tptr).type = TOK_INT_REG;
				(*tptr).val = $R20;
				break;

			case '1':
				strcpy((*tptr).text, "$R21");
				(*tptr).type = TOK_INT_REG;
				(*tptr).val = $R21;
				break;

			case '2':
				strcpy((*tptr).text, "$R22");
				(*tptr).type = TOK_INT_REG;
				(*tptr).val = $R22;
				break;

			case '3':
				strcpy((*tptr).text, "$R23");
				(*tptr).type = TOK_INT_REG;
				(*tptr).val = $R23;
				break;

			case '4':
				strcpy((*tptr).text, "$R24");
				(*tptr).type = TOK_INT_REG;
				(*tptr).val = $R24;
				break;

			default:
				strcpy((*tptr).text, "$R2");
				(*tptr).type = TOK_INT_REG;
				(*tptr).val = $R2;
				goBackOneChar();
			}
			break;
				
		case '3':
			strcpy((*tptr).text, "$R3");
			(*tptr).type = TOK_INT_REG;
			(*tptr).val = $R3;
			break;

		case '4':
			strcpy((*tptr).text, "$R4");
			(*tptr).type = TOK_INT_REG;
			(*tptr).val = $R4;
			break;

		case '5':
			strcpy((*tptr).text, "$R5");
			(*tptr).type = TOK_INT_REG;
			(*tptr).val = $R5;
			break;

		case '6':
			strcpy((*tptr).text, "$R6");
			(*tptr).type = TOK_INT_REG;
			(*tptr).val = $R6;
			break;

		case '7':
			strcpy((*tptr).text, "$R7");
			(*tptr).type = TOK_INT_REG;
			(*tptr).val = $R7;
			break;

		case '8':
			strcpy((*tptr).text, "$R8");
			(*tptr).type = TOK_INT_REG;
			(*tptr).val = $R8;
			break;
				
		case '9':
			strcpy((*tptr).text, "$R9");
			(*tptr).type = TOK_INT_REG;
			(*tptr).val = $R9;
			break;
				
		default: /*does not start with 0-9*/
			(*tptr).text[0] = '$';
			(*tptr).text[1] = 'R';
			(*tptr).text[2] = current;
			(*tptr).text[3] = '\0';
			(*tptr).type = TOK_BAD; 
		}
		break;
		
	/*FLT_REGISTER-----------------------------------------*/
	case 'F':
	case 'f':
		current = getNextLineChar();
        switch (current)
		{
		case '1':
		    current = getNextLineChar();
            if (current == '0')
			{
			    strcpy((*tptr).text, "$F10");
				(*tptr).type = TOK_FLT_REG;
				(*tptr).val = $F10;
			}
			else
			{
			    strcpy((*tptr).text, "$F1");
				(*tptr).type = TOK_FLT_REG;
				(*tptr).val = $F1;
				goBackOneChar();
			}
			break;
		
		case '2':
			strcpy((*tptr).text, "$F2");
			(*tptr).type = TOK_FLT_REG;
			(*tptr).val = $F2;
			break;
				
		case '3':
			strcpy((*tptr).text, "$F3");
			(*tptr).type = TOK_FLT_REG;
			(*tptr).val = $F3;
			break;
				
		case '4':
			strcpy((*tptr).text, "$F4");
			(*tptr).type = TOK_FLT_REG;
			(*tptr).val = $F4;
			break;
				
		case '5':
			strcpy((*tptr).text, "$F5");
			(*tptr).type = TOK_FLT_REG;
			(*tptr).val = $F5;
			break;
				
		case '6':
			strcpy((*tptr).text, "$F6");
			(*tptr).type = TOK_FLT_REG;
			(*tptr).val = $F6;
			break;
				
		case '7':
			strcpy((*tptr).text, "$F7");
			(*tptr).type = TOK_FLT_REG;
			(*tptr).val = $F7;
			break;
				
		case '8':
			strcpy((*tptr).text, "$F8");
			(*tptr).type = TOK_FLT_REG;
			(*tptr).val = $F8;
			break;
				
		case '9':
			strcpy((*tptr).text, "$F9");
			(*tptr).type = TOK_FLT_REG;
			(*tptr).val = $F9;
			break;
				
		case 'P':
		case 'p':
			strcpy((*tptr).text, "$FP");
			(*tptr).type = TOK_INT_REG;
			(*tptr).val = $FP;
			break;
				
		default: /* not 0-9*/
			(*tptr).text[0] = '$';
			(*tptr).text[1] = 'F';
			(*tptr).text[2] = current;
			(*tptr).text[3] = '\0';
			(*tptr).type = TOK_BAD;
		}
		break;
	
	/*DBL_REGISTER-----------------------------------------*/
	case 'D':
	case 'd':
		current = getNextLineChar();
        switch(current)
		{
		case '1':
		    current = getNextLineChar();
            if (current == '0')
			{
				strcpy((*tptr).text, "$D10");
				(*tptr).type = TOK_DBL_REG;
				(*tptr).val = $D10;
			}
			else
			{
			    strcpy((*tptr).text, "$D1");
				(*tptr).type = TOK_DBL_REG;
				(*tptr).val = $D1;
				goBackOneChar();
			}
			break;
				
		case '2':
			strcpy((*tptr).text, "$D2");
			(*tptr).type = TOK_DBL_REG;
			(*tptr).val = $D2;
			break;
				
		case '3':
			strcpy((*tptr).text, "$D3");
			(*tptr).type = TOK_DBL_REG;
			(*tptr).val = $D3;
			break;
				
		case '4':
			strcpy((*tptr).text, "$D4");
			(*tptr).type = TOK_DBL_REG;
			(*tptr).val = $D4;
			break;
				
		case '5':
			strcpy((*tptr).text, "$D5");
			(*tptr).type = TOK_DBL_REG;
			(*tptr).val = $D5;
			break;
				
		case '6':
			strcpy((*tptr).text, "$D6");
			(*tptr).type = TOK_DBL_REG;
			(*tptr).val = $D6;
			break;
				
		case '7':
			strcpy((*tptr).text, "$D7");
			(*tptr).type = TOK_DBL_REG;
			(*tptr).val = $D7;
			break;
				
		case '8':
			strcpy((*tptr).text, "$D8");
			(*tptr).type = TOK_DBL_REG;
			(*tptr).val = $D8;

⌨️ 快捷键说明

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