void LX_Fetch (void)
{
	int		c;

	pr_tokenclass = TK_NONE;

	pr_token[0] = 0;

	if (!pr_file_p)
	{
		pr_token_type = tt_eof;
		return;
	}

	LexWhitespace();

	c = *pr_file_p;

	switch (ASCIIToChrCode[c])
	{
	case CHR_LETTER:
		LexName();
		return;
	case CHR_NUMBER:
		pr_token_type = tt_immediate;
		pr_immediate_type = &type_float;
		pr_immediate._float = LexNumber();
		return;
	case CHR_DQUOTE:
		LexString();
		return;
	case CHR_SQUOTE:
		LexVector();
		return;
	case CHR_DOLLARSIGN:
		LexGrab();
		return;
	case CHR_EOF:
		pr_token_type = tt_eof;
		return;
	case CHR_SPECIAL:
	default:
		LexPunctuation();
		return;
	}
}
static void LexVector (void)
{
	int		i;

	pr_file_p++;
	pr_token_type = tt_immediate;
	pr_immediate_type = &type_vector;
	for (i = 0; i < 3; i++)
	{
		LexWhitespace();
		pr_immediate.vector[i] = LexNumber();
	}
	LexWhitespace();
	if (*pr_file_p != '\'')
	{
		PR_ParseError("bad vector");
	}
	pr_file_p++;
}
	////////////////////////////////////////////////////////////////////////////////
	// NextToken: Scan the input and construct the next token.
	// Inputs:
	//
	// Return Value:
	//	ExprToken		The next token.  Type will be Token::Eof on end-of-file,
	//					or Token::Error if a syntax error was encountered.
	////////////////////////////////////////////////////////////////////////////////
	RegularExprToken RegularExprLexer::NextToken()
	{
		// Skip whitespace 
		while (isspace(current)) {
			Skip();
		}

		// Remember the starting position
		int startLine = line;
		int startColumn = column;

		// Clear out the token
		tokenText.erase();

		RegularExprToken::Type type = RegularExprToken::Error;

		try {
			switch (current) {
			case 0:
				type = RegularExprToken::Eof;
				break;
			case '-':
				type = RegularExprToken::Dash;
				Consume();
				break;
			case '.':
				type = RegularExprToken::Wildcard;
				Consume();
				break;
			case '[':
				type = RegularExprToken::LeftBracket;
				Consume();
				break;
			case ']':
				type = RegularExprToken::RightBracket;
				Consume();
				break;
			case '^':
				type = RegularExprToken::Caret;
				Consume();
				break;
			case '(':
				type = RegularExprToken::LeftParen;
				Consume();
				break;
			case ')':
				type = RegularExprToken::RightParen;
				Consume();
				break;
			case '?':
				type = RegularExprToken::Optional;
				Consume();
				break;
			case '|':
				type = RegularExprToken::Or;
				Consume();
				break;
			case '*':
				type = RegularExprToken::Star;
				Consume();
				break;
			case '+':
				type = RegularExprToken::Plus;
				Consume();
				break;
			case '{':
				type = RegularExprToken::LeftBrace;
				Consume();
				break;
			case '}':
				type = RegularExprToken::RightBrace;
				Consume();
				break;
			case ',':
				type = RegularExprToken::Comma;
				Consume();
				break;
			case '=':
				type = RegularExprToken::Equal;
				Consume();
				break;
			default:
				if (ISDIGIT(current)) {
					type = LexNumber();
				} else {
					type = LexOther();
				}
				break;
			}
		} catch (int) {
			// Don't get stuck on an error token
			NextChar();
		}
		return RegularExprToken(type, tokenText, startLine, startColumn);
	}
