示例#1
0
文件: daoMacro.c 项目: hooloong/dao
int DaoParser_ParseMacro( DaoParser *self, int start )
{
	int rb1, rb2, i = start, N = self->tokens->size;
	DaoToken **toks = self->tokens->items.pToken;
	DaoMacro *macro;
	DString *lang = NULL;
	DArray  *stops;
	DMap  *markers;

	if( start + 5 >= N ) return -1;
	if( toks[start+1]->type != DTOK_LCB ){
		lang = & toks[start+1]->string;
		if( toks[start+1]->type != DTOK_IDENTIFIER ){
			DaoParser_Error( self, DAO_TOKEN_NEED_NAME, lang );
			return -1;
		}
		if( lang->size == 3 && strcmp( lang->mbs, "dao" ) == 0 ){
			DaoParser_Error( self, DAO_TOKEN_NEED_NAME, lang );
			return -1;
		}
		start += 1;
	}
	if( toks[start+1]->name != DTOK_LCB ) return -1;

	self->curLine = toks[start]->line;
	rb1 = DaoParser_FindPairToken( self, DTOK_LCB, DTOK_RCB, start, -1 );
	if( rb1 <0 || rb1 +3 >= N ) return -1;
	if( toks[rb1+1]->name != DKEY_AS || toks[rb1+2]->name != DTOK_LCB ){
		DaoParser_Error( self, DAO_CTW_INV_MAC_DEFINE, NULL );
		return -1;
	}
	rb2 = DaoParser_FindPairToken( self, DTOK_LCB, DTOK_RCB, rb1 + 1, -1 );
	if( rb2 <0 ) return -1;

	/*
	   for( i=start; i<rb2; i++ ) printf( "%s  ", toks[i]->string.mbs ); printf("\n");
	 */

	macro = DaoMacro_New();

	if( DaoParser_MakeMacroGroup( self, macro->macroMatch, macro->macroMatch, start+2, rb1 ) ==0 ){
		DaoMacro_Delete( macro );
		return -1;
	}
	if( macro->macroMatch->units->size >0 ){
		DMacroUnit *unit = (DMacroUnit*) macro->macroMatch->units->items.pVoid[0];
		if( unit->type != DMACRO_TOK )
			DaoParser_Error( self, DAO_CTW_INV_MAC_FIRSTOK, & toks[i]->string );
	}
	if( toks[rb1+3]->line != toks[rb1+2]->line ) macro->macroApply->cpos = toks[rb1+3]->cpos;
	if( DaoParser_MakeMacroGroup( self, macro->macroApply, macro->macroApply, rb1+3, rb2 ) ==0 ){
		DaoMacro_Delete( macro );
		return -1;
	}
	markers = DMap_New(D_STRING,0);

	for(i=start+2; i<rb1; i++){
		if( toks[i]->string.mbs[0] == '$' ){
			if( MAP_Find( markers, & toks[i]->string ) != NULL ){
				self->curLine = toks[i]->line;
				DaoParser_Error( self, DAO_CTW_REDEF_MAC_MARKER, & toks[i]->string );
				return 0;
			}
			MAP_Insert( markers, & toks[i]->string, 0 );
		}
	}
	DMap_Clear( markers );
	i = rb1+3;
	if( DString_EQ( & toks[start+2]->string, & toks[rb1+3]->string ) ) i ++;
	while( i < rb2 ){
		char ch = toks[i]->string.mbs[0];
		if( ch != '$' && ch != '\\' && ch != '\'' ){
			if( MAP_Find( markers, & toks[i]->string ) == NULL ){
				DArray_Append( macro->keyListApply, & toks[i]->string );
				MAP_Insert( markers, & toks[i]->string, 0 );
			}
		}
		i ++;
	}

	stops = DArray_New(D_TOKEN);
	DMacroGroup_SetStop( macro->macroMatch, stops );
	DMacroGroup_FindVariables( macro->macroMatch );
	DArray_Clear( stops );
	DMacroGroup_SetStop( macro->macroApply, stops );
	DaoNamespace_AddMacro( self->nameSpace, lang, & toks[start+2]->string, macro );
	DArray_Delete( stops );
	DMap_Delete( markers );
	return rb2;
}
示例#2
0
int DaoParser_ParseMacro( DaoParser *self, int start )
{
	int rb1, rb2, i = start, N = self->tokens->size;
	DaoToken **toks = self->tokens->items.pToken;
	DMacroUnit *first;
	DaoMacro *macro;
	DString *lang = NULL;
	DArray  *stops;
	DMap  *markers;
	DNode *it;

	if( start + 5 >= N ) return -1;
	if( toks[start+1]->type != DTOK_LCB ){
		lang = & toks[start+1]->string;
		if( toks[start+1]->type != DTOK_IDENTIFIER ){
			DaoParser_Error( self, DAO_TOKEN_NEED_NAME, lang );
			return -1;
		}
		if( lang->size == 3 && strcmp( lang->mbs, "dao" ) == 0 ){
			DaoParser_Error( self, DAO_TOKEN_NEED_NAME, lang );
			return -1;
		}
		start += 1;
	}
	if( toks[start+1]->name != DTOK_LCB ) return -1;

	self->curLine = toks[start]->line;
	rb1 = DaoParser_FindPairToken( self, DTOK_LCB, DTOK_RCB, start, -1 );
	if( rb1 <0 || rb1 +3 >= N ) return -1;
	if( toks[rb1+1]->name != DKEY_AS || toks[rb1+2]->name != DTOK_LCB ){
		DaoParser_Error( self, DAO_CTW_INV_MAC_DEFINE, NULL );
		return -1;
	}
	rb2 = DaoParser_FindPairToken( self, DTOK_LCB, DTOK_RCB, rb1 + 1, -1 );
	if( rb2 <0 ) return -1;

	/*
	   for( i=start; i<rb2; i++ ) printf( "%s  ", toks[i]->string.mbs ); printf("\n");
	 */

	macro = DaoMacro_New();
	markers = DMap_New(D_STRING,0);

	if( DaoParser_MakeMacroGroup( self, macro->macroMatch, macro->macroMatch, start+2, rb1, markers, NULL ) ==0 ){
		goto Error;
	}
	if( macro->macroMatch->units->size == 0 ) goto Error;
	first = (DMacroUnit*) macro->macroMatch->units->items.pVoid[0];
	if( first->type != DMACRO_TOK ){
		DaoParser_Error( self, DAO_CTW_INV_MAC_FIRSTOK, & toks[i]->string );
		goto Error;
	}
	for(it=DMap_First(markers); it; it=DMap_Next(markers,it)){
		if( it->value.pInt > 1 ){
			DaoParser_Error( self, DAO_CTW_REDEF_MAC_MARKER, it->key.pString );
			goto Error;
		}
	}

	DMap_Clear( markers );
	if( toks[rb1+3]->line != toks[rb1+2]->line ) macro->macroApply->cpos = toks[rb1+3]->cpos;
	if( DaoParser_MakeMacroGroup( self, macro->macroApply, macro->macroApply, rb1+3, rb2, NULL, markers ) ==0 ){
		goto Error;
	}
	for(it=DMap_First(markers); it; it=DMap_Next(markers,it)){
		DArray_Append( macro->keyListApply, it->key.pString );
	}

	stops = DArray_New(D_TOKEN);
	DMacroGroup_SetStop( macro->macroMatch, stops );
	DMacroGroup_FindVariables( macro->macroMatch );
	DArray_Clear( stops );
	DMacroGroup_SetStop( macro->macroApply, stops );
	DaoNamespace_AddMacro( self->nameSpace, lang, & first->marker->string, macro );
	DArray_Delete( stops );
	DMap_Delete( markers );
	return rb2;
Error:
	DaoMacro_Delete( macro );
	DMap_Delete( markers );
	return -1;
}
示例#3
0
文件: daoMacro.c 项目: hooloong/dao
static int DaoParser_MakeMacroGroup( DaoParser *self,
		DMacroGroup *group, DMacroGroup *parent, int from, int to )
{
	DaoToken **toks = self->tokens->items.pToken;
	unsigned char tk;
	int i, sep, rb, prev;
	DMacroUnit *unit;
	DMacroGroup *grp, *group2; /* mingw don't like grp2 ?! */

	/*
	   for( i=from; i<to; i++ ) printf( "%s  ", toks[i]->mbs ); printf("\n");
	 */

	i = from;
	while( i < to ){
		char *chs = toks[i]->string.mbs;
		self->curLine = toks[i]->line;
		tk = toks[i]->name;
#if 0
		//printf( "%i %s\n", i, chs );
#endif
		if( tk == DTOK_ESC_LB || tk == DTOK_ESC_LSB || tk == DTOK_ESC_LCB ){
			grp = DMacroGroup_New();
			grp->cpos = toks[i]->cpos;
			grp->parent = parent;
			DArray_Append( group->units, (void*)grp );
			switch( tk ){
			case DTOK_ESC_LB :
				rb = DaoParser_FindPairToken( self, DTOK_ESC_LB, DTOK_ESC_RB, i, to );
				break;
			case DTOK_ESC_LSB :
				rb = DaoParser_FindPairToken( self, DTOK_ESC_LSB, DTOK_ESC_RSB, i, to );
				grp->repeat = DMACRO_ZERO_OR_ONE;
				break;
			case DTOK_ESC_LCB :
				rb = DaoParser_FindPairToken( self, DTOK_ESC_LCB, DTOK_ESC_RCB, i, to );
				grp->repeat = DMACRO_ZERO_OR_MORE;
				break;
			default :
				{
					rb = -1;
					DaoParser_Error( self, DAO_CTW_INV_MAC_OPEN, & toks[i]->string );
					break;
				}
			}
			if( rb <0 ) return 0;

			prev = i+1;
			sep = DaoParser_FindOpenToken( self, DTOK_ESC_PIPE, i+1, rb, 0 );
			if( sep >=0 ){
				while( sep >=0 ){
					group2 = DMacroGroup_New();
					group2->parent = grp;
					if( DaoParser_MakeMacroGroup( self, group2, group2, prev, sep ) == 0 )
						return 0;
					DArray_Append( grp->units, (void*)group2 );
					prev = sep +1;
					sep = DaoParser_FindOpenToken( self, DTOK_ESC_PIPE, prev, rb, 0 );
					if( prev < rb && sep <0 ) sep = rb;
				}
				grp->type = DMACRO_ALT;
			}else if( DaoParser_MakeMacroGroup( self, grp, grp, i+1, rb ) == 0 ){
				return 0;
			}
			i = rb +1;
			self->curLine = toks[i]->line;
			if( toks[i]->string.mbs[0] == '\\' ){
				switch( toks[i]->name ){
				case DTOK_ESC_EXCLA : grp->repeat = DMACRO_ZERO; i++; break;
				case DTOK_ESC_QUES  : grp->repeat = DMACRO_ZERO_OR_ONE; i++; break;
				case DTOK_ESC_STAR  : grp->repeat = DMACRO_ZERO_OR_MORE; i++; break;
				case DTOK_ESC_PLUS  : grp->repeat = DMACRO_ONE_OR_MORE; i++; break;
				case DTOK_ESC_SQUO : case DTOK_ESC_DQUO :
				case DTOK_ESC_LB :  case DTOK_ESC_RB :
				case DTOK_ESC_LCB : case DTOK_ESC_RCB :
				case DTOK_ESC_LSB : case DTOK_ESC_RSB : break;
				default : DaoParser_Error( self, DAO_CTW_INV_MAC_REPEAT, & toks[i]->string );
						  return 0;
				}
			}
			continue;
		}

		self->curLine = toks[i]->line;
		unit  = DMacroUnit_New();
		DaoToken_Assign( unit->marker, toks[i] );
		DArray_Append( group->units, (void*)unit );
		switch( chs[0] ){
		case '$' :
			if( DString_FindMBS( & toks[i]->string, "EXP", 0 ) == 1 ){
				unit->type = DMACRO_EXP;
			}else if( DString_FindMBS( & toks[i]->string, "VAR", 0 ) == 1 ){
				unit->type = DMACRO_VAR;
			}else if( DString_FindMBS( & toks[i]->string, "ID", 0 ) == 1 ){
				unit->type = DMACRO_ID;
			}else if( DString_FindMBS( & toks[i]->string, "OP", 0 ) == 1 ){
				unit->type = DMACRO_OP;
			}else if( DString_FindMBS( & toks[i]->string, "BL", 0 ) == 1 ){
				unit->type = DMACRO_BL;
			}else if( DString_FindMBS( & toks[i]->string, "IBL", 0 ) == 1 ){
				unit->type = DMACRO_IBL;
			}
			break;
		case '(' :
		case '[' :
		case '{' :
			switch( chs[0] ){
			case '(' :
				rb = DaoParser_FindPairToken( self, DTOK_LB, DTOK_RB, i, to );
				break;
			case '[' :
				rb = DaoParser_FindPairToken( self, DTOK_LSB, DTOK_RSB, i, to );
				break;
			case '{' :
				rb = DaoParser_FindPairToken( self, DTOK_LCB, DTOK_RCB, i, to );
				break;
			default : rb = -1;
			}
			if( rb <0 ) return 0;

			grp = DMacroGroup_New();
			grp->parent = group;
			grp->repeat = DMACRO_AUTO;
			DArray_Append( group->units, (void*)grp );
			if( DaoParser_MakeMacroGroup( self, grp, parent, i+1, rb ) == 0 ) return 0;
			i = rb;
			continue;
		case '\'' :
			if( chs[2] == '\'' ){
				unit->marker->type = 0;
				switch( chs[1] ){
				case '(' : unit->marker->type = unit->marker->name = DTOK_LB; break;
				case ')' : unit->marker->type = unit->marker->name = DTOK_RB; break;
				case '[' : unit->marker->type = unit->marker->name = DTOK_LSB; break;
				case ']' : unit->marker->type = unit->marker->name = DTOK_RSB; break;
				case '{' : unit->marker->type = unit->marker->name = DTOK_LCB; break;
				case '}' : unit->marker->type = unit->marker->name = DTOK_RCB; break;
				case '\'' : unit->marker->type= unit->marker->name = DTOK_ESC_SQUO;break;
							case '\"' : unit->marker->type= unit->marker->name = DTOK_ESC_DQUO;break;
				default : break;
				}
				if( unit->marker->type == 0 ){
					DaoParser_Error( self, DAO_CTW_INV_MAC_SPECTOK, & toks[i]->string );
					return 0;
				}
				unit->type = DMACRO_BR;
				DString_SetMBS( & unit->marker->string, chs+1 );
				DString_Erase( & unit->marker->string, unit->marker->string.size-1, 1 );
			}
		default : break;
		}
		if( i+1 < to && toks[i+1]->string.mbs[0] == '@' ){
			char ch = toks[i+1]->string.mbs[1];
			if( ch != '@' ){
				if( toks[i+1]->string.size != 2 || ch < '1' || ch >'9' ){
					DaoParser_Error( self, DAO_CTW_INV_MAC_INDENT, & toks[i+1]->string );
					return 0;
				}
				unit->indent = ch - '0';
				i ++;
			}
		}
		i ++;
	}
	return 1;
}
示例#4
0
static int DaoParser_MakeMacroGroup( DaoParser *self, DMacroGroup *group, DMacroGroup *parent, int from, int to, DMap *vars, DMap *markers )
{
	unsigned char tk;
	int i, sep, rb, prev;
	DaoToken **toks = self->tokens->items.pToken;
	DMacroGroup *grp, *group2; /* mingw don't like grp2 ?! */
	DMacroUnit *unit;
	DNode *it;

	/*
	   for( i=from; i<to; i++ ) printf( "%s  ", toks[i]->mbs ); printf("\n");
	 */

	i = from;
	while( i < to ){
		DaoToken *tok = toks[i];
		char *chs = tok->string.mbs;
		int tk = tok->name;

#if 0
		printf( "%i %s\n", i, chs );
#endif
		self->curLine = tok->line;
		if( tk == DTOK_LB || tk == DTOK_LSB || tk == DTOK_LCB ){
			grp = DMacroGroup_New();
			grp->cpos = tok->cpos;
			grp->parent = parent;
			DArray_Append( group->units, (void*)grp );
			switch( tk ){
			case DTOK_LB :
				rb = DaoParser_FindPairToken( self, DTOK_LB, DTOK_RB, i, to );
				break;
			case DTOK_LSB :
				rb = DaoParser_FindPairToken( self, DTOK_LSB, DTOK_RSB, i, to );
				grp->repeat = DMACRO_ZERO_OR_ONE;
				break;
			case DTOK_LCB :
				rb = DaoParser_FindPairToken( self, DTOK_LCB, DTOK_RCB, i, to );
				grp->repeat = DMACRO_ZERO_OR_MORE;
				break;
			default :
				rb = -1;
				DaoParser_Error( self, DAO_CTW_INV_MAC_OPEN, & tok->string );
				break;
			}
			if( rb <0 ) return 0;

			prev = i+1;
			sep = DaoParser_FindOpenToken( self, DTOK_PIPE, i+1, rb, 0 );
			if( sep >=0 ){
				while( sep >=0 ){
					group2 = DMacroGroup_New();
					group2->parent = grp;
					if( DaoParser_MakeMacroGroup( self, group2, group2, prev, sep, vars, markers ) == 0 )
						return 0;
					DArray_Append( grp->units, (void*)group2 );
					prev = sep +1;
					sep = DaoParser_FindOpenToken( self, DTOK_PIPE, prev, rb, 0 );
					if( prev < rb && sep <0 ) sep = rb;
				}
				grp->type = DMACRO_ALT;
			}else if( DaoParser_MakeMacroGroup( self, grp, grp, i+1, rb, vars, markers ) == 0 ){
				return 0;
			}
			i = rb +1;
			tok = toks[i];
			self->curLine = tok->line;
			switch( tok->name ){
			case DTOK_NOT   : grp->repeat = DMACRO_ZERO; i++; break;
			case DTOK_QUERY : grp->repeat = DMACRO_ZERO_OR_ONE; i++; break;
			case DTOK_MUL   : grp->repeat = DMACRO_ZERO_OR_MORE; i++; break;
			case DTOK_ADD   : grp->repeat = DMACRO_ONE_OR_MORE; i++; break;
			default : break;
			}
			continue;
		}

		self->curLine = tok->line;
		unit = DMacroUnit_New();
		DaoToken_Assign( unit->marker, tok );
		DArray_Append( group->units, (void*)unit );
		if( chs[0] == '$' ){
			if( DString_FindMBS( & tok->string, "EXP", 0 ) == 1 ){
				unit->type = DMACRO_EXP;
			}else if( DString_FindMBS( & tok->string, "VAR", 0 ) == 1 ){
				unit->type = DMACRO_VAR;
			}else if( DString_FindMBS( & tok->string, "ID", 0 ) == 1 ){
				unit->type = DMACRO_ID;
			}else if( DString_FindMBS( & tok->string, "OP", 0 ) == 1 ){
				unit->type = DMACRO_OP;
			}else if( DString_FindMBS( & tok->string, "BL", 0 ) == 1 ){
				unit->type = DMACRO_BL;
			}else{
				DaoParser_Error( self, DAO_CTW_INV_MAC_SPECTOK, & tok->string );
				return 0;
			}
			if( vars != NULL ){
				it = DMap_Find( vars, & unit->marker->string );
				if( it == NULL ) it = DMap_Insert( vars, & unit->marker->string, 0 );
				it->value.pInt += 1;
			}
		}else if( tk == DTOK_MBS ){
			DaoLexer_Reset( self->wlexer );
			DaoLexer_Tokenize( self->wlexer, chs + 1, 0 );
			if( self->wlexer->tokens->size == 2 ){
				DaoToken_Assign( unit->marker, self->wlexer->tokens->items.pToken[0] );
				if( markers != NULL ){
					it = DMap_Find( markers, & unit->marker->string );
					if( it == NULL ) it = DMap_Insert( markers, & unit->marker->string, 0 );
					it->value.pInt += 1;
				}
			}
			DaoLexer_Reset( self->wlexer );

			rb = -1;
			if( tok->string.size == 3 ){
				switch( chs[1] ){
				case '(': rb = DaoParser_FindPair( self, "'('", "')'", i, to ); break;
				case '[': rb = DaoParser_FindPair( self, "'['", "']'", i, to ); break;
				case '{': rb = DaoParser_FindPair( self, "'{'", "'}'", i, to ); break;
				default : break;
				}
			}
			if( rb >= 0 ){
				grp = DMacroGroup_New();
				grp->parent = group;
				grp->repeat = DMACRO_AUTO;
				DArray_Append( group->units, (void*)grp );
				if( DaoParser_MakeMacroGroup( self, grp, parent, i+1, rb, vars, markers ) == 0 ) return 0;
				i = rb;
				continue;
			}
		}
		i ++;
	}
	return 1;
}