Пример #1
0
/* IdentifierToken - get an identifier */
static int IdentifierToken(ParseContext *c, int ch)
{
    int len, i;
    char *p;

    /* get the identifier */
    p = c->token;
    *p++ = ch;
    len = 1;
    while ((ch = GetChar(c)) != EOF && IdentifierCharP(ch)) {
        if (++len > MAXTOKEN)
            ParseError(c, "Identifier too long");
        *p++ = ch;
    }
    UngetC(c);
    *p = '\0';

    /* check to see if it is a keyword */
    for (i = 0; ktab[i].keyword != NULL; ++i)
        if (strcasecmp(ktab[i].keyword, c->token) == 0)
            return ktab[i].token;

    /* otherwise, it is an identifier */
    return T_IDENTIFIER;
}
Пример #2
0
/* GetChar - get the next character */
int GetChar(ParseContext *c)
{
    int ch;

    /* check for being in a comment */
    if (c->inComment) {
        if (!SkipComment(c))
            return EOF;
        c->inComment = VMFALSE;
    }

    /* loop until we find a non-comment character */
    for (;;) {

        /* get the next character */
        if ((ch = XGetC(c)) == EOF)
            return EOF;

        /* check for a comment */
        else if (ch == '/') {
            if ((ch = XGetC(c)) == '/') {
                while ((ch = XGetC(c)) != EOF)
                    ;
            }
            else if (ch == '*') {
                if (!SkipComment(c)) {
                    c->inComment = VMTRUE;
                    return EOF;
                }
            }
            else {
                UngetC(c);
                ch = '/';
                break;
            }
        }

        /* handle a normal character */
        else
            break;
    }

    /* return the character */
    return ch;
}
Пример #3
0
/* BinaryNumberToken - get a binary number */
static int BinaryNumberToken(ParseContext *c)
{
    char *p = c->token;
    int ch;

    /* get the number */
    while ((ch = GetChar(c)) != EOF) {
        if (ch == '0' || ch == '1')
            *p++ = ch;
        else if (ch != '_')
            break;
    }
    UngetC(c);
    *p = '\0';

    /* convert the string to an integer */
    c->value = (VMVALUE)strtoul(c->token, NULL, 2);

    /* return the token */
    return T_NUMBER;
}
Пример #4
0
/* NumberToken - get a number */
static int NumberToken(ParseContext *c, int ch)
{
    char *p = c->token;

    /* get the number */
    *p++ = ch;
    while ((ch = GetChar(c)) != EOF) {
        if (isdigit(ch))
            *p++ = ch;
        else if (ch != '_')
            break;
    }
    UngetC(c);
    *p = '\0';

    /* convert the string to an integer */
    c->value = (VMVALUE)atol(c->token);

    /* return the token */
    return T_NUMBER;
}
Пример #5
0
/* NextToken - read the next token */
static int NextToken(ParseContext *c)
{
    int ch, tkn;

    /* skip leading blanks */
    ch = SkipSpaces(c);

    /* remember the start of the current token */
    c->tokenOffset = (int)(c->sys->linePtr - c->sys->lineBuf);

    /* check the next character */
    switch (ch) {
    case EOF:
        tkn = T_EOL;
        break;
    case '"':
        tkn = StringToken(c);
        break;
    case '\'':
        tkn = CharToken(c);
        break;
    case '<':
        if ((ch = GetChar(c)) == '=')
            tkn = T_LE;
        else if (ch == '>')
            tkn = T_NE;
        else if (ch == '<')
            tkn = T_SHL;
        else {
            UngetC(c);
            tkn = '<';
        }
        break;
    case '>':
        if ((ch = GetChar(c)) == '=')
            tkn = T_GE;
        else if (ch == '>')
            tkn = T_SHR;
        else {
            UngetC(c);
            tkn = '>';
        }
        break;
    case '0':
        switch (GetChar(c)) {
        case 'x':
        case 'X':
            tkn = HexNumberToken(c);
            break;
        case 'b':
        case 'B':
            tkn = BinaryNumberToken(c);
            break;
        default:
            UngetC(c);
            tkn = NumberToken(c, '0');
            break;
        }
        break;
    default:
        if (isdigit(ch))
            tkn = NumberToken(c, ch);
        else if (IdentifierCharP(ch)) {
            char *savePtr;
            switch (tkn = IdentifierToken(c,ch)) {
            case T_ELSE:
                savePtr = c->sys->linePtr;
                if ((ch = SkipSpaces(c)) != EOF && IdentifierCharP(ch)) {
                    switch (IdentifierToken(c, ch)) {
                    case T_IF:
                        tkn = T_ELSE_IF;
                        break;
                    default:
                        c->sys->linePtr = savePtr;
                        break;
                    }
                }
                else
                    c->sys->linePtr = savePtr;
                break;
            case T_END:
                savePtr = c->sys->linePtr;
                if ((ch = SkipSpaces(c)) != EOF && IdentifierCharP(ch)) {
                    switch (IdentifierToken(c, ch)) {
                    case T_DEF:
                        tkn = T_END_DEF;
                        break;
                    case T_IF:
                        tkn = T_END_IF;
                        break;
                    default:
                        c->sys->linePtr = savePtr;
                        break;
                    }
                }
                else
                    c->sys->linePtr = savePtr;
                break;
            case T_DO:
                savePtr = c->sys->linePtr;
                if ((ch = SkipSpaces(c)) != EOF && IdentifierCharP(ch)) {
                    switch (IdentifierToken(c, ch)) {
                    case T_WHILE:
                        tkn = T_DO_WHILE;
                        break;
                    case T_UNTIL:
                        tkn = T_DO_UNTIL;
                        break;
                    default:
                        c->sys->linePtr = savePtr;
                        break;
                    }
                }
                else
                    c->sys->linePtr = savePtr;
                break;
            case T_LOOP:
                savePtr = c->sys->linePtr;
                if ((ch = SkipSpaces(c)) != EOF && IdentifierCharP(ch)) {
                    switch (IdentifierToken(c, ch)) {
                    case T_WHILE:
                        tkn = T_LOOP_WHILE;
                        break;
                    case T_UNTIL:
                        tkn = T_LOOP_UNTIL;
                        break;
                    default:
                        c->sys->linePtr = savePtr;
                        break;
                    }
                }
                else
                    c->sys->linePtr = savePtr;
                break;
            }
        }
        else
            tkn = ch;
    }

    /* return the token */
    return tkn;
}
Пример #6
0
int Lex::SubGetToken(void)
{
	int c, n;

	for(;;) {
		f_stoken = f_input;

		c = GetC();
		switch(c) {
		case 0:
			return 0;

		case '0':
			c = GetC();
			if(c == 'x' && c == 'X') {
				do {
					c = GetC();
				} while((c >= '0' && c <= '9')
					|| (c >= 'a' && c <= 'f')
					|| (c >= 'A' && c <= 'F'));
				return NUMBER;
			}
			// here we could test for octal, but it doesn't
			// matter too much here, we're not a compiler!
			UngetC();
		case '1':
		case '2':
		case '3':
		case '4':
		case '5':
		case '6':
		case '7':
		case '8':
		case '9':
			do {
				c = GetC();
			} while(c >= '0' && c <= '9');
			if(c == 'U' || c == 'u') {
				c = GetC();
				if(c == 'L' || c == 'l') {
					c = GetC();
					if(c != 'L' && c != 'l') {
						UngetC();
					}
					return NUMBER;
				}
				// a U by itself is ignored
				UngetC();
				return NUMBER;
			}
			if(c == 'L' || c == 'l') {
				c = GetC();
				if(c != 'L' && c != 'l') {
					UngetC();
				}
				return NUMBER;
			}
			if(c == '.') {
				do {
					c = GetC();
				} while(c >= '0' && c <= '9');
			}
			if(c == 'e' || c == 'E') {
				c = GetC();
				if(c == '-' || c == '+') {
					c = GetC();
				}
				while(c >= '0' && c <= '9') {
					c = GetC();
				}
			}
			if(c == 'f' || c == 'F') {
				return NUMBER;
			}
			UngetC();
			return NUMBER;

		case '\'':
character:
			c = GetC();
			if(c == '\\') {
				c = GetC();
			}
			c = GetC();
			if(c != '\'') {
				fprintf(stderr, "%s:%ld: error: invalid character\n", f_filename, f_line);
				g_errcnt++;
			}
			return CHARACTER;

		case '"':
string:
			do {
				c = GetC();
				if(c == '\n' || c == '\0') {
					fprintf(stderr, "%s:%ld: error: unterminated string\n", f_filename, f_line);
					g_errcnt++;
					break;
				}
				if(c == '\\') {
					c = GetC();
					if(c == '\n' || c == '\0') {
						fprintf(stderr, "%s:%ld: error: unterminated string\n", f_filename, f_line);
						g_errcnt++;
						break;
					}
					c = '\0';
				}
			} while(c != '"');
			return STRING;

		case 'l':
		case 'L':
			c = GetC();
			if(c == '"') {
				goto string;
			}
			if(c == '\'') {
				goto character;
			}

		// comments are very simply ignored
		case '/':
			n = GetC();
			if(n == '/') {
				do {
					c = GetC();
				} while(c != '\n' && c != '\0');
				break;
			}
			if(n == '*') {
				n = GetC();
				do {
					c = n;
					n = GetC();
				} while(n != '\0' && (c != '*' || n != '/'));
				break;
			}
			UngetC();
			return c;

		default:
			if( isalpha(c) || (c=='_') || (c==':') )
			{
				do {
					c = GetC();
				} while((c >= 'a' && c <= 'z')
					|| (c >= 'A' && c <= 'Z')
					|| (c >= '0' && c <= '9')
					|| c == '_' || c == ':');
				UngetC();
				return IDENTIFIER;
			}
			else
			{
				return c;
			}

		}
	}
}
Пример #7
0
/* ParseStatement - parse a statement */
void ParseStatement(ParseContext *c, Token tkn)
{
    /* dispatch on the statement keyword */
    switch (tkn) {
    case T_REM:
        /* just a comment so ignore the rest of the line */
        break;
    case T_DEF:
        ParseDef(c);
        break;
    case T_END_DEF:
        ParseEndDef(c);
        break;
    case T_DIM:
        ParseDim(c);
        break;
    case T_LET:
        ParseLet(c);
        break;
    case T_IF:
        ParseIf(c);
        break;
    case T_ELSE:
        ParseElse(c);
        break;
    case T_ELSE_IF:
        ParseElseIf(c);
        break;
    case T_END_IF:
        ParseEndIf(c);
        break;
    case T_END:
        ParseEnd(c);
        break;
    case T_FOR:
        ParseFor(c);
        break;
    case T_NEXT:
        ParseNext(c);
        break;
    case T_DO:
        ParseDo(c);
        break;
    case T_DO_WHILE:
        ParseDoWhile(c);
        break;
    case T_DO_UNTIL:
        ParseDoUntil(c);
        break;
    case T_LOOP:
        ParseLoop(c);
        break;
    case T_LOOP_WHILE:
        ParseLoopWhile(c);
        break;
    case T_LOOP_UNTIL:
        ParseLoopUntil(c);
        break;
    case T_STOP:
        ParseStop(c);
        break;
    case T_GOTO:
        ParseGoto(c);
        break;
    case T_RETURN:
        ParseReturn(c);
        break;
    case T_PRINT:
        ParsePrint(c);
        break;
    case T_IDENTIFIER:
        if (SkipSpaces(c) == ':') {
            DefineLabel(c, c->token, codeaddr(c));
            break;
        }
        UngetC(c);
    default:
        SaveToken(c, tkn);
        ParseImpliedLetOrFunctionCall(c);
        break;
    }
}