Exemplo n.º 1
0
void print_state_machine(StateMachine* machine)
{
	int i;

	for(i = 0; i < machine->n; i++)
	{
		int j;

		State* s = &(machine->states[i]);
		State* s1 = NULL;

		printf("State %d", i);

		if(machine->states[i].accepting)
		{
			printf(" -> accepting state! Returns %s", machine->states[i].name);
		}

		printf("\n");

		printf("Accepts transitions with: ");
		for(j = 0; j < 128; j++)
		{
			s1 = get_next_state(machine, s, j);

			if(s1 != NULL)
			{
				printf("%c", j);
			}
		}

		printf("\n");
	}
}
Exemplo n.º 2
0
int decode_scancode(alt_up_ps2_dev *ps2, KB_CODE_TYPE *decode_mode,
		alt_u8 *buf, char *ascii) {
	alt_u8 byte = 0;
	int status_read = 0;
	*decode_mode = KB_INVALID_CODE;

	static DECODE_STATE state = STATE_INIT;

	do {
		status_read = alt_up_ps2_read_data_byte(ps2, &byte);
		//FIXME: When the user press the keyboard extremely fast, data may get
		//occasionally get lost 

		//		if (byte != 0)
		//			printf("byte read: %x status: %d\n", byte, status_read);

		if (status_read != 0) {

			if (state == STATE_INIT)
				return status_read;
			else
				return -2;
		}

		state = get_next_state(state, byte, decode_mode, buf, ascii);
	} while (state != STATE_DONE);

	state = STATE_INIT;
	return 0;
}
Exemplo n.º 3
0
void _state_machine_initialize(state_machine_t machine){
	int i,j;
	transitioning_t transition;
	for(i=0;i<NUM_STATES;i++){
		for(j=0;j<NUM_TRANSITIONS;j++){
			
			transition = get_next_state((state_e)i, (transition_e)j);
			_set_transitioning(machine, (state_e)i, (transition_e)j, transition);

		}
	}
}
Exemplo n.º 4
0
SDL_Rect Animation::Get_Frame_to_Render(Entity& ent) {
    if(SDL_GetTicks() - last_frame_time < anim_frame_rate){
        SDL_Rect rect =  {397,21+(current_frame)*70,74,60};
        return rect;
    }
    else {
        last_frame_time = SDL_GetTicks();
        if (mini_anim_frame == 0) {
            /// \todo Figure out how to uncouple these, we'll likely
            /// want to have a subclass of animation that works for
            /// the player and references the input state

            //EnvLine* line  = Level::p_level->ClosestLine(ent.x, ent.y);
            double dist_to_ground = 0;
            //    line->DistToPoint(ent.x, ent.y).dist_to_pt - 2.5;
            // dont understand why this goes down to 2.5 at the ground
            // and stops there.
            current_state = get_next_state(ent, targetx, targety,
                                           xcont, dist_to_ground);
            if (current_state == P_STAND || current_state == PUSH_R ||
                current_state == PUSH_L || current_state == PUSH_U ||
                current_state == PUSH_D || current_state == FREE_U ||
                current_state == FREE_D || current_state == H_WALL_R ||
                current_state == H_WALL_L || current_state == DEAD ) {
                mini_anim_frame = 0;
            }
            else {
                mini_anim_frame = 1;
            }
            current_frame = states[current_state].beg_frame;
        }
        else {
            current_frame = states[current_state].beg_frame
                + mini_anim_frame - 1;
            mini_anim_frame += 1;
            if (mini_anim_frame == states[current_state].maframe_lim + 1) {
                mini_anim_frame = 0;
                current_state = states[current_state].end_state;
            }
        }
        SDL_Rect rect =  {397,21+(current_frame)*70,74,60};
        return rect;
    }
}
Exemplo n.º 5
0
int read_make_code(KB_CODE_TYPE *decode_mode, alt_u8 *buf)
{
  alt_u8 byte = 0;
  int status_read =0;
  *decode_mode = KB_INVALID_CODE;
  DECODE_STATE state = STATE_INIT;
  do {
    status_read = read_data_byte_with_timeout(&byte, DEFAULT_PS2_TIMEOUT_VAL); //Changed by Schaertl
    //FIXME: When the user press the keyboard extremely fast, data may get
    //occasionally get lost 

    if (status_read == PS2_ERROR)
      return PS2_ERROR;

    state = get_next_state(state, byte, decode_mode, buf);
  } while (state != STATE_DONE);

  return PS2_SUCCESS;
}
Exemplo n.º 6
0
int decode_scancode(alt_up_ps2_dev *ps2, KB_CODE_TYPE *decode_mode, alt_u8 *buf, char *ascii)
{
	alt_u8 byte = 0;
	int status_read =0;
	*decode_mode = KB_INVALID_CODE;
	DECODE_STATE state = STATE_INIT;
	do
	{
		status_read = alt_up_ps2_read_data_byte_timeout(ps2, &byte);
		//FIXME: When the user press the keyboard extremely fast, data may get
		//occasionally get lost 

		if (status_read != 0)
			return status_read;

		state = get_next_state(state, byte, decode_mode, buf, ascii);
	} while ( state != STATE_DONE );

	return 0;
}
Exemplo n.º 7
0
/* Function update

   Given the previous generation of the game board in old_array, performs a single iteration of Conway's
   Game of Life, storing the new generation of the game board in new_array.

   Input: int     rows      - the number of rows of the game board
          int     cols      - the number of columns of the game board
          int[][] old_array - the previous generation of the game board, a 2D array of zeros and ones
          int[][] new_array - a 2D array where the next generation of the game board will be stored

   Output: None
 */
