Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 06.12.2009, 15:43   #1
EniOk
Пользователь
 
Аватар для EniOk
 
Регистрация: 07.06.2009
Сообщений: 43
По умолчанию Лексический анализатор С++

Прога должна разбивать текст на лексемки и дальше возиться с ними отдавать их другой...
Это есть долгосрок и мне досталось распознавание целых десятичных констант. То есть есть строка. Из нее надо вычленить все лексемы такого типа.

То, что я написал почти работает...

Вот класс:
Код:
class CScanner
{
private:
	PCHAR pCurrentPosition;
	PCHAR pStopScanSymbol;
	char *String;
public:
	CScanner(char*);
	LEXEME GetNextLexem();
};
CScanner::CScanner(char *ScanningString)
{
	CScanner::String = ScanningString;
	CScanner::pCurrentPosition = ScanningString;
	CScanner::pStopScanSymbol = ScanningString + strlen(ScanningString);
}

LEXEME CScanner::GetNextLexem()
{
	LEXEME Lexem;
	Lexem.Token.Buffer = NULL;
	Lexem.Token.Length = 0;
	Lexem.Class = C_CLASS_UNKNOWN;
	Lexem.Subclass = C_SUBCLASS_STANDARD;
	Lexem.Value  = C_UNKNOWN;
	Lexem.nLine = 1;
	while (CScanner::pCurrentPosition < CScanner::pStopScanSymbol)
	{
		if (*(CScanner::pCurrentPosition ) == ' '||
			*(CScanner::pCurrentPosition ) == '	') CScanner::pCurrentPosition++;
		if (*(CScanner::pCurrentPosition ) == '\n') 
		{
			Lexem.nLine++;
			CScanner::pCurrentPosition++;
		}
		if (isdigit(*(CScanner::pCurrentPosition)))
		{
			printf("ISDIGIT;");
			Lexem.Class = C_CLASS_CONSTANT;
			Lexem.Subclass = C_SUBCLASS_INTEGER;
			Lexem.Value = C_DECIMAL;
			Lexem.Token.Buffer = CScanner::pCurrentPosition;
			Lexem.Token.Length = 0;
			if (*(CScanner::pCurrentPosition) == '0')
			{
				Lexem.Token.Length = 1;
				printf("ISNULL;");
				if (*((CScanner::pCurrentPosition)+1)=='x' ||
					*((CScanner::pCurrentPosition)+1)=='X')
				{
					printf("NEXTIS'X';");
					Lexem.Class = C_CLASS_CONSTANT;
					Lexem.Subclass = C_SUBCLASS_INTEGER;
					Lexem.Value = C_HEXADECIMAL;
					while (((*(CScanner::pCurrentPosition) )!= ' ' ||
						(*(CScanner::pCurrentPosition))!= '	' ||
						(*(CScanner::pCurrentPosition))!= '\n') &&
						(CScanner::pCurrentPosition < CScanner::pStopScanSymbol))
						CScanner::pCurrentPosition++; // ищем конец не своей лексемы

					return Lexem;
				}//Сюда надо вставить код для шестнадцатиричных констант
				if (((*((CScanner::pCurrentPosition)+1)) == ' ' ||
					(*((CScanner::pCurrentPosition)+1)) == '	'||
					(*((CScanner::pCurrentPosition)+1)) == '\n')||
						(((CScanner::pCurrentPosition)+1) < CScanner::pStopScanSymbol))
				{
					printf("NEXTISWHITESPACE;");
					CScanner::pCurrentPosition++;
					return Lexem;
				}
				CScanner::pCurrentPosition++;
			}
			else
			{
				printf("ISN'TNULL;");
				for (CScanner::pCurrentPosition; 
				CScanner::pCurrentPosition < CScanner::pStopScanSymbol;
				CScanner::pCurrentPosition++)
				{
					if (*(CScanner::pCurrentPosition) == '.')
					{
						printf("ISDOT;");
					Lexem.Class = C_CLASS_CONSTANT;
					Lexem.Subclass = C_SUBCLASS_FLOATING_POINT;
					while ((*(CScanner::pCurrentPosition) != ' ' ||
						*(CScanner::pCurrentPosition) != '	' ||
						*(CScanner::pCurrentPosition) != '\n') &&
						((CScanner::pCurrentPosition) < CScanner::pStopScanSymbol))
						CScanner::pCurrentPosition++; // ищем конец не своей лексемы
					return Lexem; //Сюда код для дробных чисел вместо этого блока
					}
					if (isdigit(*(CScanner::pCurrentPosition)))
					{Lexem.Token.Length++; printf("ISDIGIT;");}
					
					if (*(CScanner::pCurrentPosition) == ' '||
						*(CScanner::pCurrentPosition) == '	'||
						*(CScanner::pCurrentPosition) == '\n'||
						((CScanner::pCurrentPosition) == CScanner::pStopScanSymbol))
					{return Lexem; printf("ISWHITESPACE;");}
				}
			}
		}
		printf("ISN'TDIGIT;");
		CScanner::pCurrentPosition++;
	}
	return Lexem;
}

