Exemplo n.º 1
0
static int read_statement(Tokenizer *tokz, Token *tokens, int *ntok_ret)
{
	int ntokens=0;
	Token *tok=NULL;
	int had_comma=0; /* 0 - no, 1 - yes, 2 - not had, not expected */
	int retval=0;
	int e=0;

	while(1){
		tok=&tokens[ntokens];
		
		if(!tokz_get_token(tokz, tok)){
			e=1;
			continue;
		}

		if(ntokens==MAX_TOKENS-1){
			e=E_TOKZ_TOKEN_LIMIT;
			tokz_warn_error(tokz, tok->line, e);
			if(!(tokz->flags&TOKZ_ERROR_TOLERANT))
				break;
		}else{
			ntokens++;
		}
		
		if(!TOK_IS_OP(tok)){
			if(ntokens==1 && !had_comma){
				/* first token */
				had_comma=2;
			}else{
				if(had_comma==0)
					goto syntax;
			
				had_comma=0;
			}
			continue;
		}
		
		/* It is an operator */
		ntokens--;
		
		switch(TOK_OP_VAL(tok)){
		case OP_SCOLON:
			retval=(ntokens==0 ? P_NONE : P_STMT_NS);
			break;
			
		case OP_NEXTLINE:
			retval=(ntokens==0 ? P_NONE : P_STMT);
			break;
			
		case OP_L_BRC:
			retval=(ntokens==0 ? P_BEG_SECT : P_STMT_SECT);
			break;
			
		case OP_R_BRC:
			if(ntokens==0){
				retval=P_END_SECT;
			}else{
				tokz_unget_token(tokz, tok);
				retval=P_STMT_NS;
			}
			break;

		case OP_EOF:
			retval=(ntokens==0 ? P_EOF : P_STMT_NS);
			
			if(had_comma==1){
				e=E_TOKZ_UNEXPECTED_EOF;
				goto handle_error;
			}
			
			goto end;
			
		case OP_COMMA:
			if(had_comma!=0)
				goto syntax;

			had_comma=1;
			continue;
			
		default:
			goto syntax;
		}
		
		if(had_comma!=1)
			break;
		
	syntax:
		e=E_TOKZ_SYNTAX;
	handle_error:
		tokz_warn_error(tokz, tok->line, e);
		
		if(!(tokz->flags&TOKZ_ERROR_TOLERANT) || retval!=0)
			break;
	}
	
end:
	if(e!=0)
		retval=-retval;
	
	*ntok_ret=ntokens;
	
	return retval;
}
Exemplo n.º 2
0
bool tokz_get_token(Tokenizer *tokz, Token *tok)
{
    int c, c2, e;
    
    if (!(tokz->flags&TOKZ_READ_FROM_BUFFER))
    assert(tokz->file!=NULL);
    
    tok_free(tok);
    
    if(!TOK_IS_INVALID(&(tokz->ungettok))){
        *tok=tokz->ungettok;
        tokz->ungettok.type=TOK_INVALID;
        return TRUE;
    }

    while(1){
    
        e=0;
        
        do{
            c=GETCH();
        }while(c!='\n' && c!=EOF && isspace(c));
    
        tok->line=tokz->line;
    
        switch(c){
        case EOF:
            TOK_SET_OP(tok, OP_EOF);
            return TRUE;
            
        case '\n':
            INC_LINE();
            
            if(tokz->flags&TOKZ_IGNORE_NEXTLINE)
                continue;
            
            TOK_SET_OP(tok, OP_NEXTLINE);
            
            return TRUE;
            
        case '\\':
            do{
                c=GETCH();
                if(c==EOF){
                    TOK_SET_OP(tok, OP_EOF);
                    return FALSE;
                }
                if(!isspace(c) && e==0){
                    e=E_TOKZ_EOL_EXPECTED;
                    tokz_warn_error(tokz, tokz->line, e);
                    if(!(tokz->flags&TOKZ_ERROR_TOLERANT))
                        return FALSE;
                }
            }while(c!='\n');
            
            INC_LINE();
            continue;

        case '#':
            if(tokz->flags&TOKZ_READ_COMMENTS){
                e=scan_line_comment(tok, tokz);
                break;
            }else if((e=skip_line_comment(tokz))){
                break;
            }
            
            continue;
            
        case '/':
            c2=GETCH();
            
            if(c2=='='){
                TOK_SET_OP(tok, OP_AS_DIV);
                return TRUE;
            }
            
            if(c2!='*'){
                UNGETCH(c2);
                TOK_SET_OP(tok, OP_DIV);
                return TRUE;
            }
            
            if(tokz->flags&TOKZ_READ_COMMENTS){
                e=scan_c_comment(tok, tokz);
                break;
            }else if((e=skip_c_comment(tokz))){
                break;
            }
            
            continue;
            
        case '\"':
            e=scan_string(tok, tokz, TRUE);
            break;

        case '\'':
            e=scan_char(tok, tokz);
            break;

        default: 
            if(('0'<=c && c<='9') || c=='-' || c=='+'){
                e=scan_number(tok, tokz, c);
                break;
            }

             if(START_IDENT(c))
                e=scan_identifier(tok, tokz, c);
            else
                e=scan_op(tok, tokz, c);
        }
        
        if(!e)
            return TRUE;
        
        tokz_warn_error(tokz, tokz->line, e);
        return FALSE;
    }
}