Beispiel #1
0
/* 'cmdLine' contains one or several arguments. Each argument can be:
 - escaped, in which case it starts with '"', ends with '"' and
   each '"' that is part of the name is escaped with '\\'
 - unescaped, in which case it start with != '"' and ends with ' ' or '\0'
*/
void ParseCmdLine(const WCHAR *cmdLine, WStrVec& out)
{
    while (cmdLine) {
        while (str::IsWs(*cmdLine))
            cmdLine++;
        if ('"' == *cmdLine)
            cmdLine = ParseQuoted(cmdLine, &out);
        else if ('\0' != *cmdLine)
            cmdLine = ParseUnquoted(cmdLine, &out);
        else
            cmdLine = NULL;
    }
}
/*
================
Lexer::ReadToken
================
*/
const Token *Lexer::ReadToken( void ) {
	if ( tokPos == -1 )
		tokPos = 0;
	else if ( tokIsUnread ) {
		tokIsUnread = false;
		return &token;
	}
	while ( bufPos < bufSize ) {
		// Single line comments
		if ( !lineComment.IsEmpty() &&
			String::CmpPrefix((const char *)(buffer+bufPos), lineComment.c_str()) == 0 ) {
			if ( !(flags & LEXER_FULL_LINES) && tokPos > 0 ) {
				FinishToken();
				return &token;
			}
			bufPos += 2;
			if ( tokPos > 0 ) {
				SkipRestOfLine();
				return &token;
			}
			SkipRestOfLine();

			continue;
		}
		// Multiline comments
		else if ( !blockComment[0].IsEmpty() &&
			String::CmpPrefix((const char *)(buffer+bufPos), blockComment[0].c_str()) == 0 ) {
				if ( !(flags & LEXER_FULL_LINES) && tokPos > 0 ) {
					FinishToken();
					return &token;
				}
				bufPos += 2;
				int l = line;
				SkipToCommentEnd(); 
				// If changed line during comment, finish the line.
				if ( (flags & LEXER_FULL_LINES) && l != line && tokPos > 0 ) {
					FinishToken();
					return &token;
				}
				continue;
		}

		switch( buffer[bufPos] ) {
			// Ignore whitespaces
			case ' ':
			case '\t':
				SkipWhiteSpaces();
				if ( flags & LEXER_FULL_LINES )
					AddToToken( ' ' );
				else if ( tokPos > 0 ) {
					FinishToken();
					return &token;
				}
				continue;

			// Newlines
			case '\n':
			case '\r':
				if ( !tokPos ) {
					FinishLine();
					continue;
				}
				FinishLine();
				return &token;

			// Quoted tokens
			case '\"':
			case '\'':
				if ( flags & LEXER_FULL_LINES ) {
					ParseQuoted();
					continue;
				}
				if ( tokPos > 0 ) {
					FinishToken();
					return &token;
				}
				ParseQuoted();
				return &token;

			default:
				// Check for single char tokens
				if ( (flags & LEXER_FULL_LINES) == 0 && !singleTokenChars.IsEmpty() ) {
					char c = buffer[bufPos];
					const char *chars = singleTokenChars.c_str();
					int num = singleTokenChars.Length();
					for( int i=0; i<num; i++ ) {
						if ( c != chars[i] )
							continue;
						if ( tokPos == 0 ) {
							AddToToken( buffer[bufPos] );
							bufPos++;
						}
						FinishToken();
						return &token;
					}
				}
				// Add this char to the token
				AddToToken( buffer[bufPos] );
				bufPos++;
				continue;
		}
	}
	if ( tokPos > 0 ) {
		FinishToken();
		return &token;
	}
	line = 0;

	return NULL;
}
Beispiel #3
0
/* Parse the next expression */
VyParseTree* Parse(){
	/* Check that we have not reached the end of the input stream; if so, return null */
	if(!MoreTokensExist()){
		return NULL;	
	}


	/* Get the next token */
	VyToken* next = GetNextToken();

	/* It's type is used to determine how to continue parsing */
	int tokType = next->type;

	/* Store the result of parsing before returning it */
	VyParseTree* expr;

	/* If it starts with a parenthesis, parse it as a list */
	if(tokType == OPAREN){
		expr =  ParseList();
	}

	/* If it begins with a quote, then parse whatever is next and quote it */
	else if(tokType == QUOTE){
		expr = ParseQuoted();
	}

	/* Parse a substitution */
	else if(tokType == DOLLAR){
		expr = ParseSubstitution();
	}
	/* Parse a splicing substitution */
	else if(tokType == DOLLARAT){
		expr = ParseSpliceSubstitution();	
	}

	/* Parse a bracketed list */
	else if(tokType == OBRACKET){
		expr = ParseBracketedList();
	}

	/* Parse an infix list (curly braces) */
	else if(tokType == OCURLY){
		expr = ParseCurlyList();	
	}
	/* If it is a number, identifier, or string then make a parse tree out of the token */
	else if(tokType == IDENT){
		VyParseTree* ident = MakeIdent();
		SetStrData(ident, next->data);
		expr = ident;
	}
	else if(tokType == NUM){
		expr = ParseNumberFromToken(next);
	}
	else if(tokType == STRING){
		VyParseTree* str = MakeString();
		SetStrData(str,next->data);
		expr = str;
	}
	/* Unexpected end of list */
	else if(tokType == CPAREN || tokType == CBRACKET || tokType == CCURLY){
		VyParseTree* err = ParseError("Unexpected end of list");
		SetPosition(err, next->pos);
		return err;
	}

	/* If there is no expression before a :, then the token type will be COLON
	 * Instead of dying, add an error */
	else if(tokType == COLON){
		VyParseTree* error = ParseError("Reference lacking instance");
		SetPosition(error, next->pos);  
		return error;
	}

	/* Handle object references: Check whether the next token is a colon.
	 * If so, then use the previously parsed expression (expr) and another
	 * expression  gotten from Parse() to create a reference node */
	VyToken* lookAhead = GetNextToken();
	if(lookAhead != NULL /* Make sure that the token list didn't end before looking at the type */
			&& lookAhead->type == COLON){ 
		VyParseTree* obj = expr;

		VyParseTree* ref = Parse();

		/* Check for validity */
		if(ref == NULL){
			expr = Reference(obj, ParseError("Incomplete reference."));  
		}else{
			expr = Reference(obj, ref);
		}
	}
	else{
		/* Backtrack one token to make up for the lookahead */
		if(lookAhead != NULL) BacktrackToken();
	}   

	/* Set the position of the current expression */
	SetPosition(expr, next->pos);

	/* If the tree is an object reference, set the position of 
	 * the first part (obj), because it wasn't gotten through a full Parse() call*/
	if(expr->type == TREE_REF){
		SetPosition(GetObj(expr), next->pos);
	}

	return expr;
}