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

📄 yufa.cpp

📁 对已给语言文法
💻 CPP
📖 第 1 页 / 共 2 页
字号:

#include <stdio.h>
#include <stdlib.h>

#include <string.h>

#ifndef COMMON_H
#define COMMON_H

typedef enum{
	ERROR, UNKNOWN,
	LEXER_DONE,	// success!
	IF, THEN, ELSE, WHILE, DO, BEGIN, END,	//9
	ID, NUM,	//11
	AND, OR,
	LT, LE, GT, GE, EQ,	//18
	ASSIGN, PLUS, MINUS, MUL, DIV,	//23
	LP, RP, SEMI
}TokenType;


typedef struct{
	TokenType type;
	char *name;
}Token;


typedef enum{
	INERROR,
	START,
	DONE,
	INID,
	INNUM,
	INLE,	// LT & LE
	INGE,	// GT & GE
	INEQ,	// EQ & ASSIGN
	INCOMMENT
}ScannerState;


typedef enum{
	ST_ERROR,
	ST_NORMAL,	// undefined, but not error
	ST_EXP,	// expression
	ST_IF, ST_THEN, ST_WHILE, ST_ASSIGN, ST_BEGIN
}StatementType;

#endif




class SyntaxTreeNode{
private:
	TokenType type;
	int value;	// identifiers will be given distinguish values.
	SyntaxTreeNode *left, *right, *child3;
	
public:
	SyntaxTreeNode();
	SyntaxTreeNode(TokenType t, int val);
	~SyntaxTreeNode();
	
	void setType(TokenType t);
	void setValue(int val);
	
	TokenType getType();
	int getValue();
	
	void addLeft(TokenType t, int val);
	// add the subtree n to this tree's left
	void addLeft(SyntaxTreeNode *n);
	
	void addRight(TokenType t, int val);
	// add the subtree n to this tree's right
	void addRight(SyntaxTreeNode *n);
	
	void addChild3(TokenType t, int val);
	// add the subtree n to this tree's child3
	void addChild3(SyntaxTreeNode *n);
	
	SyntaxTreeNode* getRootNode();
	
	SyntaxTreeNode* getLeft();
	SyntaxTreeNode* getRight();
	SyntaxTreeNode* getChild3();
	
	friend class SyntaxTree;
};

class SyntaxTree{
private:
	SyntaxTreeNode *root;
	void display(SyntaxTreeNode *n, int tabcount, FILE *fo=stdout);
	
public:
	SyntaxTree(TokenType t, int val=0);
	// set root node with n.
	SyntaxTree(SyntaxTreeNode *n);
	SyntaxTree(SyntaxTree *tree);
	SyntaxTree();	// with root.type = ERROR
	~SyntaxTree();
	
	void display(FILE *fo=stdout);
	
	void setRootNode();
	void setRootNode(TokenType t, int val=0);
	// set root node with n.
	void setRootNode(SyntaxTreeNode *n);
	
	void addLeft(TokenType t, int val=0);
	// add the subtree n to this tree's left
	void addLeft(SyntaxTree *n);
	
	void addRight(TokenType t, int val=0);
	// add the subtree n to this tree's right
	void addRight(SyntaxTree *n);
	
	void addChild3(TokenType t, int val=0);
	// add the subtree n to this tree's child3
	void addChild3(SyntaxTree *n);
	
	SyntaxTreeNode* getRootNode();
	
	SyntaxTree* getLeft();
	SyntaxTree* getRight();
	SyntaxTree* getChild3();

};


class Lexer{
private:
	char *src;
	int length;
	int index;
	char *buf;
	
public:
	Lexer(char *filename);
	Lexer();
	~Lexer();
	void reset();	// rewind index
	bool isReady();
	bool isFinished();
	char *getSrc();
	int getIndex();
	
	void setSrc(char *s, int len);
	
	Token nextToken();
};

class Parser{
private:
	Lexer *lexer;
	Token currentToken;

	Token nextToken();
	
	SyntaxTree* Statement();
	SyntaxTree* Assign();
	SyntaxTree* Expression();
		SyntaxTree* T();
		SyntaxTree* F();
	SyntaxTree* Condition();
	SyntaxTree* Boolean();
		SyntaxTree* T2();
		SyntaxTree* F2();
	SyntaxTree* While();
	SyntaxTree* Begin();
	SyntaxTree* Block();

	void printError(const char *error);

public:
	Parser(char* sourcefile);
	
	Parser();
	
	~Parser();
	
	void reset();
	
	void printError();
	
	SyntaxTree* parse();
	
	void setLexer(Lexer *srclexer);
	
};
/************************************************************SyntaxTreeNode**************/




