| 1 | cycrow | 1 | #include "bod_parser_base.h"
 | 
        
           |  |  | 2 | #include "../common/strutils.h"
 | 
        
           |  |  | 3 | #include "../common/string_builder.h"
 | 
        
           |  |  | 4 |   | 
        
           |  |  | 5 | #include <stdarg.h>
 | 
        
           |  |  | 6 | #include <stdlib.h>
 | 
        
           |  |  | 7 | #include <stdio.h>
 | 
        
           |  |  | 8 | //---------------------------------------------------------------------------------
 | 
        
           |  |  | 9 | void bod_parser_base::error(const bod_text_parser::token *t, ErrorSeverity severity, const char *format, ...)
 | 
        
           |  |  | 10 | {
 | 
        
           |  |  | 11 | 	va_list ap;
 | 
        
           |  |  | 12 | 	va_start(ap, format);
 | 
        
           |  |  | 13 |   | 
        
           |  |  | 14 | 	Error *e=new Error();
 | 
        
           |  |  | 15 | 	e->makeCode(F_Compiler, severity, E_Error);
 | 
        
           |  |  | 16 | 	if(t){
 | 
        
           |  |  | 17 | 		e->line=t->line;
 | 
        
           |  |  | 18 | 		e->col=t->col;
 | 
        
           |  |  | 19 | 	}
 | 
        
           |  |  | 20 | 	else{
 | 
        
           |  |  | 21 | 		e->line=-1;
 | 
        
           |  |  | 22 | 		e->col=-1;
 | 
        
           |  |  | 23 | 	}
 | 
        
           |  |  | 24 | 	_vsnprintf(e->text, sizeof(e->text), format, ap);
 | 
        
           |  |  | 25 | 	va_end(ap);
 | 
        
           |  |  | 26 |   | 
        
           |  |  | 27 | 	errors.push_back(e);
 | 
        
           |  |  | 28 | }
 | 
        
           |  |  | 29 | //---------------------------------------------------------------------------------
 | 
        
           |  |  | 30 | bod_text_parser::token* bod_parser_base::loadValue(token_stream& is, const char *context)
 | 
        
           |  |  | 31 | {
 | 
        
           |  |  | 32 | 	bod_text_parser::token* t=is.tok();
 | 
        
           |  |  | 33 | 	bod_text_parser::token* res;
 | 
        
           |  |  | 34 |   | 
        
           |  |  | 35 | 	if(t==NULL || t->type!=token::t_text){
 | 
        
           |  |  | 36 | 		error(t ? t : is.previous(), S_Error, "%sExpected value after '%s'", context, is.previous()->getText());
 | 
        
           |  |  | 37 | 		return NULL;
 | 
        
           |  |  | 38 | 	}
 | 
        
           |  |  | 39 | 	res=t;
 | 
        
           |  |  | 40 |   | 
        
           |  |  | 41 | 	t=(++is).tok();
 | 
        
           |  |  | 42 | 	if(t==NULL || t->type!=token::t_semicolon){
 | 
        
           |  |  | 43 | 		error(is.previous(), S_Error, "%sExpected ';' after '%s'", context, is.previous()->getText());
 | 
        
           |  |  | 44 | 		return NULL;
 | 
        
           |  |  | 45 | 	}
 | 
        
           |  |  | 46 | 	++is;
 | 
        
           |  |  | 47 | 	return res;
 | 
        
           |  |  | 48 | }
 | 
        
           |  |  | 49 | //---------------------------------------------------------------------------------
 | 
        
           |  |  | 50 | bool bod_parser_base::ungetValue(token_stream& s)
 | 
        
           |  |  | 51 | {
 | 
        
           |  |  | 52 | 	if(s.fail()) return false;
 | 
        
           |  |  | 53 | 	if(s.tell() >= 2){
 | 
        
           |  |  | 54 | 		--s;
 | 
        
           |  |  | 55 | 		if(s.tok()->type==bod_text_parser::token::t_semicolon){
 | 
        
           |  |  | 56 | 			--s;
 | 
        
           |  |  | 57 | 			if(s.tok()->type==bod_text_parser::token::t_text)
 | 
        
           |  |  | 58 | 				return true;
 | 
        
           |  |  | 59 | 		}
 | 
        
           |  |  | 60 | 	}
 | 
        
           |  |  | 61 | 	s.setstate(token_stream::failbit);
 | 
        
           |  |  | 62 | 	return false;
 | 
        
           |  |  | 63 | }
 | 
        
           |  |  | 64 | //---------------------------------------------------------------------------------
 | 
        
           |  |  | 65 | bool bod_parser_base::loadIntValue(token_stream& is, int *i, const char *msg)
 | 
        
           |  |  | 66 | {
 | 
        
           |  |  | 67 | 	const char *str;
 | 
        
           |  |  | 68 | 	token *t=loadValue(is, msg);
 | 
        
           |  |  | 69 | 	bool bRes;
 | 
        
           |  |  | 70 | 	if(bRes=(t!=NULL)){	
 | 
        
           |  |  | 71 | 		str=t->text;
 | 
        
           |  |  | 72 | 		while(*str!=0 && *str==' ')
 | 
        
           |  |  | 73 | 			str++;
 | 
        
           |  |  | 74 | 		if(*str=='0' && ((str[1] | 0x20)=='x')){
 | 
        
           |  |  | 75 | 			if(bRes=ishexa(t->text))
 | 
        
           |  |  | 76 | 				*i=hextoi(t->text);
 | 
        
           |  |  | 77 | 		}
 | 
        
           |  |  | 78 | 		else{
 | 
        
           |  |  | 79 | 			if(bRes=isinteger(t->text))
 | 
        
           |  |  | 80 | 				*i=atoi(t->text);
 | 
        
           |  |  | 81 | 		}
 | 
        
           |  |  | 82 | 		if(bRes==false)
 | 
        
           |  |  | 83 | 			error(t, S_Error, "%sExpected integer value", msg);
 | 
        
           |  |  | 84 | 	}
 | 
        
           |  |  | 85 | 	return bRes;
 | 
        
           |  |  | 86 | }
 | 
        
           |  |  | 87 | //---------------------------------------------------------------------------------
 | 
        
           |  |  | 88 | bool bod_parser_base::loadDoubleValue(token_stream& is, double *d, const char *msg)
 | 
        
           |  |  | 89 | {
 | 
        
           |  |  | 90 | 	token *t=loadValue(is, msg);
 | 
        
           |  |  | 91 | 	bool bRes;
 | 
        
           |  |  | 92 | 	if(bRes=(t!=NULL)){
 | 
        
           |  |  | 93 | 		if((bRes=isfloat(t->text))==false)
 | 
        
           |  |  | 94 | 			error(t, S_Error, "%sExpected float value", msg);
 | 
        
           |  |  | 95 | 		else
 | 
        
           |  |  | 96 | 			*d=atof(t->text);
 | 
        
           |  |  | 97 | 	}
 | 
        
           |  |  | 98 | 	return bRes;
 | 
        
           |  |  | 99 | }
 | 
        
           |  |  | 100 | //---------------------------------------------------------------------------------
 | 
        
           |  |  | 101 | /*char * bod_parser_base::loadString(token_stream& is, const char *context)
 | 
        
           |  |  | 102 | {
 | 
        
           |  |  | 103 | 	int pos=(int)is.tell();
 | 
        
           |  |  | 104 | 	bod_text_parser::token *t, *prev=NULL;
 | 
        
           |  |  | 105 | 	size_t size=0;
 | 
        
           |  |  | 106 | 	while((t=is.tok())!=NULL && t->type==token::t_text || t->type==token::t_colon){
 | 
        
           |  |  | 107 | 		size+=strlen(t->text) + 1;
 | 
        
           |  |  | 108 | 		++is;
 | 
        
           |  |  | 109 | 	}
 | 
        
           |  |  | 110 | 	size++;
 | 
        
           |  |  | 111 |   | 
        
           |  |  | 112 | 	if(t==NULL){
 | 
        
           |  |  | 113 | 		error(is.previous(), S_Error, "%sUnexpected end of document found while looking for end of string (;)", context);
 | 
        
           |  |  | 114 | 		return NULL;
 | 
        
           |  |  | 115 | 	}
 | 
        
           |  |  | 116 | 	if(t->type!=token::t_semicolon){
 | 
        
           |  |  | 117 | 		error(t, S_Error, "%sUnexpected here '%s' while loading string", context, t->getText());
 | 
        
           |  |  | 118 | 		return NULL;
 | 
        
           |  |  | 119 | 	}
 | 
        
           |  |  | 120 |   | 
        
           |  |  | 121 | 	char *str, *s;
 | 
        
           |  |  | 122 | 	str=new char[size];
 | 
        
           |  |  | 123 | 	s=str;
 | 
        
           |  |  | 124 |   | 
        
           |  |  | 125 | 	// it can happen that the stream will unload some tokens as we iterate through it
 | 
        
           |  |  | 126 | 	// whis will fix problem with pos being greater than current pos
 | 
        
           |  |  | 127 | 	if((size_t)pos > is.tell())
 | 
        
           |  |  | 128 | 		pos-=token_stream::tokenTreshold;
 | 
        
           |  |  | 129 |   | 
        
           |  |  | 130 | 	is.advance(-((int)is.tell() - pos));
 | 
        
           |  |  | 131 | 	while((t=is.tok())!=NULL && t->type==token::t_text || t->type==token::t_colon){
 | 
        
           |  |  | 132 | 		if(prev!=NULL && prev->type==token::t_text && t->type==token::t_text){
 | 
        
           |  |  | 133 | 			*s=' ';
 | 
        
           |  |  | 134 | 			s++;
 | 
        
           |  |  | 135 | 		}
 | 
        
           |  |  | 136 | 		size=strlen(t->text);
 | 
        
           |  |  | 137 | 		memcpy(s, t->text, size);
 | 
        
           |  |  | 138 | 		s+=(int)size;
 | 
        
           |  |  | 139 |   | 
        
           |  |  | 140 | 		prev=t;
 | 
        
           |  |  | 141 | 		++is;
 | 
        
           |  |  | 142 | 	}
 | 
        
           |  |  | 143 | 	*s=0;
 | 
        
           |  |  | 144 |   | 
        
           |  |  | 145 | 	++is;
 | 
        
           |  |  | 146 | 	return str;
 | 
        
           |  |  | 147 | }*/
 | 
        
           |  |  | 148 |   | 
        
           |  |  | 149 | char * bod_parser_base::loadString(token_stream& is, const char *context)
 | 
        
           |  |  | 150 | {
 | 
        
           |  |  | 151 | 	bod_text_parser::token *t, *prev=NULL;
 | 
        
           |  |  | 152 | 	string_builder str="";
 | 
        
           |  |  | 153 |   | 
        
           |  |  | 154 | 	while((t=is.tok())!=NULL && (t->type==token::t_text || t->type==token::t_colon)){
 | 
        
           |  |  | 155 | 		if(prev!=NULL && prev->type==token::t_text && t->type==token::t_text){
 | 
        
           |  |  | 156 | 			str << ' ';
 | 
        
           |  |  | 157 | 		}
 | 
        
           |  |  | 158 | 		str << t->getText();
 | 
        
           |  |  | 159 | 		prev=t;
 | 
        
           |  |  | 160 | 		++is;
 | 
        
           |  |  | 161 | 	}
 | 
        
           |  |  | 162 | 	if(t==NULL){
 | 
        
           |  |  | 163 | 		error(is.previous(), S_Error, "%sUnexpected end of document found while looking for end of string (;)", context);
 | 
        
           |  |  | 164 | 		return NULL;
 | 
        
           |  |  | 165 | 	}
 | 
        
           |  |  | 166 | 	if(t->type!=token::t_semicolon){
 | 
        
           |  |  | 167 | 		error(t, S_Error, "%sUnexpected here '%s' while loading string", context, t->getText());
 | 
        
           |  |  | 168 | 		return NULL;
 | 
        
           |  |  | 169 | 	}
 | 
        
           |  |  | 170 | 	++is;
 | 
        
           |  |  | 171 | 	return is.fail() ? NULL : str.getbuffer();
 | 
        
           |  |  | 172 | }
 | 
        
           |  |  | 173 | //---------------------------------------------------------------------------------
 |