void update(int rows, int cols, int old_array[rows][cols], int new_array[rows][cols]) {
    /* For each cell in old_array, you should:
         1. Determine whether that cell will be alive or dead in the next generation
            by calling get_next_state on old_array.
         2. If the cell's next state is 1 (alive), set that cell to alive in new_array
            by calling set_alive.  Otherwise, set that cell to dead in new_array by calling
            set_dead. */
    int r, c;
    for(r=0; r<rows; r++)
    {
	for(c=0; c<cols; c++)
	{
	    if(get_next_state(rows, cols, old_array, r, c)==1)
	    {
		new_array[r][c]=1;
	    }
	    else
	    {
		new_array[r][c]=0;
	    }
	}
    }

}
Exemplo n.º 8
0
/**********************************************************************************************************
Purpose:			Set the proper token depending on the lexeme read from the buffer. 
Author:				Thom Palmer and Chris Whitten
History/Versions:	10.20.13
Called functions:	b_setmark(), b_getc(), b_getmark(), SEOF(), WHTSPACE(), is_assop(), strncmp(),
					b_set_getc_offset(), b_retract(), b_get_getc_offset(),b_eob(), isalnum(), b_addc()
					get_next_state(), b_create(), b_pack(), b_destroy() 
Parameters:			Buffer * const pBD
Return value:		Token t
Algorithm:			Validate parameters, read char from buffer, check the char to see if its a legal character.
					depending on the char peak forward to see what the following char is in order to 
					determine if it's part of the lexeme or if it's time to return. once a valid lexeme is
					found set the token and return. if a valid lexeme is not found set the token to error 
					state and return. 
**********************************************************************************************************/
Token mlwpar_next_token(Buffer * sc_buf)
{
	Token t;			/* token to return after recognition */
	unsigned char c;	/* input symbol */
	int state = 0;		/* initial state of the FSM */
	unsigned int retrCtr;
	short lexstart;		/* start offset of a lexeme in the input buffer */
	short lexend;		/* end offset of a lexeme in the input buffer */
	int accept = NOAS;	/* type of state - initially not accepting */  
	unsigned int i=0;	/* Used throughout the function as iterator */
   
	/* Ensure the buffer is not null before trying to access it */

	if(sc_buf == NULL)
	{	   
		scerrnum = BUFFNULL;  
	     t_set_err_t(RUNTIMERR, t);
	}     
                
	while (1) /* Endless loop broken by token returns it will generate a warning */
	{ 
                
		/* Set mark before getting the next character. This prevents the need for unneccessary decrements. */
		b_setmark(sc_buf, b_get_getc_offset(sc_buf));
		lexstart = b_getmark(sc_buf);
	
		/* Get the next char from the buffer. */
		c = b_getc(sc_buf); 	
	
		/* Ensure SEOF has not been read before processing any further. */
		if(SEOF(c))
		{
			t.code = SEOF_T;
			return t;
		}

		/* If it's whitespace ignore and return to the start of the loop. */
		if(WHTSPC(c))
		{
			continue;
		}

		/* Drop into switch statement to determine what the character can potentially represent and handle it appropriatly. */
		switch(c)
		{
			/* If c is '=' the token can either be a relation operatory or an assignment operator,  so peak forward */
			case EQSIGN:
				{ 
					c = b_getc(sc_buf);
					/* If the next character is '=' then we have found a relational operator */
					if(c == EQSIGN) 
					{
						/* Set the code and attribute and return t */
						t.code = REL_OP_T;
						t.attribute.rel_op = EQ;
						return t;
					}
					/* Otherwise retract and return an assignment operator token */
					b_retract(sc_buf);
					t.code = ASS_OP_T;
					return t;
				} 
			/* If the token starts with ! it can either be a comment or the != relational operator, so peak forward and act appropriatly. */
			case EXCLAMTN:
				c = b_getc(sc_buf);
				/* If the next token is < then we have a comment therfore ignore everything in the line.*/
				if(c == LESSTHN)
				{
					do
					{
						c = b_getc(sc_buf);
						if(SEOF(c))
						{ 
							t.code = ERR_T;
							t.attribute.err_lex[0] = EXCLAMTN;
							t.attribute.err_lex[1] = LESSTHN;
							t.attribute.err_lex[2] = c;
							t.attribute.err_lex[3] = STRTERM;
							b_retract(sc_buf);
							return t;
						}
					}while ( c != NEWLINE && c != CARRTRN);

					++line;
					continue;
				}
				/* If the next token we have the NE relational operator. */
				if(c == EQSIGN)
				{
					t.code = REL_OP_T;
					t.attribute.rel_op = NE ;
					return t;
				}
				/* if the next char is neither = or < we have an error set ERR_T*/
				t.code = ERR_T;
				t.attribute.err_lex[0] = EXCLAMTN;
				t.attribute.err_lex[1] = c;
				t.attribute.err_lex[2] = STRTERM;
	   
				/* We assume the error was meant to be a token so ignore everything in the line. */
				do
				{
					c = b_getc(sc_buf);
					/* If SEOF or b_eob is found retract the buffer and return t */
					if(SEOF(c))
					{
						b_retract(sc_buf);
						return t;
					}
				}while ( c != NEWLINE);
				++line;
				return t;

			/*If we have a plus sign '+' set the token and it's attirbute then return. */
			case POS:
				t.code = ART_OP_T;
				t.attribute.arr_op = PLUS;
				return t;

			/*If we have a minus sign '-' set the token and it's attirbute then return. */
			case NEG:
				t.code = ART_OP_T;
				t.attribute.arr_op = MINUS;
				return t;

			/*If we have a a period '.' it could be a logical operator or an error. */
			case PERIOD:
				retrCtr = 1;
				i = 0;
				c = b_getc(sc_buf);
				
				/* Switch on the first character read after the period '.' */
				switch (c) 
				{
				/* If its an 'A' we might have .AND. */
				case'A' :
					/* Compare the string the string read from the buffer to the string literal .AND.  */
					++retrCtr;
					if(b_getc(sc_buf) == 'N')
					{
						++retrCtr;
						if(b_getc(sc_buf) == 'D')
						{
							++retrCtr;
							if(b_getc(sc_buf) == PERIOD)
							{
								t.code = LOG_OP_T;
								t.attribute.log_op = AND;
								return t;
							}
						}
					}
					break;
				case'O':
					/* Comapre the string the string read from the buffer to the string literal .OR.  */
					++retrCtr;
					if(b_getc(sc_buf) == 'R')
					{
						++retrCtr;
						if(b_getc(sc_buf) == PERIOD)
						{
							t.code = LOG_OP_T;
							t.attribute.log_op = OR;
							return t;
						}
					}

					break;
				}

				while(i<retrCtr)
				{
					b_retract(sc_buf);
					i++;
				}
				t.code = ERR_T;
				/* Add char which caused the error to the err_lex */
				t.attribute.err_lex[0] = PERIOD;
				t.attribute.err_lex[1] = STRTERM;
				return t;

			/* If we have an astrix sign '*' set the token and it's attirbute then return. */
			case ASTRX:
				t.code = ART_OP_T;
				t.attribute.arr_op = MULT;
				return t;

			/* If c is a forward slash '/' set the token and it's attirbute then return. */
			case FWDSLSH:
				t.code = ART_OP_T;
				t.attribute.arr_op = DIV;
				return t;

			/* If c is a left brace '{' set the token and it's attirbute then return. */
			case LBRACE:
				t.code = LBR_T;
				return t;

			/* If c is a right brace '}' set the token and it's attirbute then return. */
			case RBRACE:
				t.code = RBR_T;
				return t;

			/* If c is a left parenthesis '(' set the token and it's attirbute then return. */
			case LPRNTHS:
				t.code = LPR_T;
				return t;

			/* If c is a right parenthesis ')' set the token and it's attirbute then return. */
			case RPRNTHS:
				t.code = RPR_T;
				return t;

			/* If c is a less than symbol '<' check the next char. */
			case LESSTHN:
				c = b_getc(sc_buf);

				/* If the next char is the greater than symbol '>' set the proper token and return. */
				if(c == GRTRTHN){
					t.code = SCC_OP_T;
					return t;
				}

				/* If the next char is not recognized restract the buffer and set the token */
				t.code = REL_OP_T;
				t.attribute.rel_op = LT;
				b_retract(sc_buf);
				return t;

			/* If c is a greater than symbol '>' set the proper token and return. */
			case GRTRTHN:
				t.code = REL_OP_T;
				t.attribute.rel_op = GT;
				return t;

			/* If c is a new line '\n' increment the line number and return to the start of the loop. */
			case CARRTRN:
				NEWLINE_TEST
				continue;
				
			/* If c is a NEWLINE character increment the line number and continue */
			case NEWLINE:
				++line;
				continue;

			/* If c is a comma ',' set the proper token and return. */
			case COMMA:
				t.code = COM_T;  
				return t;

			/* If c is a semi colon ';' set the proper token and return. */
			case SEMICLN:
				t.code = EOS_T;
				return t;

			/* If c is a quotation mark '"' we have the start of a string, analyze the next chars until '"' or SEOF is hit. */
			case QUOTE:
				/* read all the chars in from the input buffer until a '"' */
				do
				{
					c = b_getc(sc_buf);
					lexend = b_get_getc_offset(sc_buf);
					/* If eob has be set or SEOF is read in from the buffer prior to closing the string */
					/* Break into the error token setup. */
					if( SEOF(c))
					{	
						/* Set the getc_offset to the start of the string */
						b_set_getc_offset(sc_buf,lexstart);
						/* Iterate over the buffer and copy the contents of the error string into the err_lex */
						for( i = 0; i < lexend-lexstart; i++) /* Comparison of unsigned int and short will generate warning. 
															     lexend-lexstart will always be positive no need to cast */
						{				
							c = b_getc(sc_buf);
							/* For the first 20 characters */
							if(i<=ERR_LEN)
							{
								/* Copy c into the current index of err_lex for first 16 characters */
								if(i<=16)
								t.attribute.err_lex[i] = c;
								/* Copy a decimal into the indexes between 17 and ERR_LEN */
								if(i>16 && i<ERR_LEN)
								{
									t.attribute.err_lex[i] = PERIOD;
								}
								/* Copy a string terminator into the last index of err_lex */
								if (i==ERR_LEN)
								{
									t.attribute.err_lex[i]= STRTERM;
								}

							}
					
						}
						t.code = ERR_T;							
						return t;
					}
					/* Increment the line number each time a line terminator is found */
					if(c == NEWLINE)
					{
						++line;
					}
					if(c == CARRTRN)
					{
						NEWLINE_TEST
					}
				}while ( c != QUOTE );
			
				/* Closing quote found. Valid String */
				/* Set the getc_offset back to the start of the string */
				b_set_getc_offset(sc_buf,lexstart);
				/* Set the str_offset attribute to the location of the current getc_offset in the str_LTBL */
				t.attribute.str_offset = b_getsize(str_LTBL);

				/* Add the characters of the string into the str_LTBL */
				for(  i = 0; i< lexend-lexstart;i++) /* Comparison of unsigned int and short will generate warning. 
														lexend-lexstart will always be positive no need to cast */
				{			
					c = b_getc(sc_buf);
					/* Ensure that quotes are not added to the string */
					if(c != '"')
					{
						if(!b_addc(str_LTBL, c))
						{
							scerrnum = FAILADDC;
							t_set_err_t(RUNTIMERR, t);
						}
					}
				}
				/* Add the string terminator to the string and set the Token Code */
				if (!b_addc(str_LTBL,STRTERM))
				{
					scerrnum = FAILADDC;
					t_set_err_t(RUNTIMERR, t);
				}
				t.code = STR_T;
				return t;
			}
	
		/* Special symbol scanning completed. Now checking for lexeme type */
		if (isalnum(c))
		{
			/* Use for loop to iterate over the transition table based on the current state and character */
			/* Continue iterating until an accepting state has been found */
			for(state = get_next_state(state,c,&accept);accept==NOAS; state = get_next_state(state,c,&accept))
			{
				c = b_getc(sc_buf);
			}
		
			/* Retract the buffer if is is an accepting state with a retract */
			if(accept==ASWR)
			{
				b_retract(sc_buf);
			}
			/* Set the end of the lexeme at the current getc_offset */
			lexend = b_get_getc_offset(sc_buf);
			/* Create a temporary buffer to store the lexeme */
			lex_buf = b_create((lexend - lexstart +1),0,'f');
			/* If buffer creation was not successful. Set the error token for a runtime error. */
			if (!lex_buf)
			{
				scerrnum = BUFFNULL;
				t_set_err_t(RUNTIMERR, t);
			}

			
			
			/* Reset the getc_offset to the start of the lexeme */
			b_set_getc_offset(sc_buf,lexstart);
			/* Add the characters of the lexeme to lex_buf */
			for( i = 0;i<lexend-lexstart;i++) /* Comparison of unsigned int and short will generate warning. 
												 lexend-lexstart will always be positive no need to cast */
			{
				if (!b_addc(lex_buf,b_getc(sc_buf)))
				{
					scerrnum = FAILADDC;
					t_set_err_t(RUNTIMERR, t);
				}
			}
			/* Pack lex_buf and add the string terminator to it */
			b_pack(lex_buf);
			/* If b_addc fails set the token for a runtime error and return t  */
			if (!b_addc(lex_buf,STRTERM))
			{
				scerrnum = FAILADDC;
				t_set_err_t(RUNTIMERR, t);
			}
			/* Call the accepting function at the current state index and pass the lexeme */
			t = aa_table[state](b_get_chmemloc(lex_buf,0));
			b_destroy(lex_buf);
			return t;
		}
		/* This code will be executed if c was an invalid symbol*/
		/* Set error token and return t. */
		t.code = ERR_T;
		t.attribute.err_lex[0] = c;
		t.attribute.err_lex[1] = STRTERM; /*Probably a better way to do this.*/
		return t;             
   }
}
Exemplo n.º 9
0
/********************************************************************************
 * Deterministic finit automata. A word is read from the input file. The automata
 * is then fed with the word.
 ********************************************************************************/