И main()
Код:
void main(IN int argc, IN char *argv[])
{
	HANDLE hFile, hMapping;
	PVOID View;
	DWORD Length;
// Тут удалить до след. комента
	char name[] ="C:\\1.txt" ;
	argv[1] = name;
//Открытие файла
	if( !CreateReadFileView(
			argv[1],
			&hFile,
			&hMapping,
			(PVOID *)&View,
			&Length )) {
				printf ("Input error - error opening of ''%s''", argv[1]);//ошибка открытия файла с именем argv[1]
	}
//Обработка входного файла, образ которого размещается в памяти по
//адресам [View, View + Length – 1]
	char *temp = (PCHAR) View;
	printf("%s",temp);
	CScanner Scanner(temp);
	
	LEXEME Lex1;
	while ((Lex1= Scanner.GetNextLexem()).Class != C_CLASS_UNKNOWN)
	{
	printf("\n ''%.*s''", Lex1.Token.Length, Lex1.Token.Buffer);
	printf(" Class: %i, #line: %i, subclass: %i, value: %i", Lex1.Class, Lex1.nLine, Lex1.Subclass, Lex1.Value);
	}
	getch();
//Закрытие файла
		CloseFileView(
			&hFile,
			&hMapping,
			(PVOID *)&View );
}
Проблема возникает при подаче на нее
Код:
1
2
3
09
0x1
работает ровно до 09 и дальше мучается...
Помогите понять где ошибка плз)
EniOk вне форума Ответить с цитированием
Старый 06.12.2009, 15:43   #2
EniOk
Пользователь
 
Аватар для EniOk
 
Регистрация: 07.06.2009
Сообщений: 43
По умолчанию

Функции, используемые:
Код:
BOOL CreateReadFileView(
	IN	LPCTSTR	FileName,
	OUT	PHANDLE	phFile,
	OUT	PHANDLE	phFileMapping,
	OUT	PVOID	*ppFileView,
	OUT	PDWORD	pFileLength)
{
	HANDLE	hFile;
	HANDLE	hFileMapping;
	PVOID	pFileView;

	hFile = CreateFile(
		FileName,
		GENERIC_READ,
		FILE_SHARE_READ,
		NULL,
		OPEN_EXISTING, 		0,
		NULL);
	if( INVALID_HANDLE_VALUE == hFile )
		return FALSE;

	hFileMapping = CreateFileMapping(
		hFile,
		NULL,
		PAGE_READONLY,
		0,
		0,
		NULL);

	if(hFileMapping == NULL)
		goto CLOSE_FILE;

	pFileView = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0);
	if(pFileView == NULL)
		goto CLOSE_FILE_MAPPING;

	*phFile = hFile;
	*phFileMapping = hFileMapping;
	*ppFileView = pFileView;
	*pFileLength = GetFileSize( hFile, NULL );

	return TRUE;

CLOSE_FILE_MAPPING:
	CloseHandle( hFileMapping );

CLOSE_FILE:
	CloseHandle( hFile );
	return FALSE;
}

