Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Алгоритмы и структуры (программирование).docx
Скачиваний:
21
Добавлен:
19.03.2015
Размер:
1.36 Mб
Скачать

Файл infix2postfix.H

#ifndef INFIX2POSTFIX_H

#define INFIX2POSTFIX_H

/* типы лексем: константы, операции, имена переменных */

typedef enum { tt_CONST, tt_OPER, tt_ID } TokenType;

/* виды операций: сложение, вычитание, умножение, деление,

* левая и правая скобки */

typedef enum {op_ADD='+', op_SUB='-', op_MUL='*', op_DIV='/', op_LBR='(', op_RBR=')'} OperType;

/* максимальная длина имени переменной */

#define MAX_ID_LEN 40

/* тип - лексема */

typedef struct {

TokenType ttype;

union Value {

/* с лексемой связано одно из следующих значений */

int inum;

OperType otype;

char id[MAX_ID_LEN + 1];

} tvalue;

int num;

} Token;

//It converts string (s) to array of tokens

//return 0 in case of success

// -1 in case of wrong format of any token

// -2 in case of it can not resize array

int tokenize(const char *s, Token **tokens, int *len);

//For converting from infix form to postfix

//return 0 in case of success

// -1 unknow type of operator

// -2 unknow type of token

// -3 stack is over full

// -4 memory error: cant resize array

int infix2postfix(const Token *infix, int in_len, Token **postfix, int *out_len);

#endif

Файл unit_tests.C

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

#include <ctype.h>

#include "infix2postfix.h"

#define IN_STR_SIZE 200

char strC[IN_STR_SIZE] = "";

void out_TokensArray(Token **t_array, int *len)

{

memset(strC,0,sizeof(strC)); //erase strC

char strT[IN_STR_SIZE] = "";

for(int i=0; i<(*len); i++)

switch((*t_array)[i].ttype)

{

case tt_CONST:

printf("%d ", (*t_array)[i].tvalue.inum);

sprintf(strT, "%d ", (*t_array)[i].tvalue.inum);

strcat(strC, strT);

break;

case tt_OPER:

printf("%c ", (*t_array)[i].tvalue.otype);

sprintf(strT, "%c ", (*t_array)[i].tvalue.otype);

strcat(strC, strT);

break;

case tt_ID:

printf("%s ", (*t_array)[i].tvalue.id);

sprintf(strT, "%s ", (*t_array)[i].tvalue.id);

strcat(strC, strT);

break;

}

printf("\n");

}

void covert_i2p(const char *s)

{

printf(" ORIGINAL INPUTED STRING: \"%s\"", s);

Token *infix;

int in_len = 0;

switch(tokenize(s, &infix, &in_len))

{

case 0:

printf("\n INFIX: ");

out_TokensArray(&infix, &in_len);

Token *postfix;

int out_len = 0;

switch(infix2postfix(infix, in_len, &postfix, &out_len))

{

case 0:

printf(" POSTFIX: ");

out_TokensArray(&postfix, &out_len);

break;

case -1:

printf("\nError: Unkown type of operator\n");

strcpy(strC, "Error");

break;

case -2:

printf("\nError: Unkown type of token\n");

strcpy(strC, "Error");

break;

case -3:

printf("\nError: Memory error: Stack is over full\n");

strcpy(strC, "Error");

break;

case -4:

printf("\nError: Memory error: Cant resize array\n");

strcpy(strC, "Error");

break;

default:

printf("\nError: Unknown error\n");

strcpy(strC, "Error");

break;

}

free(postfix);

break;

case -1:

printf("\nError: Format of token is incorrect\n");

strcpy(strC, "Error");

break;

case -2:

printf("\nError: Memory error: Cant resize array\n");

strcpy(strC, "Error");

break;

default:

printf("\nError: Unknown error\n");

strcpy(strC, "Error");

break;

}

free(infix);

}

void test(char *headline, char *in_str, char *expect_str)

{

printf("\n%s\n", headline);

covert_i2p(in_str);

printf(" EXPECTED: %s\n", expect_str);

if(strcmp(strC, expect_str) == 0)

printf(" PASSED");

else

printf(" DONT MATCH!!!");

printf("\nNext... press <Enter>\n");

getchar();

}

int main(int argc, char* argv[])

{

printf("\nUnit tests for infix2postfix.h is run\n");

printf(" Press <Enter> for the full test script...\n");

printf(" Input string and press <Enter> if you want to do test with this string...\n");

char s[IN_STR_SIZE];

gets(s);

if(strlen(s) == 0)

{

printf("Test script is running...\n");

//test("", "", " ");

test("Does it understand correct tokens?", "2 + 123 - ( abc * abc123 ) / a1b2c3", "2 123 + abc abc123 * a1b2c3 / - ");

test("Will it be worked correct with spaces/tabs at the begin/end?", " 2 + 7 ", "2 7 + ");

test("Can it work with one token?", "7", "7 ");

test("Will it return error in case of wrong format of token?", "a + 987bcd", "Error");

test("Will it return error in case of unknown operator?", "5 ^ 9", "Error");

test("Some random test 1", "3 + 4 * 2 / ( 1 - 5 )", "3 4 2 * 1 5 - / + ");

test("Some random test 2", "( 1 + 23 * 4 ) * ( 5 - 1 )", "1 23 4 * + 5 1 - * ");

test("Some random test 3", "7 + ( 5 - 2 ) * 4", "7 5 2 - 4 * + ");

test("Some random test 4", "8 / ( 2 + 2 )", "8 2 2 + / ");

test("Some random test 5", "( 8 / ( 2 + 2 ) )", "8 2 2 + / ");

printf("Test script is over\n");

}

else

covert_i2p(s);

printf("\nPress <Enter> for exit");

getchar();

return 0;

}