void start_automata(config_t *conf, FILE *fp) {
	struct s_node *node = NULL;
	int next_state = 0;
	int last_state = 0;

	char word[MAXWORDSIZE], val[MAXWORDSIZE];
	automata_t automata;
	automata.state = BEGIN;


	reset_automata(&automata);
	init_automata();

	conf->traffic.pattern = NULL;


	while(get_next_word(word, fp) != EOF) {
		/* remember line of word */
		word_line = fp_line; 

	
		/* the closing bracket indicates that the current state ist finished with its work. The automata 
		 * should return to the the state that calls the current state */
		 if(strcmp(word, "}") == 0) {
			node = get_node(automata.state);
			if(node->check != NULL) {
				node->check(conf);
				//fprintf(stderr, "leaving state %i, calling check...\n", automata.state);
			}
			automata.state = node->return_state;	
			continue;
		}
		
		 next_state = get_next_state(automata.state, word);	
		 
		
		/* change state */
		if(next_state != -1) {
			
			/* before we change the state: call the check function of the last state */
		//	fprintf(stderr, "changing %i ==> %i \n", automata.state, next_state);
			node = get_node(automata.state);
			if(node != NULL) {
				if(node->check != NULL) {
					node->check(conf);
		//			fprintf(stderr, "check function called \n");
				}
			}
			
			last_state = automata.state;
			automata.state = next_state;
			node = get_node(automata.state);
			node->return_state = last_state;
		//	fprintf(stderr, "%i ==> %i\n", automata.state, last_state);
			if(node->init != NULL) {
				node->init(conf);
				/* a new conf structure could have been malloced ( node->init(conf) could be the 
				 * pointer to the function init_stream in states.c, which mallocs a new conf structure.
				 * conf sould always point to the last element in the linked list ) */ 
				while(conf->next != NULL)
					conf = conf->next;
			}
		}
		
		/* remain in current state */
		else {
			struct s_node *node;
			node = get_node(automata.state);
			if(node != NULL) {
				get_pair_value(val, fp);	
				node->read(word, val, conf, &automata);
			//	fprintf(stderr, "in state...automata.state = %i\n", automata.state);
			}
			else {
				fprintf(stderr, "INTERNAL ERROR: automata in unknown state (%i)\n", automata.state);
				exit(0);
			}	
			
		}
	}
	
	/* automata should end up in state BEGIN!! */
	if(automata.state != BEGIN) {
		fprintf(stderr, "ERROR: unexpected end of file, %i\n", automata.state);
		exit(0);	
	}
	//conf->next = NULL;

}
Exemplo n.º 10
0
void pce220_serial_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
    if (id == TIMER_SEND && m_enabled)
    {
        //send data
        if (m_bytes_count <= length())
        {
            switch(m_state)
            {
            case SIO_WAIT:
                m_ack = 1;  //data send request
                //waits until is ready to receive
                if(!m_busy)
                    return;
                break;
            case SIO_SEND_START:
                //send start bit
                m_xin = 1;
                break;
            case SIO_SEND_BIT0:
            case SIO_SEND_BIT1:
            case SIO_SEND_BIT2:
            case SIO_SEND_BIT3:
            case SIO_SEND_BIT4:
            case SIO_SEND_BIT5:
            case SIO_SEND_BIT6:
            case SIO_SEND_BIT7:
                m_xin = BIT(~m_current_byte, m_state - SIO_SEND_BIT0);
                break;
            case SIO_SEND_PARITY:
                m_xin = calc_parity(m_current_byte);
                break;
            case SIO_SEND_STOP1:
            case SIO_SEND_STOP2:
                //stop bit
                m_xin = m_ack = 0;
                break;
            }

            if (m_state == (SIO_SEND_PARITY + SIO_STOP_BIT))
            {
                //next byte
                m_bytes_count++;
                popmessage("Send %d/%d bytes\n", m_bytes_count , (UINT32)length());
                m_state = SIO_WAIT;
                if (m_bytes_count < length())
                    fread(&m_current_byte, 1);
                else
                    m_current_byte = SIO_EOT_BYTE;
            }
            else
            {
                m_state = get_next_state();
            }

        }
        else
        {
            m_din = m_xin = m_ack = 0;
        }
    }
    else if (id == TIMER_RECEIVE && m_enabled)
    {
        //receive data
        switch(m_state)
        {
        case SIO_WAIT:
            //wait send request
            if(m_busy)
                return;
            m_ack = 1; //acknowledge
            break;
        case SIO_SEND_START:
            //wait for the start bit
            if (!m_xout)
                return;
            break;
        case SIO_SEND_BIT0:
        case SIO_SEND_BIT1:
        case SIO_SEND_BIT2:
        case SIO_SEND_BIT3:
        case SIO_SEND_BIT4:
        case SIO_SEND_BIT5:
        case SIO_SEND_BIT6:
        case SIO_SEND_BIT7:
            m_current_byte |= ((~m_xout)&1) << (m_state - SIO_SEND_BIT0);
            break;
        case SIO_SEND_PARITY:
            if (m_xout != calc_parity(m_current_byte))
                logerror("SIO %s: byte %d has wrong parity!\n", tag(), m_bytes_count);
            break;
        case SIO_SEND_STOP1:
        case SIO_SEND_STOP2:
            //receive stop bit
            m_ack = 0;
            break;
        }

        if (m_state == (SIO_SEND_PARITY + SIO_STOP_BIT))
        {
            //next byte
            m_bytes_count++;
            popmessage("Received %d bytes\n", m_bytes_count);
            m_state = SIO_WAIT;
            if (m_current_byte != SIO_EOT_BYTE)
                fwrite(&m_current_byte, 1);
            m_current_byte = 0;
        }
        else
        {
            m_state = get_next_state();
        }
    }
    else
    {
        m_din = m_xin = m_ack = 0;
    }
}
Exemplo n.º 11
0
int _sys_soc_suspend(s32_t ticks)
{
	enum power_states state;
	int pm_operation = SYS_PM_NOT_HANDLED;
	post_ops_done = 0;

	if ((ticks != K_FOREVER) && (ticks < MIN_TIME_TO_SUSPEND)) {
		printk("Not enough time for PM operations (" TIME_UNIT_STRING
		       ": %d).\n", ticks);
		return SYS_PM_NOT_HANDLED;
	}

	state = get_next_state();

	printk("Entering %s state\n", state_to_string(state));

	switch (state) {
	case SYS_POWER_STATE_CPU_LPS:
	case SYS_POWER_STATE_CPU_LPS_1:
	case SYS_POWER_STATE_CPU_LPS_2:
		/*
		 * A wake event is needed in the following cases:
		 *
		 * On Quark SE C1000 x86:
		 * - SYS_POWER_STATE_CPU_LPS:
		 *   The PIC timer is gated and cannot wake the core from
		 *   that state.
		 *
		 * - SYS_POWER_STATE_CPU_LPS_1:
		 *   If the ARC enables LPSS, the PIC timer will
		 *   not wake us up from SYS_POWER_STATE_CPU_LPS_1
		 *   which is mapped to C2.
		 *
		 *   As the ARC enables LPSS, it should as well take care of
		 *   setting up the relevant wake event or communicate
		 *   to the x86 that information.
		 *
		 * On Quark SE C1000 ARC:
		 * - SYS_POWER_STATE_CPU_LPS:
		 *   The ARC timer is gated and cannot wake the core from
		 *   that state.
		 *
		 * - SYS_POWER_STATE_CPU_LPS_1:
		 *   The ARC timer is gated and cannot wake the core from
		 *   that state.
		 */
		setup_wake_event();
		pm_operation = SYS_PM_LOW_POWER_STATE;
		_sys_soc_set_power_state(state);
		break;
	case SYS_POWER_STATE_DEEP_SLEEP:
	case SYS_POWER_STATE_DEEP_SLEEP_1:
		/* Don't need pm idle exit notification */
		_sys_soc_pm_idle_exit_notification_disable();

		pm_operation = SYS_PM_DEEP_SLEEP;
		do_soc_sleep(state);
		break;
	default:
		printk("State not supported\n");
		break;
	}

	if (pm_operation != SYS_PM_NOT_HANDLED) {
		if (!post_ops_done) {
			post_ops_done = 1;
			printk("Exiting %s state\n", state_to_string(state));
			_sys_soc_power_state_post_ops(state);
		}
	}

	return pm_operation;
}
Exemplo n.º 12
0
Token malpar_next_token(Buffer * sc_buf)
{
		Token t;         /*token to be returned */
		unsigned char c; /* input symbol */
		Buffer *lex_buf; /* temporary buffer for holding lexemes */       
		int accept = NOAS; /* Not Accepting State */
		int state = 0;     /* Start state in the Transition Table */
		int lexstart;      /* current lexeme start offset */ 
 static int forward;  /* current input char offset */                                       
/* 
forward is the offset from the beginning of the char buffer of the
input buffer (sc_buf) to the current character, which is to be processed
by the scanner.
lexstart is the offset from the beginning of the char buffer of the
input buffer (sc_buf) to the first character of the current lexeme,
which is being processed by the scanner.
*/ 
		
		
	   /* DECLARE YOUR VARIABLES HERE IF NEEDED */
 int VID_FLAG = 0; /*flag if start of VID reconised*/
 int FPL_FLAG = 0; /*flag for if FPL*/
 int DIL_FLAG = 0; /*flag for if DIL is reconised*/
 int OIL_FLAG = 0; /*flag for if octal literal is reconised*/
 int ZERO_FLAG = 0; /*flag for if first digit is a 0*/
 int NUM_FLAG = 0; /*flag if number of unknown type is reconised*/
 int i; /*generic counter for a for loop*/
 
 lexstart = sc_buf->addc_offset;
 forward = lexstart;
				
 while (1)/*constant used for infinite loop*/
 { 
	 c = sc_buf->ca_head[forward++];  /*may need to be ++forward if getting wierd errors*/

	 if (isalnum(c)==0 || c=='"')
	 {
		 switch (c)
		 {
		 case '"':
			 {
				 ca_setmark(sc_buf,forward);
				 c = sc_buf->ca_head[forward++];
				 if (c != '"') /*checks to see if it is an empty string*/
				 {
					 while (c = sc_buf->ca_head[forward++])
					 {
						 if (c=='\n' || c=='\r') /*potential weird string error*/
						 {
							 t.code = ERR_T;
							 if ((forward - ca_getmark(sc_buf)) >= 20)
							 {
								 for (i=0;i<17;i++)
								 {
									 t.attribute.err_lex[i] = sc_buf->ca_head[ca_getmark(sc_buf)+1];
								 }
								 t.attribute.err_lex[17]='.';
								 t.attribute.err_lex[18]='.';
								 t.attribute.err_lex[19]='.';
								 t.attribute.err_lex[20]='\0';
							 }
							 else
							 {
								 for (i=0;i<20;i++)
								 {
									 t.attribute.err_lex[i]= sc_buf->ca_head[ca_getmark(sc_buf)+1];
								 }
								 t.attribute.err_lex[20]='\0';
							 }
						 }
						 if (c == '"') 
						 {
							 t.attribute.str_offset = str_LTBL->addc_offset;
							 for (i=(ca_getmark(sc_buf)+1);i<forward;i++) /*forward may point to 1 past the quotation mark*/
							 {
								 ca_addc(str_LTBL,sc_buf->ca_head[i]);
							 }
							 ca_addc(str_LTBL,'\0'); /*end of string marker*/
							 t.code = STR_T;
						 }
					 }
				 }
				 else
				 {
					 t.code = ERR_T;
					 t.attribute.err_lex[0]='R';
					 t.attribute.err_lex[1]='U';
					 t.attribute.err_lex[2]='N';
					 t.attribute.err_lex[3]=' ';
					 t.attribute.err_lex[4]='T';
					 t.attribute.err_lex[5]='I';
					 t.attribute.err_lex[6]='M';
					 t.attribute.err_lex[7]='E';
					 t.attribute.err_lex[8]=' ';
					 t.attribute.err_lex[9]='E';
					 t.attribute.err_lex[10]='R';
					 t.attribute.err_lex[11]='R';
					 t.attribute.err_lex[12]='O';
					 t.attribute.err_lex[13]='R';
					 t.attribute.err_lex[14]=':';
					 t.attribute.err_lex[15]='\0';
				 }
				 break;
			 }
		 case '+':
			 {
				 t.code = ART_OP_T;
				 t.attribute.arr_op = PLUS;
				 break;
			 }

		 case '-':
			 {
				 t.code = ART_OP_T;
				 t.attribute.arr_op = MINUS;
				 break;
			 }

		 case '*':
			 {
				 t.code = ART_OP_T;
				 t.attribute.arr_op = MULT;
				 break;
			 }

		 case '/':
			 {
				 t.code = ART_OP_T;
				 t.attribute.arr_op = DIV;
				 break;
			 }

		 case '{':
			 {
				 t.code = LPR_T;
				 break;
			 }

		 case '}':
			 {
				 t.code = RPR_T;
				 break;
			 }

		 case '>':
			 {
				 t.code = REL_OP_T;
				 t.attribute.rel_op = GT;
				 break;
			 }

		 case '<':
			 {
				 t.code = REL_OP_T;
				 t.attribute.rel_op = LT;
				 break;
			 }

		 case '=':
			 {
				 if (sc_buf->ca_head[forward++] == '=')
				 {
					 t.code = REL_OP_T;
					 t.attribute.rel_op = EQ;
				 }
				 else
				 {
					 forward--;
					t.code = ASS_OP_T;
				 }
				 break;
			 }

		 case ' ':
			 {
				 //c = sc_buf->ca_head[forward++];
				 break;
			 }
		 case '.':
			 {	
				 c= sc_buf->ca_head[forward++];
				 if (c == 'A')
				 {	
					 c= sc_buf->ca_head[forward++];
					 if (c == 'N')
					 {
						 c = sc_buf->ca_head[forward++];
						 if (c =='D')
						 {
							 t.code = LOG_OP_T;
							 t.attribute.log_op = AND;
						 }
						 else
						 {
							 t.code = ERR_T;
						 }
					 }
					 else
					 {
						 t.code = ERR_T;
					 }
				 }
				 if (c == 'O')
				 {
					 c = sc_buf->ca_head[forward++];
					 if (c == 'R')
					 {
						 t.code = LOG_OP_T;
						 t.attribute.log_op = OR;
					 }
					 else 
					 {
						 t.code = ERR_T;
					 }
				 }
				 else
				 {
					 t.code = ERR_T;
				 }
				 break;
			 }
		 case '!':
			 {	
				 c = sc_buf->ca_head[forward++];
				 if (c != '<')
				 {
					 t.code = ERR_T;
					 forward--;
				 }
				 if (c == '=')
				 {
					 t.code = REL_OP_T;
					 t.attribute.rel_op = NE;
				 }
				 else
				 {
					 while (sc_buf->ca_head[forward++] != '\n'){} //move through buffer untill comment is done
				 }
				 break;
			 }
		 case ';':
			 {
				 t.code = EOS_T;
				 break;
			 }
		 case '(':
			 {
				 t.code = LBR_T;
				 break;
			 }
		 case ')':
			 {
				 t.code = RBR_T;
				 break;
			 }
		 case EOF:
			 {
				 t.code=SEOF_T;
				 break;
			 }
		 default:/* may pick up others like string, so wierd errors could come from here*/
			 {
				 t.code = ERR_T;
				 t.attribute.err_lex[0] = c;
				 t.attribute.err_lex[1] = '/0'; /*store end of string inidicator to the string*/
				 break;
			 }
		 }
	 }
	 else /*character is a digit or letter*/
		 /*final state machine*/
	 {
		 ca_setmark(sc_buf,forward);
		 
		 state = 0;
		 lexstart = ca_getmark(sc_buf);
		 state = get_next_state (state,c,&accept);

		 c = sc_buf->ca_head[forward++];

		 while (accept == NOAS)
			 {
				 state = get_next_state(state,c,&accept);
				 if (accept == NOAS) /*if statemet to check if sate has changed*/
				 {
					 c = sc_buf->ca_head[forward++];
				 }
			 }

		 lex_buf = b_create(sc_buf->capacity,sc_buf->inc_factor,sc_buf->mode);

		 if (state == (2||7||8||11))
		 {
			 forward = lexstart;
		 }
		 
		 c = sc_buf->ca_head[lexstart];

		 while (1)
		 {
			 switch (c)/*character most recently added in*/
			 {
			 case 0: /*[a-zA-Z]*/
				 {
					 /*VID or SVID or Keyword may need to take this out check w/ leland*/
					 if (iskeyword(lex_buf->ca_head) != FALSE) /*keyword token found*/
					 {
						 if (lex_buf->addc_offset>0)
						 {
							 forward--; /*character not added to lex_buf move pointer back 1*/
						 }
						 t.code = KW_T;
						 t.attribute.kwt_idx = iskeyword(lex_buf->ca_head); /*set attribute*/
					 }
					 else
					 {
						 /*check to see if any of the identifier flags have been checked*/
						 if (FPL_FLAG!=0||DIL_FLAG!=0||OIL_FLAG!=0||NUM_FLAG!=0)
						 {
							 if (FPL_FLAG == 1) 
							 {
								 if (lex_buf->addc_offset>0)
								 {
									 forward--; /*character not added to lex_buf move pointer back 1*/
								 }
								 reset_flags(&FPL_FLAG,&DIL_FLAG,&OIL_FLAG,&ZERO_FLAG,&VID_FLAG,&NUM_FLAG);
								 t=aa_table[8](lex_buf->ca_head);
							 }
							 if (DIL_FLAG == 1) 
							 {
								 if (lex_buf->addc_offset>0)
								 {
									 forward--; /*character not added to lex_buf move pointer back 1*/
								 }
								 reset_flags(&FPL_FLAG,&DIL_FLAG,&OIL_FLAG,&ZERO_FLAG,&VID_FLAG,&NUM_FLAG);
								 t=aa_table[7](lex_buf->ca_head);

							 }
							 if (OIL_FLAG == 1) 
							 {
								 if (lex_buf->addc_offset>0)
								 {
									 forward--; /*character not added to lex_buf move pointer back 1*/
								 }
								 reset_flags(&FPL_FLAG,&DIL_FLAG,&OIL_FLAG,&ZERO_FLAG,&VID_FLAG,&NUM_FLAG);
								 t=aa_table[12](lex_buf->ca_head);
							 }
							 if (ZERO_FLAG == 1) 
							 {
								 if (lex_buf->addc_offset>0)
								 {
									 forward--; /*character not added to lex_buf move pointer back 1*/
								 }
								 reset_flags(&FPL_FLAG,&DIL_FLAG,&OIL_FLAG,&ZERO_FLAG,&VID_FLAG,&NUM_FLAG);
								 t=aa_table[7](lex_buf->ca_head);
							 }
							 if (NUM_FLAG==1&&ZERO_FLAG==0) 
							 {
								 if (lex_buf->addc_offset>0)
								 {
									 forward--; /*character not added to lex_buf move pointer back 1*/
								 }
								 reset_flags(&FPL_FLAG,&DIL_FLAG,&OIL_FLAG,&ZERO_FLAG,&VID_FLAG,&NUM_FLAG);
								 t=aa_table[7](lex_buf->ca_head);
							 }

						 }
						 VID_FLAG = 1; /*set variable identifier flag*/
					 }
					 ca_addc(lex_buf,c);
					 break;
				 }
			 case 1: /*0*/
				 {
					 /*octal or DIL 0 or FPL 0*/
					 if (ZERO_FLAG==1)/*leading 0 and another digit*/
					 {
						 OIL_FLAG=1;
					 }
					 if (FPL_FLAG==0&&NUM_FLAG==0&&DIL_FLAG==0&&ZERO_FLAG==0)
					 {
						 ZERO_FLAG=1; /*identify as a numeric token starting with 0*/
					 }
					 if (NUM_FLAG==1&&ZERO_FLAG==0) /*number with no leading 0*/
					 {
						 /*could be FPL or DIL*/
					 }
					 if (VID_FLAG==1)
					 {
						 reset_flags(&FPL_FLAG,&DIL_FLAG,&OIL_FLAG,&ZERO_FLAG,&VID_FLAG,&NUM_FLAG);
						 VID_FLAG=1;
					 }
					 /*if FPL_FLAG is set it is known to be an FPL*/
					 ca_addc(lex_buf,c);
					 break;
				 }
			 case 2: /*[8-9]*/ 
				 {
					 if (ZERO_FLAG==1&&FPL_FLAG==0&&OIL_FLAG==0&&DIL_FLAG==0)/*leading 0 and no decimal place*/
					 {
						 reset_flags(&FPL_FLAG,&DIL_FLAG,&OIL_FLAG,&ZERO_FLAG,&VID_FLAG,&NUM_FLAG);
						 /*number is single 0*/
						 if (lex_buf->addc_offset > 0)
						 {
							 forward--;
						 }
						 t=aa_table[7](lex_buf->ca_head);
					 }
					 if (OIL_FLAG==1)
					 {
						 reset_flags(&FPL_FLAG,&DIL_FLAG,&OIL_FLAG,&ZERO_FLAG,&VID_FLAG,&NUM_FLAG); /*reset the flags*/
						 if (lex_buf->addc_offset > 0)
						 {
							 forward--; 
						 }
						 t=aa_table[12](lex_buf->ca_head);

					 }
					 if (NUM_FLAG==0&&DIL_FLAG==0&&FPL_FLAG==0) /*no preceeding digits*/
					 {
						 /*could be a DIL or FPL*/
						 NUM_FLAG=1;
					 }
					 if (VID_FLAG==1)/*is already known VID*/
					 {
						 reset_flags(&FPL_FLAG,&DIL_FLAG,&OIL_FLAG,&ZERO_FLAG,&VID_FLAG,&NUM_FLAG);
						 VID_FLAG=1;
					 }
					 ca_addc(lex_buf,c);
					 break;
				 }
			 case 3: /*[1-7]*/
				 {
					 if (ZERO_FLAG==1&&OIL_FLAG==1) /*already known oil*/
					 {
						 /*still oil*/
					 }
					 if (ZERO_FLAG==1&&OIL_FLAG==0)/*leading 0 with no other digits*/
					 {
						 OIL_FLAG=1;
					 }
					 if (NUM_FLAG==0&&FPL_FLAG==0&&DIL_FLAG==0)/*no numeric flags set*/
					 {
						 NUM_FLAG=1;
					 }
					 if (VID_FLAG==1)
					 {
						 reset_flags(&FPL_FLAG,&DIL_FLAG,&OIL_FLAG,&ZERO_FLAG,&VID_FLAG,&NUM_FLAG);
						 VID_FLAG=1;
					 }
					 ca_addc(lex_buf,c);
					 break;
				 }
			 case 4: /*.*/
				 {
					 if (NUM_FLAG==0&&ZERO_FLAG==0&&DIL_FLAG==0&&FPL_FLAG==0)/*if no numeric flags are set*/
					 {
						 reset_flags(&FPL_FLAG,&DIL_FLAG,&OIL_FLAG,&ZERO_FLAG,&VID_FLAG,&NUM_FLAG);
						 ca_addc(lex_buf,c);
						 t=aa_table[9](lex_buf->ca_head);
					 }
					 if (OIL_FLAG==1) /*if known OIL*/
					 {
						 reset_flags(&FPL_FLAG,&DIL_FLAG,&OIL_FLAG,&ZERO_FLAG,&VID_FLAG,&NUM_FLAG);
						 ca_addc(lex_buf,c);
						 t=aa_table[9](lex_buf->ca_head);
					 }
					  if (FPL_FLAG==1) /*if known FPL*/
					 {
						 reset_flags(&FPL_FLAG,&DIL_FLAG,&OIL_FLAG,&ZERO_FLAG,&VID_FLAG,&NUM_FLAG);
						 ca_addc(lex_buf,c);
						 t=aa_table[9](lex_buf->ca_head);
					 }
					 if ((DIL_FLAG==1||NUM_FLAG==1)&&FPL_FLAG==0)/*if identified as a DIL or NUM already*/
					 {
						 FPL_FLAG=1;
					 }
					 if (VID_FLAG==1) /*if VID*/
					 {
						 if (lex_buf->addc_offset>0)
						 {
							 forward--; /*character not added to lex_buf move pointer back 1*/
						 }
						 reset_flags(&FPL_FLAG,&DIL_FLAG,&OIL_FLAG,&ZERO_FLAG,&VID_FLAG,&NUM_FLAG);
						 t=aa_table[3](lex_buf->ca_head);
					 }
					 ca_addc(lex_buf,c);
					 break;
				 }
			 case 5: /*#*/
				 {
					 if (VID_FLAG==0&&FPL_FLAG==0&&DIL_FLAG==0&&OIL_FLAG==0&&ZERO_FLAG==0)
					 {
						 ca_addc(lex_buf,c);
						 t=aa_table[9](lex_buf->ca_head);
					 }
					 if (FPL_FLAG==1)
					 {
						 if(lex_buf->addc_offset>0)
						 {
							 forward--;
						 }
						 t=aa_table[8](lex_buf->ca_head);
					 }
					 if (VID_FLAG==1)
					 {
						 reset_flags(&FPL_FLAG,&DIL_FLAG,&OIL_FLAG,&ZERO_FLAG,&VID_FLAG,&NUM_FLAG);
						 ca_addc(lex_buf,c);
						 t=aa_table[2](lex_buf->ca_head);
					 }
					 break;
				 }
			 case 6: /*other*/
				 {
					 if (lex_buf->addc_offset!=0)
					 {
						 sc_buf->addc_offset--; /*character never written to lex_buf set pointer back 1*/
					 }
					 if ((c==';'||c ==' ')&&VID_FLAG==1)
					 {
						 reset_flags(&FPL_FLAG,&DIL_FLAG,&OIL_FLAG,&ZERO_FLAG,&VID_FLAG,&NUM_FLAG);
						 t = aa_table[2](lex_buf->ca_head);
					 }
					 if ((c==';'||c ==' ')&&FPL_FLAG==1)
					 {
						 reset_flags(&FPL_FLAG,&DIL_FLAG,&OIL_FLAG,&ZERO_FLAG,&VID_FLAG,&NUM_FLAG);
						 t=aa_table[8](lex_buf->ca_head);
					 }
					 if ((c==';'||c ==' ')&&DIL_FLAG==1)
					 {
						 reset_flags(&FPL_FLAG,&DIL_FLAG,&OIL_FLAG,&ZERO_FLAG,&VID_FLAG,&NUM_FLAG);
						 t=aa_table[7](lex_buf->ca_head);
					 }
					 if ((c==';'||c ==' ')&&OIL_FLAG==1)
					 {
						 reset_flags(&FPL_FLAG,&DIL_FLAG,&OIL_FLAG,&ZERO_FLAG,&VID_FLAG,&NUM_FLAG);
						 t=aa_table[11](lex_buf->ca_head);
					 }
					 if ((c==';'||c ==' ')&&NUM_FLAG==1)
					 {
						 reset_flags(&FPL_FLAG,&DIL_FLAG,&OIL_FLAG,&ZERO_FLAG,&VID_FLAG,&NUM_FLAG);
						 t=aa_table[11](lex_buf->ca_head);
					 }
					 if ((c==';'||c ==' ')&&ZERO_FLAG==1)
					 {
						 reset_flags(&FPL_FLAG,&DIL_FLAG,&OIL_FLAG,&ZERO_FLAG,&VID_FLAG,&NUM_FLAG);
						 t=aa_table[7](lex_buf->ca_head);
					 }
					 else
					 {
						 reset_flags(&FPL_FLAG,&DIL_FLAG,&OIL_FLAG,&ZERO_FLAG,&VID_FLAG,&NUM_FLAG);
						 ca_addc(lex_buf,c);
						 t=aa_table[9](lex_buf->ca_head);
					 }
					 break;
				 }
			 }
			 c=(lex_buf,sc_buf->ca_head[forward++]);/*add next character to the buffer*/
		 }
	 }
	 b_destroy(lex_buf);
	 return t;               
   }//end while(1)
}
Exemplo n.º 13
0
//==========================================================================================================
// Mimimize the DFA using Myphill-Nerode based algorithm. The algorithm consider all state pairs, marking
// them as non-equivalent if possible. When finished, those not marked are put in the same new state.
// Steps:
// 1. Mark as non-equivalent those pairs with different accepting values
// 2. Iteratively mark pairs that for any input symbol go to a marked pair (or transition defined just for
//    one of them on that symbol).
// 3. Combine unmarked pairs to form new states.
// 4. Write the new transitions, mark accepting new states
//==========================================================================================================
void DFA::minimize() {
    //------------------------------------------------------------------------------------------------------
    // Create the pairs and do initial mark (true means pair is non-equivalent)
    //------------------------------------------------------------------------------------------------------
    vector<bool*> pairs;
    int num_states = get_num_states();
    
    for(int i = 0; i < num_states - 1; ++i) {
        pairs.push_back(new bool[num_states - i - 1]);
        pairs[i] -= (i+1); // This ugly trick enables accessing pairs[i][j], but actually using just half the memory
        
        for(int j = i+1; j < num_states; ++j) {
            pairs[i][j] = (accepting[i] != accepting[j]);
        }
    }
    
    //------------------------------------------------------------------------------------------------------
    // Mark until an iteration where no changes are made
    //------------------------------------------------------------------------------------------------------
    bool changed = true;
    while(changed) {
        changed = false;
        
        for(int i = 0; i < num_states - 1; ++i) {
            for(int j = i+1; j < num_states; ++j) {
                if(pairs[i][j]) continue; // Pair already marked
                
                for(int sym = 0; sym < NUM_SYMBOLS; ++sym) {
                    int x = get_next_state(i, sym), y = get_next_state(j, sym);
                    if(x == y) continue;

                    sort_pair(x,y); // Must have the smaller index first to access pairs table
                    
                    if(x == -1 or pairs[x][y]) {
                        pairs[i][j] = true;
                        changed = true;
                    }
                } // for each symbol
            }
        }
    }
    
    //------------------------------------------------------------------------------------------------------
    // Combine states:
    // 1. A new state is a set of old states which are equivalent
    // 2. If an old state is not equivalent to any other state, a new state is created that contains only it
    // 3. After adding a pair {i,j} (i < j}, there's no need to look at pairs {j,x} (j < x), because pair
    // {i,x} must have already been added.
    //------------------------------------------------------------------------------------------------------
    vector<vector<int>> new_states;
    vector<int> old_to_new(num_states, -1);
    set<int> added_states;
    
    for(int i = 0; i < num_states - 1; ++i) {
        if(added_states.count(i) != 0) continue;
        
        new_states.push_back({i});
        old_to_new[i] = new_states.size() - 1;
        
        for(int j = i+1; j < num_states; ++j) {
            if(not pairs[i][j]) {
                new_states.back().push_back(j);
                old_to_new[j] = new_states.size() - 1;
                added_states.insert(j);
            }
        }
    }
    
    if(added_states.empty()) // No minimization occurred
        return;
    
    // If the last state wasn't combined with any other state, add a new state that contains only it;
    // This is needed because the last state has no entry in the pairs table as a first of any pair
    if(added_states.count(num_states-1) == 0)
        new_states.push_back({num_states-1});
    
    //------------------------------------------------------------------------------------------------------
    // Write new transitions and mark accepting new states. Then replace the old DFA with the new one.
    //------------------------------------------------------------------------------------------------------
    vector<int> new_accepting(new_states.size(), -1);
    vector<vector<int>> new_table(new_states.size(), vector<int>(NUM_SYMBOLS, -1));
    
    for(int i = 0; i < new_states.size(); ++i) {
        for(auto s: new_states[i])
            if(accepting[s] != accepting[new_states[i][0]])
                throw string("DFA states found to be equivalent yet have different accepting values");
        
        new_accepting[i] = accepting[new_states[i][0]]; // If the first is accepting they all are, and vice versa
        
        for(int sym = 0; sym < NUM_SYMBOLS; ++sym) {
            // Since all old states in this new states are equivalent, need to check only one
            int old_next_state = get_next_state(new_states[i][0], sym);
            if(old_next_state != -1)
                new_table[i][sym] = old_to_new[old_next_state];
        }
    }
    
    accepting = new_accepting;
    table = new_table;
    

    //------------------------------------------------------------------------------------------------------
    // Free memory
    //------------------------------------------------------------------------------------------------------
    for(int i = 0; i < num_states - 1; ++i) {
        delete (pairs[i] + i + 1);
    }    
} // minimize()