//Функция закрывает образ файла в памяти
VOID
CloseFileView(
	IN PHANDLE	phFile,
	IN PHANDLE	phFileMapping,
	IN PVOID	*ppFileView
	)
{
	if( *ppFileView != NULL ) { 		UnmapViewOfFile( *ppFileView );
		*ppFileView = NULL;
	}
	if( *phFileMapping != NULL ) {
		CloseHandle( *phFileMapping );
		*phFileMapping = NULL;
	}
	if( *phFile != INVALID_HANDLE_VALUE ) {
		SetEndOfFile( *phFile );
		CloseHandle( *phFile );
		*phFile = INVALID_HANDLE_VALUE;
	}
}
Типы данных:
Код:
typedef enum {
	C_UNKNOWN,
//Значения ключевых слов
	C_ASM,
	C_AUTO,
	C_BASED,
	C_BREAK,
	C_CASE,
	C_CDECL,
	C_CHAR,
	C_CONST,
	C_CONTINUE,
	C_DECLSPEC,
	C_DEFAULT,
	C_DLLEXPORT,
	C_DLLIMPORT,
	C_DO,
	C_DOUBLE,
	C_ELSE,
	C_ENUM,
	C_EXCEPT,
	C_EXTERN,
	C_FASTCALL,
	C_FINALLY,
	C_FLOAT,
	C_FOR,
	C_GOTO,
	C_IF,
	C_INLINE,
	C_INT,
	C_INT16,
	C_INT32,
	C_INT64,
	C_INT8,
	C_LONG,
	C_NAKED,
	C_REGISTER,
	C_RETURN,
	C_SHORT,
	C_SIGNED,
	C_SIZEOF,
	C_STATIC,
	C_STDCALL,
	C_STRUCT,
	C_SWITCH,
	C_THREAD,
	C_TRY,
	C_TYPEDEF,
	C_UNION,
	C_UNSIGNED,
	C_VOID,
	C_VOLATILE,
	C_WHILE,
//Значения констант
	C_OCTAL,
	C_DECIMAL,
	C_HEXADECIMAL,
//Значения лексем операций
	C_FIELD_MEMBER,		//	.
	C_FIELD_PTR,		//	->
	C_INCREMENT,		//	++
	C_DECREMENT,		//	--
	C_AND,				//	&
	C_MUL,				//	*
	C_ADD,				//	+
	C_SUB,				//	-
	C_NOT,				//	~
	C_LNOT,				//	!
	C_DIV,				//	/
	C_REMN,				//	%
	C_LEFT_SHIFT,		//	<<
	C_RIGHT_SHIFT,		//	>>
	C_LESS,				//	<
	C_GREAT,			//	>
	C_LESS_EQUAL,		//	<=
	C_GREAT_EQUAL,		//	>=
	C_EQUAL,			//	==
	C_NOT_EQUAL,		//	!=
	C_XOR,				//	^
	C_OR,				//	|
	C_LAND,				//	&&
	C_LOR,				//	||
	C_QUESTION,			//	?
	C_COLON,			//	:
	C_ASSIGN,			//	=
	C_MUL_ASSIGN,		//	*=
	C_DIV_ASSIGN,		//	/=
	C_REMN_ASSIGN,		//	%=
	C_ADD_ASSIGN,		//	+=
	C_SUB_ASSIGN,		//	-=
	C_LEFT_SHIFT_ASSIGN,		//	<<= 
	C_RIGHT_SHIFT_ASSIGN,		//	>>=
	C_AND_ASSIGN,		//	&=
	C_XOR_ASSIGN,		//	^=
	C_OR_ASSIGN,		//	|=
	C_POUND,			//	#
	C_DOUBLE_POUND,		//	##
	//Значения лексем пунктуации
	C_LEFT_PARENTHESIS,		//	(
	C_RIGHT_PARENTHESIS,	//	)
	C_COMMA,				//	,
	C_SEMICOLON,			//	;
	C_LEFT_SQUARE_BRACKET,	//	[
	C_RIGHT_SQUARE_BRACKET,	//	]
	C_LEFT_BRACE,			//	{
	C_RIGHT_BRACE,			//	}
	C_THREE_PERIOD			//	...
	//	C_DOUBLE_QUOTATION_MARK,//	"
} C_VALUE;

typedef struct _TOKEN {
	PCSTR	Buffer;
	ULONG	Length;
} TOKEN, *PTOKEN;

typedef struct _LEXEME {
	TOKEN	Token;
	ULONG	nLine;
	ULONG	Class;
	ULONG	Subclass;
	ULONG	Value;
} LEXEME, *PLEXEME;

//Определение классов, подклассов и значений лексем
typedef enum {
	C_CLASS_UNKNOWN,
	C_CLASS_ERROR,		//Обозначает лексему, не относящуюся к данному языку
	C_CLASS_IDENTIFIER,
	C_CLASS_CONSTANT,
	C_CLASS_PUNCTUATOR,
	C_CLASS_OPERATION,
	C_CLASS_HEADER,
	C_STRING_LITERAL
} C_CLASS;

typedef enum {
	C_SUBCLASS_IDENTIFIER,
	C_SUBCLASS_STANDARD,		//Стандартные лексемы keyword
	C_SUBCLASS_EXTENDED,		//Дополнительные лексемы keyword
	C_SUBCLASS_FLOATING_POINT,	//Вещественные константы
	C_SUBCLASS_INTEGER,			//Целочисленные константы
	C_SUBCLASS_CHARACTER		//Символьные константы
} C_SUBCLASS;
//Функция создает образ файла в памяти
EniOk вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Синтаксический анализатор delphin100 Общие вопросы Delphi 10 01.05.2010 12:50
морфологический анализатор Lavisa Помощь студентам 0 19.10.2009 23:11
Лексический анализатор serguna005 Паскаль, Turbo Pascal, PascalABC.NET 5 06.12.2008 00:00
Анализатор формул KJIOyH Помощь студентам 1 05.11.2007 18:18