SyntaxTreeNode::SyntaxTreeNode(){
	type = ERROR;
	value = 0;
	left = right = child3 = NULL;
}
SyntaxTreeNode::SyntaxTreeNode(TokenType t, int val){
	type = t;
	value = val;
	left = right = child3 = NULL;
}

SyntaxTreeNode::~SyntaxTreeNode(){
	if(left != NULL){
		delete left;
	}
	if(right != NULL){
		delete right;
	}
	if(child3 != NULL){
		delete child3;
	}
}

/*===================================================================*/

void SyntaxTreeNode::setType(TokenType t){
	type = t;
}

TokenType SyntaxTreeNode::getType(){
	return type;
}

void SyntaxTreeNode::setValue(int val){
	value = val;
}

int SyntaxTreeNode::getValue(){
	return value;
}


void SyntaxTreeNode::addLeft(TokenType t, int val){
	left = new SyntaxTreeNode(t, val);
}
void SyntaxTreeNode::addLeft(SyntaxTreeNode *n){
	left = n;
}


void SyntaxTreeNode::addRight(TokenType t, int val){
	right = new SyntaxTreeNode(t, val);
}
void SyntaxTreeNode::addRight(SyntaxTreeNode *n){
	right = n;
}


void SyntaxTreeNode::addChild3(TokenType t, int val){
	child3 = new SyntaxTreeNode(t, val);
}
void SyntaxTreeNode::addChild3(SyntaxTreeNode *n){
	child3 = n;
}


SyntaxTreeNode* SyntaxTreeNode::getLeft(){
	return left;
}

SyntaxTreeNode* SyntaxTreeNode::getRight(){
	return right;
}

SyntaxTreeNode* SyntaxTreeNode::getChild3(){
	return child3;
}





/************************************************************SyntaxTree***********/




char* tokenToString(TokenType type);

/*======================================================================*/

SyntaxTree::SyntaxTree(TokenType t, int val){
	root = new SyntaxTreeNode(t, val);
}
SyntaxTree::SyntaxTree(SyntaxTreeNode *n){
	setRootNode(n);
}
SyntaxTree::SyntaxTree(SyntaxTree *tree){
	setRootNode(tree->getRootNode());
}
SyntaxTree::SyntaxTree(){
	setRootNode();
}

SyntaxTree::~SyntaxTree(){
	if(root != NULL){
		delete root;
	}
}

/*====================================================================*/

void SyntaxTree::display(SyntaxTreeNode *n, int tabcount, FILE *fo){
	static int tab[200];	// is it enough?
	
	SyntaxTreeNode * node = n;
	if(node == NULL) return;
	
	if(node->type == NUM){
		fprintf(fo, "%-3d", node->value);
	}else{
		fprintf(fo, "%-3s", tokenToString(node->type));
	}
		
	if(node->left != NULL){
		tab[tabcount] = 1;
	}
	
	if(node->right != NULL){
		fprintf(fo, "---");
		this->display(node->right, tabcount + 1, fo);
	}
	
	if(node->left != NULL){
		fprintf(fo, "\n");
		for(int i=0;i<tabcount;i++){
			if(tab[i] == 1){
				fprintf(fo, "|%5s", "");
			}else{
				fprintf(fo, "%6s", "");
			}
		}
		fprintf(fo, "+-----");
		tab[tabcount] = 0;
		this->display(node->left, tabcount + 1, fo);
	}
	
}

void SyntaxTree::display(FILE *fo){
	if(fo == NULL){
		fo = stdout;
		printf("\nFILE* NULL, will write to STDOUT.\n\n");
	}
		
	fprintf(fo, "\n");
	this->display(root, 0, fo);
	fprintf(fo, "\n");
}


void SyntaxTree::setRootNode(TokenType t, int val){
	root = new SyntaxTreeNode(t, val);
}
void SyntaxTree::setRootNode(SyntaxTreeNode *n){
	if(n == NULL){
		root = new SyntaxTreeNode();
	}else{
		root = n;
	}
}
void SyntaxTree::setRootNode(){
	root = new SyntaxTreeNode();
}


void SyntaxTree::addLeft(TokenType t, int val){
	root->left = new SyntaxTreeNode(t, val);
}
void SyntaxTree::addLeft(SyntaxTree *n){
	if(n == NULL) return;
	root->left = n->getRootNode();
}


void SyntaxTree::addRight(TokenType t, int val){
	root->right = new SyntaxTreeNode(t, val);
}
void SyntaxTree::addRight(SyntaxTree *n){
	if(n == NULL) return;
	root->right = n->getRootNode();
}


void SyntaxTree::addChild3(TokenType t, int val){
	root->child3 = new SyntaxTreeNode(t, val);
}
void SyntaxTree::addChild3(SyntaxTree *n){
	if(n == NULL) return;
	root->child3 = n->getRootNode();
}


SyntaxTreeNode* SyntaxTree::getRootNode(){
	return root;
}


SyntaxTree* SyntaxTree::getLeft(){
	if(root->left == NULL)
		return NULL;
	else
		return new SyntaxTree(root->left);
}

SyntaxTree* SyntaxTree::getRight(){
	if(root->right == NULL)
		return NULL;
	else
		return new SyntaxTree(root->right);
}


SyntaxTree* SyntaxTree::getChild3(){
	if(root->child3 == NULL)
		return NULL;
	else
		return new SyntaxTree(root->child3);
}

/*==================================================================*/

char* tokenToString(TokenType type){
	char *s = NULL;
	switch(type){
		case ID:
			s = "ID";
			break;
		case NUM:
			s = "NUM";
			break;
		case IF:
			s = "if";
			break;
		case THEN:
			s = "thn";
			break;
		case ELSE:
			s = "els";
			break;
		case WHILE:
			s = "whl";
			break;
		case DO:
			s = "do";
			break;
		case BEGIN:
			s = "blk";
			break;
		case END:
			s = "end";	// "end"
			break;
		case ASSIGN:
			s = "'='";
			break;
		case EQ:
			s = "==";
			break;
		case LT:
			s = "'<'";
			break;
		case GT:
			s = "'>'";
			break;
		case PLUS:
			s = "'+'";
			break;
		case MUL:
			s = "'*'";
			break;
		case MINUS:
			s = "'-'";
			break;
		case DIV:
			s = "'/'";
			break;
		case OR:
			s = "'|'";
			break;
		case AND:
			s = "'&'";
			break;
		default:
			s = "undef";
	}
	return s;
}





/************************************************************Lexer************/


#define MAXRESERVED 7
#define TOKENBUFSIZE 64

void getSingleOperator(char c, Token &token);
void keywordLookup(Token &token);


static Token ReservedWords[MAXRESERVED] = {
	{IF, "if"},
	{THEN, "then"},
	{ELSE, "else"},
	{WHILE, "while"},
	{DO, "do"},
	{BEGIN, "begin"},
	{END, "end"}
};


Lexer::Lexer(char *filename){
	buf = new char[TOKENBUFSIZE];
	FILE *fp = fopen(filename, "r");
	index = 0;
	if(fp==NULL){
		src = NULL;
		printf("\n\n********************************************\n");
		printf("* FATAL ERROR! LEXER COULD NOT OPEN FILE!!!\n");
		printf("* %s : No such file.\n", filename);
		printf("********************************************\n\n");
		length = 0;
	}else{
		int i = 0;
		while(fgetc(fp)!=EOF){
			i++;
		}
		length = i;
		src = new char[i+1];
		
		rewind(fp);
		i = 0;
		while(src[i] = fgetc(fp)){
			if(src[i] == EOF){
				src[i] = '\0';
				break;
			}
			i++;
		}
	
		fclose(fp);
	}
}

Lexer::Lexer(){
}

Lexer::~Lexer(){
	delete[] src;
}

void Lexer::reset(){
	index = 0;
}

bool Lexer::isFinished(){
	return (index == length - 1);
}

bool Lexer::isReady(){
	return (src != NULL);
}

char* Lexer::getSrc(){
	return src;
}

void Lexer::setSrc(char *s, int len){
	src = s;
	index = 0;
	length = len;
	buf = new char[TOKENBUFSIZE];
}

int  Lexer::getIndex(){
	return index;
}


/***=======================================================****/


Token Lexer::nextToken(){
	Token token;
	ScannerState state = START;
	int bufindex = 0;
	bool next = true;	// index++
	char c;
	
	if(index==length-1){
		token.type = ERROR;
		token.name = "NO CHAR LEFT.";
		return token;
	}
	
	c = src[index];
	while(c==' ' || c=='\n' || c=='\r' || c=='\t'){
		index ++;
		c = src[index];
	}
	
	// get started
	if((c>='a' && c<='z') || (c>='A' && c<='Z')){
		state = INID;
		token.type = ID;
		buf[bufindex++] = c;
	}else if(c>='0' && c<='9'){
		state = INNUM;
		token.type = NUM;
		buf[bufindex++] = c;
	}else if(c=='='){
		state = INEQ;
	}else if(c=='<'){
		state = INLE;
	}else if(c=='>'){
		state = INGE;
	}else{
		state = DONE;
		getSingleOperator(c, token);
	}
	index ++;
	
	while(state!=DONE){
		c = src[index];
		switch(state){
			case INEQ:

⌨️ 快捷键说明

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