Lymisy Ответов: 2

Как вставить идентификатор в таблицу символов или хэш-таблицу на языке Си?


#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include "type.h"

FILE *file;

char buffer[1000 + 1];  // + 1 for the null terminator.
char tokens[1000 + 1];

int index = 0;
int line_num = 0;
int line_row = 0;
int line_column = 0;
int max_token = 0;

void show_table();
int check_identifier();


typedef enum
{
	WORD,       // Consists of a string of letters.
	SEPARATOR,  // Consists of a single separator.
	SPACE,      // Consists of a single space character.
	NELI,
	NUMBER,
	OPERATOR,
	EQUALIZER,
	UNKNOWN,    // Consists of a single unknown character.
	IDENT,
	ENFI,
} token_type;

token_type token;


char predirect[][12] = { "use", "system",  "label",  "translate"};

char header[][12] = {"haven","s_type","m_type", "n_type", "io" };

char data_type[][12] = { "mark",  "hollow",  "decii",  "decii", "quad", "num", "strand"};

char data_tool[][12] = { "loop",  "during",  "set",  "check", "else", "compare", "pare", "list", "construct", "log", "class", "public", "private",
"return", "read", "write", "file", "return", "merge", "message", "elem", "object"};

char data_modifiers[][12] = { "extern","static", "register","short", "long", "signed", "unsigned"};


void library(char t[])
{
	int i;

	for (i = 0; i < 5; i++)
	{
		if (strcmp(t, predirect[i]) == 0)
		{
			printf(" %03d:   %s\t              Predirect\n", line_num, t);
			return;
		}
	}
	for (i = 0; i < 6; i++)
	{
		if (strcmp(t, header[i]) == 0)
		{
			printf(" %03d:   %s\t              Header\n", line_num, t);
			return;
		}
	}
	for (i = 0; i < 8; i++)
	{
		if (strcmp(t, data_type[i]) == 0)
		{			
			printf(" %03d:   %s\t              Data_type\n", line_num, t);
			return;
		}
	}
	for (i = 0; i < 24; i++)
	{
		if (strcmp(t, data_tool[i]) == 0)
		{
			printf(" %03d:   %s\t              Data_tool\n", line_num, t);
			return;
		}
	}
	for (i = 0; i < 8; i++)
	{
		if (strcmp(t, data_modifiers[i]) == 0)
		{
			printf(" %03d:   %s\t              Data_modifiers\n", line_num, t);
			return;
		}
	}
	check_identifier(buffer);
}

int check_identifier()
{
	int i = 0;

	line_num++;

	strcpy(tokens, buffer);
	printf(" %03d:   %s\t              Identifier\n", line_num, tokens);

	return IDENT;
}

get_token(FILE *file, char *const buf, const int max_token)
{
	int length = 0;
	int ch;

	if ((ch = fgetc(file)) == EOF) 
	{
		return ENFI;
	}

	buffer[length++] = ch;
	buffer[length] = 0;                        /* In case 'ch' is separator, space, or unknown. */

	if (seperator(ch))
	{
		return SEPARATOR;
	}

	if (space(ch))
	{
		return SPACE;
	}

	if (neli(ch))
	{
		return NELI;
	}
	if (number(ch))
	{
		return NUMBER;
	}
	if (operators(ch))
	{
		return OPERATOR;
	}

	if (equalizer(ch))
	{
		return EQUALIZER;
	}

	if (!letter(ch))
	{
		return UNKNOWN;
	}

	while ((ch = fgetc(file)) != EOF && length < max_token) 
	{
		// If we see a non-letter, put it back on the input stream.
		if (!letter(ch)) 
		{
			ungetc(ch, file);
			break;
		}
		buffer[length++] = ch;
	}
	buffer[length] = 0;

	return WORD;
}

int main()
{
	file = fopen("source.txt", "r");	

	while ((token = get_token(file, buffer, 1000 + 1)) != ENFI)
	{
		line_num++;

		switch (token)
		{
		case SEPARATOR:
			printf(" %03d:   %s\t              Separator\n", line_num, buffer);
			break;
		case SPACE:
			printf("", buffer);
			break;
		case NELI:
			printf("%s", buffer);
			break;
		case NUMBER:
			printf(" %03d:   %s\t              Number\n", line_num, buffer);
			break;
		case OPERATOR:
			printf(" %03d:   %s\t              Operator\n", line_num, buffer);
			break;
		case EQUALIZER:
			printf(" %03d:   %s\t              Equalizer\n", line_num, buffer);
			break;
		case WORD:
			library(buffer);
			break;
		case UNKNOWN:
			printf(" %03d: \tASCII value %d       \tUnknown\n", line_num, buffer[0]);
			break;
		default:
			break;
		}
	}

	if (IDENT)
	{
		show_table();
	}

	return 0;
}

void show_table()
{
	int i = 0;
	int j = 0;

	line_row++;

	printf(" _________________________________________symbol_table______________\n");
	printf(" Id         Ident            type                                   \n");
	printf(" -------------------------------------------------------------------\n");

	printf(" %03d:   %s\t              Identifier\n", line_row, tokens);
}


Что я уже пробовал:

Я пытаюсь поместить идентификаторы в хэш-таблицу или таблицу символов.

В функции library(), если ни один из strcmps не является истинным, то слово
левый-это идентификатор. Этот идентификатор должен быть помещен в хэш-таблицу. Первоначально я пытался поместить возвращаемый идентификатор здесь (и добавил случай для IDENT в main), но независимо от того, что я пробовал, идентификаторы не будут распечатываться вместе с остальной информацией при печати вывода или возврате значения.

По какой-то причине мне пришлось создать новую функцию для идентификаторов check_identifiers (), чтобы она позволяла печатать идентификаторы и возвращать значение. Он все еще не позволяет использовать case, поэтому я помещаю оператор if в main, который я использую для печати show_table. Попробовал использовать token == IDENT в операторе if, но он не позволяет распечатать show_table. Мне трудно понять, как получить информацию об идентификаторе, чтобы связать ее с начальной вставкой таблицы.

2 Ответов

Рейтинг:
0

Richard MacCutchan

if (IDENT)
{
    show_table();
}	

Это всегда будет верно, так как IDENT-ненулевое значение. Так и должно быть
if (token == IDENT)
{
    show_table();
}


Lymisy

Верхний пример позволяет show table распечатать showtable, в то время как второй пример этого не делает.

Richard MacCutchan

Как я уже сказал, верхний пример будет всегда распечатать showtable Это происходит потому, что ценность enum пункт IDENT является ненулевым, и, таким образом, if утверждение всегда будет истинным.

Однако не совсем ясно, в чем именно заключается ваша проблема.

Lymisy

Я не уверен, где я должен поместить функцию вставки для хэш-таблицы. Я знаю, что идентификаторы или переменные, а также имена переменных функций входят в таблицу. Вот почему я подошел к этому пути так далеко, но не уверен, где их вставить.

Richard MacCutchan

Извините, но я не могу помочь, так как не знаю, что пытается сделать программа.

Рейтинг:
0

KarstenK

Ваши переменные данных-это фиксированная память, и когда вы хотите ее изменить, вы должны выделить некоторую (большую) память, чем memcopy исходных данных и чем добавить данные в правильные места.

То же самое можно сделать и с перечислением, но вам тоже нужен некоторый буфер. Поэтому работа с динамическим массивом типа int.