static void LexPunctuation (void)
{
	pr_token_type = tt_punct;
	*(int *)pr_token = 0;
	*pr_token = *pr_file_p;
	switch (*pr_file_p++)
	{
	case ';':
		pr_tokenclass = TK_SEMICOLON;
		return;
	case '(':
		if (*pr_file_p == '+' && pr_file_p[1] == ')')
		{
			pr_token[1] = *pr_file_p++;
			pr_token[2] = *pr_file_p++;
			pr_tokenclass = TK_BITSET;
			return;
		}
		if (*pr_file_p == '-' && pr_file_p[1] == ')')
		{
			pr_token[1] = *pr_file_p++;
			pr_token[2] = *pr_file_p++;
			pr_tokenclass = TK_BITCLR;
			return;
		}
		pr_tokenclass = TK_LPAREN;
		return;
	case ')':
		pr_tokenclass = TK_RPAREN;
		return;
	case ',':
		pr_tokenclass = TK_COMMA;
		return;
	case '+':
		if (*pr_file_p == '=')
		{
			pr_token[1] = *pr_file_p++;
			pr_tokenclass = TK_ADDASSIGN;
			return;
		}
		if (*pr_file_p == '+')
		{
			pr_token[1] = *pr_file_p++;
			pr_tokenclass = TK_INC;
			return;
		}
		pr_tokenclass = TK_PLUS;
		return;
	case '*':
		if (*pr_file_p == '=')
		{
			pr_token[1] = *pr_file_p++;
			pr_tokenclass = TK_MULASSIGN;
			return;
		}
		pr_tokenclass = TK_ASTERISK;
		return;
	case '/':
		if (*pr_file_p == '=')
		{
			pr_token[1] = *pr_file_p++;
			pr_tokenclass = TK_DIVASSIGN;
			return;
		}
		pr_tokenclass = TK_SLASH;
		return;
	case '{':
		pr_bracelevel++;
		pr_tokenclass = TK_LBRACE;
		return;
	case '}':
		pr_bracelevel--;
		pr_tokenclass = TK_RBRACE;
		return;
	case '[':
		pr_tokenclass = TK_LBRACKET;
		return;
	case ']':
		pr_tokenclass = TK_RBRACKET;
		return;
	case ':':
		pr_tokenclass = TK_COLON;
		return;
	case '#':
		pr_tokenclass = TK_NUMBERSIGN;
		return;
	case '=':
		if (*pr_file_p == '=')
		{
			pr_token[1] = *pr_file_p++;
			pr_tokenclass = TK_EQ;
			return;
		}
		pr_tokenclass = TK_ASSIGN;
		return;
	case '&':
		if (*pr_file_p == '&')
		{
			pr_token[1] = *pr_file_p++;
			pr_tokenclass = TK_AND;
			return;
		}
		pr_tokenclass = TK_BITAND;
		return;
	case '|':
		if (*pr_file_p == '|')
		{
			pr_token[1] = *pr_file_p++;
			pr_tokenclass = TK_OR;
			return;
		}
		pr_tokenclass = TK_BITOR;
		return;
	case '!':
		if (*pr_file_p == '=')
		{
			pr_token[1] = *pr_file_p++;
			pr_tokenclass = TK_NE;
			return;
		}
		pr_tokenclass = TK_NOT;
		return;
	case '>':
		if (*pr_file_p == '=')
		{
			pr_token[1] = *pr_file_p++;
			pr_tokenclass = TK_GE;
			return;
		}
		pr_tokenclass = TK_GT;
		return;
	case '<':
		if (*pr_file_p == '=')
		{
			pr_token[1] = *pr_file_p++;
			pr_tokenclass = TK_LE;
			return;
		}
		pr_tokenclass = TK_LT;
		return;
	case '.':
		if (ASCIIToChrCode[*pr_file_p] == CHR_NUMBER)
		{
			pr_file_p--;
			pr_token_type = tt_immediate;
			pr_immediate_type = &type_float;
			pr_immediate._float = LexNumber();
			return;
		}
		if (*pr_file_p == '.')
		{
			if (pr_file_p[1] == '.')
			{
				pr_token[1] = *pr_file_p++;
				pr_token[2] = *pr_file_p++;
				pr_tokenclass = TK_ELLIPSIS;
				return;
			}
			else
			{
				pr_token[1] = *pr_file_p++;
				pr_tokenclass = TK_RANGE;
				return;
			}
		}
		pr_tokenclass = TK_PERIOD;
		return;
	case '-':
		if (*pr_file_p == '=')
		{
			pr_token[1] = *pr_file_p++;
			pr_tokenclass = TK_SUBASSIGN;
			return;
		}
		if (*pr_file_p == '-')
		{
			pr_token[1] = *pr_file_p++;
			pr_tokenclass = TK_DEC;
			return;
		}
		if (ASCIIToChrCode[*pr_file_p] == CHR_NUMBER)
		{
			pr_file_p--;
			pr_token_type = tt_immediate;
			pr_immediate_type = &type_float;
			pr_immediate._float = LexNumber();
			return;
		}
		pr_tokenclass = TK_MINUS;
		return;
	default:
		PR_ParseError("unknown punctuation");
	}
}