⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 reader.cpp

📁 用VC实现的词法分析器
💻 CPP
字号:
// Reader.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include <stdio.h>

#include "CodeObject.h"
#include "TokenMaker.h"
#include "Grammar.h"

// Global standard handles
FILE * pOut;
FILE * pIn;

namespace IO
{

	int ReadLine(char * buffer, unsigned max, FILE * stream)
	{
		int nChar;
		unsigned nIndex = 0;
		while(nIndex < max-1)
		{
			switch(nChar = fgetc(stream))
			{
			case EOF:	// End of file
				buffer[nIndex] = 0;
				if (nIndex == 0)
					return 0;
				return 1;

			case 0x0A:
				buffer[nIndex] = 0;
				return 1;

			case 0x0D:
				continue;

			default:
				buffer[nIndex++] = nChar;
			}
		}
		buffer[max-1] = '\0';
		return -1;
	}

	void WriteLine(const char * buffer, FILE * stream)
	{
		fputs(buffer, stream);
		fputc('\n', stream);
	}
};

int ParseExpression(CppList<CodeObject*> * pTokenList, Grammar * pG, CodeObject ** ppResult)
{
	/*
		Breakdown:

		for (start = first; start != end; start++)
			if start type = Input
				done
			grammar begin
			while next != end
				grammar next
				if error
					exit
				if continue
					continue
				if not found break while
				if found
					create object within list
					restart from the very beginning
	*/

	CodeObject * pStart;
	CodeObject * pNext;

	CppList<CodeObject*>::iterator _Start;
	CppList<CodeObject*>::iterator _Next;

	CodeObject * pNew = NULL;

	Grammar::Result r;

	// Dummy NULL token so the for loop works
	pNew = new CodeObject;
	pNew->Line = 0;
	pNew->Type = Null;
	pTokenList->push_back(pNew);


Restart:	// Yeah, that's right... I use goto. In this case, it DOES make clearer code
	for(_Start = pTokenList->begin(); _Start != pTokenList->end(); _Start++)
	{
		pStart = *_Start;
		_Next = _Start;
		pG->Begin();
		while(_Next != pTokenList->end())
		{
			pNext = *_Next;
			r = pG->Next(pNext->Type);
			if (r == Grammar::BadInput)
			{
				IO::WriteLine("Unexpected Failure!!!", pOut);
				*ppResult = NULL;
				return -1;
			}
			else if (r == Grammar::Continue)
			{
				_Next++;
				continue;
			}
			else if (r == Grammar::NotFound)
				break;
			else if (r == Grammar::Found)
			{
				pNew = new CodeObject;
				pNew->Line = pStart->Line;
				pNew->Type = pG->GetResult();
				pTokenList->splice(pNew->Descendants->begin(), *pNew->Descendants, _Start, _Next);
				pTokenList->insert(_Next, pNew);
				goto Restart;
			}
		}
	}

	pStart = *pTokenList->begin();
	if (pStart->Type != Input)
	{
		IO::WriteLine("  Failure: Bad Input!!!", pOut);
		*ppResult = NULL;
		return -1;
	}

	*ppResult = pStart;
	pTokenList->pop_front();	// Lose ownership of result
	pStart = *pTokenList->begin();
	delete pStart;	// Delete dummy NULL object
	pTokenList->pop_front();

	return 0;
}

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

	char line[256];

	pIn = fopen("Input.txt", "rt");
	if (/* Write Output to a file == */ false)
		pOut = fopen("Output.txt", "wt");	
	else
		pOut = stdout;	/*Write to console*/

	Utility::MallocList<char *> strList;

	if (!pIn)
		printf("Error!\n");
	else
		while(IO::ReadLine(line, 256, pIn))
			strList.push_back(strdup(line));

/*
	Grammar description in BNF:

	Value		->	Integer
	Expression	->	Value | (Expression Operator Expression) | (OpenParenthesis Expression CloseParenthesis)
	Operator	->	PlusSign
	Input		->	Expression, EndOfFile

	'Integer', 'OpenParenthesis', 'CloseParenthesis', and 'PlusSign' are 
		created by the token parser and terminals

	'Input' is the completed result
*/
	Grammar::Rule r1 = {Value,{Integer, Null}};
	Grammar::Rule r2 = {Expression,{Value, Null}};
	Grammar::Rule r3 = {Expression,{Expression, Operator, Expression, Null}};
	Grammar::Rule r4 = {Expression,{OpenParenthesis, Expression, CloseParenthesis, Null}};
	Grammar::Rule r5 = {Operator,{PlusSign, Null}};
	Grammar::Rule r6 = {Input,{Expression, EndOfFile, Null}};
	
	Grammar g;

	g.AddRule(&r1);
	g.AddRule(&r2);
	g.AddRule(&r3);
	g.AddRule(&r4);
	g.AddRule(&r5);
	g.AddRule(&r6);

	IO::WriteLine("Grammar Tree:\n", pOut);
	g.Dump(pOut, true, 0);


	IO::WriteLine("\nParsing Tokens:\n", pOut);

	CppList<CodeObject *> tokenList;

	if (TokenMaker::MakeTokens(&strList, &tokenList))
		IO::WriteLine(LastError, pOut);

	for(CppList<CodeObject*>::iterator _Iter = tokenList.begin(); _Iter != tokenList.end(); _Iter++)
	{
		CodeObject * pObj = *_Iter;
		pObj->Dump(pOut, true, 0);
	}

	IO::WriteLine("\nParsing Expression:\n", pOut);

	CodeObject * pInput;

	if (!ParseExpression(&tokenList, &g, &pInput))
	{
		IO::WriteLine("\nResult:\n", pOut);
		pInput->Dump(pOut, true);
	}

	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -