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

📄 analyse.cpp

📁 编译器模拟程序
💻 CPP
字号:
#include "scan.h"

/*语法分析部分:
  * 转换
  * lexp →NUMBER| ( op lexp-seq )
  * op →+ | - | *
  * lexp -seq → lexp-seq lexp|lexp
  * 为EBNF如下:
  * <lexp> -> <NUMBER> | (<op> <lexp -seq>)
  * <op> -> + | - | *
  * <lexp -seq> -> <lexp> { <lexp> }
  *
  */
 
  void compiler::error(){
	  
	  cout << "context error......" << endl;
	  fprintf(listing, "%s\n", "An error occoured.");
	  exit(0);
  }
  
  void compiler::match(TokenType type){
	  
	  if(token.type == type){
		  
			  token = getToken();
	  }
	  else{
		  
		  error();
	  }
  }
  
  
  treenode* compiler::lexp(){
	  
	  treenode* tempNode = new treenode();
	  
	  if(token.tokenValue[0]=='('){
		  
		  match(LPAREN);
	    
	  if(strcmp(token.tokenValue,"+") == 0){
		  
		  match(PLUS);
		  
		  tempNode->content = *(new tokenForUse(PLUS, '+'));
		  treenode* left = new treenode();
		  left = lexp_seq();
		  treenode* right = new treenode();
		  right = lexp_seq();
		  tempNode->leftChild = left;
		  tempNode->rightChild = right;
	  }
	  else
	  if(strcmp(token.tokenValue,"-") == 0){
		  
		  match(MINUS);
		  
		  tempNode->content = *(new tokenForUse(MINUS, '-'));
		  treenode* left = new treenode();
		  left = lexp_seq();
		  treenode* right = new treenode();
		  right = lexp_seq();
		  tempNode->leftChild = left;
		  tempNode->rightChild = right;
	  }
	  else
	  if(strcmp(token.tokenValue,"*") == 0){
		  
		  match(TIMES);
		  
		  tempNode->content = *(new tokenForUse(TIMES, '*'));
		  treenode* left = new treenode();
		  left = lexp_seq();
		  treenode* right = new treenode();
		  right = lexp_seq();
		  tempNode->leftChild = left;
		  tempNode->rightChild = right;
	  }
	  else
		  error();	  		  
		  match(RPAREN);
	  
	  }else
		  if(token.type == NUM){		  
		  
		  tempNode->content = token;
		  match(NUM);
	  }
	  return tempNode;
  }
  
  treenode* compiler::lexp_seq(){
	  
	  return lexp();
  }
  void compiler::printResult(treenode* &root){
	  
	  if(root != NULL){
		  
		  printResult(root->leftChild);
		  
		  fprintf(listing, "%s\t", root->content.tokenValue);
		  
		  printResult(root->rightChild);
	  }
  }
  
  void compiler::printTree(treenode* &root){
	  
	  //按层次遍历;
	  nodes.push_back(root);
	  
	  while(!nodes.empty()){
		  
		  verNodes.push_back(nodes.front());
		  
		  if(nodes.front()->leftChild != NULL){
			  
			  nodes.push_back(nodes.front()->leftChild);
			  nodes.push_back(nodes.front()->rightChild);
		  }
		  nodes.pop_front();
	  }
	  
	  int i=0;
	  int cap = 0;
	  int numoftwo = 0;
	  while(i<verNodes.size()){
		  
		  if(cap == 0){
			  
			  fprintf(listing, "\n%s\n", verNodes[i]->content.tokenValue);
			  
			  cap = 2;
			  i++;
		  }
		  else{
			  
			  for(int j=0; j<cap && i<verNodes.size(); j++){
				  
				  fprintf(listing, "%s\t", verNodes[i]->content.tokenValue);
				  
				  if(verNodes[i]->content.type != NUM){
					  
					  numoftwo++;
				  }
				  i++;
			  }
			  cap = numoftwo*2;
			  cout << endl;
			  fprintf(listing, "\n");
		  }
	  }
  }
  int compiler::getResult(treenode* &root){
	  
	  int result;
	  switch(root->content.type){
		  
	  case PLUS :{
		  
		  result = getResult(root->leftChild) + getResult(root->rightChild);	
		  break;
				 }
	  case MINUS :{
		  
		  result = getResult(root->leftChild) - getResult(root->rightChild);	
		  break;
				  }
	  case TIMES :{
		  
		  result = getResult(root->leftChild) * getResult(root->rightChild);	
		  break;
				  }
	  case NUM :{
		  
		  result = atoi(root->content.tokenValue);
		  break;
				}
	  }
	  return result;
  }
  int main(){

	  compiler myComp = *new compiler();

	  fprintf(myComp.listing, "词法分析结果: \n");
	  //语法树的根结点;
	  treenode* resultroot = new treenode();
	  //语法分析;
	  myComp.token = myComp.getToken();
	  resultroot = myComp.lexp();
	  
	  fprintf(myComp.listing, "转换为正常算术表达式: \n");
	  myComp.printResult(resultroot);
	  
	  fprintf(myComp.listing, "\n最终计算结果: ");
	  fprintf(myComp.listing, "%d\n", myComp.getResult(resultroot));
	  
	  fprintf(myComp.listing, "打印语法树(按层打印对应不是很整齐): \n");
	  myComp.printTree(resultroot);

	  cout << "结果详见out.txt." << endl;
	  return 0;
  }

⌨️ 快捷键说明

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