自己动手写C语言编译器(1)
来源:互联网 发布:o2o在线预约商城源码 编辑:程序博客网 时间:2024/05/17 08:45
直接上代码 (表达式树 在此 初具 模型 )
由于没有做前期的“词法分析”,
1.支持 单个 字符 形式的变量
2.支持 单个 字符形式的操作符
3.支持 优先级 。
不支持
1.不支持多个字符的操作符和变量。
2. 不支持左右结合性
3.不支持函数
4. 不支持语句
5. 不支持关键字。
这些将陆续添加 。
// MyCompiler.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include <fstream>#include <list>#include <map>#include <string>#include <iostream>#include <vector>//把Token转换为字符串#define ATokenToString(l, r) if(l == r)return #r;using namespace std;namespace tokens{enum TOKEN{INVALID_TYPE,WHITE_SPACE,NAME,NUMBER,END,PLUS,MINUS,MUL,DIV,PRINT,ASSIGN,LP,RP,};static string MyTokenToString(TOKEN token){ATokenToString(token, WHITE_SPACE)ATokenToString(token, NAME)ATokenToString(token, NUMBER)ATokenToString(token, END)ATokenToString(token, PLUS)ATokenToString(token, MINUS)ATokenToString(token, MUL)ATokenToString(token, DIV)ATokenToString(token, PRINT)ATokenToString(token, ASSIGN)ATokenToString(token, LP)ATokenToString(token, RP)return "";}}class tokenizer{int mTokenTypes[256];string mCurrentStrToken;tokens::TOKEN mCurrentTokenType;istream& mIfStream;public:tokenizer(istream& infile):mIfStream(infile){memset(mTokenTypes, 0, 256);mTokenTypes['+'] = tokens::PLUS;mTokenTypes['-'] = tokens::MINUS;mTokenTypes['*'] = tokens::MUL;mTokenTypes['/'] = tokens::DIV;mTokenTypes[';'] = tokens::PRINT;mTokenTypes['='] = tokens::ASSIGN;mTokenTypes['('] = tokens::LP;mTokenTypes[')'] = tokens::RP;mTokenTypes['\t'] = tokens::WHITE_SPACE;mTokenTypes[' '] = tokens::WHITE_SPACE;char ch = 0;for (ch = 'a'; ch <= 'z'; ch ++){mTokenTypes[ch] = tokens::NAME; }for(ch = 'A'; ch <= 'Z'; ch ++){mTokenTypes[ch] = tokens::NAME; }for(ch = '0'; ch <= '9'; ch ++){mTokenTypes[ch] = tokens::NUMBER; }mTokenTypes['.'] = tokens::NUMBER;}bool hasNext(){char temptoken = 0;if(mIfStream.get(temptoken)){mIfStream.putback(temptoken);return true;}return false;}const string getCurrent(){return mCurrentStrToken;}tokens::TOKEN getTokenType(){return mCurrentTokenType;}const string getNext(){string strValue;char ch = 0;mIfStream>>ch;mCurrentTokenType = (tokens::TOKEN)mTokenTypes[ch];mIfStream.putback(ch);mIfStream>>strValue;mCurrentStrToken = strValue;return strValue;}};class Node;struct NodeVisitor{virtual void BeginVisitTree(Node* nod) = 0;virtual void VisitNode(Node* nod) = 0;virtual void EndVisitTree(Node* nod) = 0;};class Node{char m_Data;NodeVisitor* m_pGetNode;public:Node* m_pLeftChild;Node* m_pRightChild;Node* m_pParent;int m_priority_level;public:char getData(){return m_Data;}Node(){m_Data = 0;m_pLeftChild = NULL;m_pRightChild = NULL;m_pParent = NULL;//空的Node,优先级最低m_priority_level = 0;}Node(char data){m_Data = data;m_pLeftChild = NULL;m_pRightChild = NULL;m_pParent = NULL;m_priority_level = 0;}void set(Node* pL, Node* pR){m_pLeftChild = pL;m_pRightChild = pR;}void setLeft(Node* pLeft){m_pLeftChild = pLeft;}void setRight(Node* pRight){m_pRightChild = pRight;}void accept(NodeVisitor* pGetIt){m_pGetNode = pGetIt;}void Postorder_Traversal(NodeVisitor* pVisiter){if(m_pLeftChild != NULL)m_pLeftChild->Postorder_Traversal(pVisiter);if (m_pRightChild != NULL)m_pRightChild->Postorder_Traversal(pVisiter);pVisiter->VisitNode(this);}void Inorder_Traversal(NodeVisitor* pVisiter){//Begin Tree.pVisiter->BeginVisitTree(this);if(m_pLeftChild != NULL)m_pLeftChild->Inorder_Traversal(pVisiter);//Visit this node. //Node should not be diffrent from tree.pVisiter->VisitNode(this);if (m_pRightChild != NULL)m_pRightChild->Inorder_Traversal(pVisiter);//End Tree.pVisiter->EndVisitTree(this);}};class ExpressionVisiter: public NodeVisitor{public:void BeginVisitTree(Node* nod){if (nod->m_pLeftChild != NULL && nod->m_pRightChild != NULL){printf("%c", '(');}}void VisitNode(Node* nod){printf("%c", nod->getData());}void EndVisitTree(Node* nod){if (nod->m_pLeftChild != NULL && nod->m_pRightChild != NULL){printf("%c", ')');}}};class Tree{public:Tree(){pHead = new Node();}Node* pHead;~Tree(){}Node* getNext(){}void Postorder_Traversal(NodeVisitor* pVisiter){if(pHead->m_pLeftChild!=NULL)pHead->m_pLeftChild->Postorder_Traversal(pVisiter);}void Inorder_Traversal(NodeVisitor* pVisiter){if(pHead->m_pLeftChild!=NULL)pHead->m_pLeftChild->Inorder_Traversal(pVisiter);}Node* getCurrent(){}Node* getFirst(){}bool bHasNext(){}void setValue(Node* pNode){pHead->m_pLeftChild = pNode;}};//打印一个字符串的所有排列。void printSequence(char* pChara){int i = 0;static int MAX_LEN = strlen(pChara);if (pChara[0] == '\0'){for (int i = 0; i < MAX_LEN; i ++){printf("%c", pChara[i + 1]);}printf("\n", ""); }char* tempChar = pChara;while (*tempChar != '\0' ){char* pMyString = new char[MAX_LEN + 1];memcpy(pMyString, pChara, MAX_LEN + 1);memcpy(pMyString + i, pMyString + i + 1, MAX_LEN - i);pMyString[MAX_LEN] = *tempChar;printSequence(pMyString);tempChar ++;i ++;delete[] pMyString;}}#ifdef TESTint main(int argc, char* argv[]){ExpressionVisiter visister;Tree* pTree = new Tree();Node* pNode1 = new Node('-');Node* pNode11 = new Node('+');Node* pNode12 = new Node('/');Node* pNode111 = new Node('a');Node* pNode112 = new Node('*');Node* pNode121 = new Node('e');Node* pNode122 = new Node('f');Node* pNode1121 = new Node('b');Node* pNode1122 = new Node('-');Node* pNode11221 = new Node('c');Node* pNode11222 = new Node('d');pNode1->set(pNode11, pNode12);pNode11->set(pNode111, pNode112);pNode12->set(pNode121, pNode122);pNode112->set(pNode1121, pNode1122);pNode1122->set(pNode11221, pNode11222);pTree->setValue(pNode1);pTree->Inorder_Traversal(&visister);//printSequence("a");system("PAUSE");return 1;}#else//字符的类型class SH_CHARACTER_TYPE{public:enum CHARACTER_TYPE{ILLIGAL_CHAR = 0x00000000,DIGITAL_CHAR = 0x00000001,NON_DIGITAL_CHAR = 0x00000002,UNIVERSAL_CHAR = 0x00000004,INTEGER_CONSTANT_CHAR = 0x00000008,FLOATING_CONSTANT_CHAR = 0x00000010,ENUMERATION_CONSTANT_CHAR = 0x00000020,CHARACTER_CONSTANT_CHAR = 0x00000040,STRING_LITERAL_CHAR = 0x00000080,PUNCTUATOR_CHAR = 0x00000100,EOL_CHAR = 0x00000200,EOF_CHAR = 0x00000400,WHITESPACE_CHAR = 0x00000800,OPERATOR_CHAR = 0x00001000,};};class sh_ctype{private:int ctypeTable[256];public:void clear(){//清除for (int i = 0; i < 256; ++ i){ctypeTable[i] = SH_CHARACTER_TYPE::ILLIGAL_CHAR;}}sh_ctype(){clear();setCtype('a', 'z', SH_CHARACTER_TYPE::NON_DIGITAL_CHAR);setCtype('A', 'Z', SH_CHARACTER_TYPE::NON_DIGITAL_CHAR);setCtype('0', '9', SH_CHARACTER_TYPE::DIGITAL_CHAR);setCtype('0', '9', SH_CHARACTER_TYPE::INTEGER_CONSTANT_CHAR);setCtype('x', SH_CHARACTER_TYPE::INTEGER_CONSTANT_CHAR);setCtype('X', SH_CHARACTER_TYPE::INTEGER_CONSTANT_CHAR);setCtype('u', SH_CHARACTER_TYPE::INTEGER_CONSTANT_CHAR);setCtype('U', SH_CHARACTER_TYPE::INTEGER_CONSTANT_CHAR);setCtype('l', SH_CHARACTER_TYPE::INTEGER_CONSTANT_CHAR);setCtype('L', SH_CHARACTER_TYPE::INTEGER_CONSTANT_CHAR);setCtype('0', '9', SH_CHARACTER_TYPE::FLOATING_CONSTANT_CHAR);setCtype('e', SH_CHARACTER_TYPE::FLOATING_CONSTANT_CHAR);setCtype('E', SH_CHARACTER_TYPE::FLOATING_CONSTANT_CHAR);setCtype('l', SH_CHARACTER_TYPE::FLOATING_CONSTANT_CHAR);setCtype('L', SH_CHARACTER_TYPE::FLOATING_CONSTANT_CHAR);setCtype('f', SH_CHARACTER_TYPE::FLOATING_CONSTANT_CHAR);setCtype('F', SH_CHARACTER_TYPE::FLOATING_CONSTANT_CHAR);//标点符号字符setCtype(0x21,0x2F, SH_CHARACTER_TYPE::PUNCTUATOR_CHAR);setCtype(0x3a,0x40, SH_CHARACTER_TYPE::PUNCTUATOR_CHAR);setCtype(0x5B,0x60, SH_CHARACTER_TYPE::PUNCTUATOR_CHAR);//空白字符setCtype(0x20, SH_CHARACTER_TYPE::WHITESPACE_CHAR);setCtype(0x09, 0x0D, SH_CHARACTER_TYPE::WHITESPACE_CHAR);setCtype('+', SH_CHARACTER_TYPE::OPERATOR_CHAR);}//断定是否是某种类型bool assert(char ch, SH_CHARACTER_TYPE::CHARACTER_TYPE type){if ((getCtype(ch)&type) == type){return true;}return false;}void setCtype(char from, char to, SH_CHARACTER_TYPE::CHARACTER_TYPE type){for (char ch = from; ch <= to ; ++ ch){ctypeTable[ch] = ctypeTable[ch]|type;}}void setCtype(char ch, SH_CHARACTER_TYPE::CHARACTER_TYPE type){ctypeTable[ch] = ctypeTable[ch]|type;}int getCtype(char ch){return ctypeTable[ch];}};int getLevel(char ch){switch(ch){case ',':return 0;case '=':return 1;case '|': return 2;case '^':return 3;case '>': case '<':return 5;case '+' : case '-':return 6;case '*': case '/':return 7;case '&':return 8;case '.':return 9;default:return INT_MAX;}}static int const INVALID = 0;static int const EXPRESSION = 0x0001;static int const LVALUE = 0x0002;static int const OPERATOR_LEFT = 0x0004;static int const OPERATOR_RIGHT = 0x0008;int main(int argc, char* argv[]){sh_ctype ct;Node* pHead = NULL;Node* preTreeOperator = NULL;char ch;while (cin.get(ch) && ch != '\n'){//如果目前没有操作子Treeif (preTreeOperator == NULL){preTreeOperator = new Node(ch);preTreeOperator->m_priority_level = getLevel(ch);pHead = preTreeOperator;continue;}else{ Node* no = new Node(ch); no->m_priority_level = getLevel(ch); Node* theTree = preTreeOperator; if(pHead->m_priority_level == no->m_priority_level && pHead->m_priority_level == INT_MAX) {std::cout<<"Unkown symbol "<<"\""<<ch<<"\"";system("PAUSE");return;} else if (no->m_priority_level <= pHead->m_priority_level) { pHead->m_pParent = no; no->m_pLeftChild = pHead; pHead = no; preTreeOperator = no; continue; } if(theTree->m_priority_level == no->m_priority_level && theTree->m_priority_level == INT_MAX) {std::cout<<"Unkown symbol "<<"\""<<ch<<"\"";system("PAUSE");return; } while (theTree!= NULL&& theTree->m_priority_level >= no->m_priority_level) { theTree = theTree->m_pParent; } if (theTree != NULL) {no->m_pLeftChild = theTree->m_pRightChild;no->m_pParent = theTree;theTree->m_pRightChild = no;preTreeOperator = no; }}}Tree tree;ExpressionVisiter vister;tree.setValue(pHead);tree.Inorder_Traversal(&vister);system("PAUSE");}#endif
阅读全文
0 0
- 自己动手写C语言编译器(1)
- 自己动手写C语言编译器(2)
- 自己动手写C语言编译器(3)
- 自己动手写C语言编译器(4)
- 自己动手写C语言编译器(5)
- 自己动手写C语言编译器(暂停)
- 自己动手写C语言库函数(1) memcpy
- 自己动手写编译器
- 自己动手写编译器
- 自己动手写C语言格式化输出函数(一)
- 自己动手写C语言格式化输出函数(二)
- 自己动手写C语言格式化输出函数(三)
- 自己动手写C语言库函数(2) memmove
- 自己动手写C语言库函数(3) strstr
- 自己动手写C语言库函数(4)strlen
- 自己动手写C语言库函数(5)strcpy
- 自己动手写C语言库函数(6) atoi
- 自己动手写编译器之Tiny语言语法分析器的实现
- 文件上传
- ios 11 CORE ML 学习入门
- 侯二牛推荐的书。
- maven 环境变量
- fatal error C1075: 与左侧的 圆括号“)”
- 自己动手写C语言编译器(1)
- 剑指offer——11.二进制中1的个数
- 【hdu 1029】Ignatius and the Princess IV
- 大话数据结构 code第七章 02邻接表创建_CreateALGraph
- 处理海量数据的模式MapReduce,大规模数据集的并行运算
- Struts2——将字符串、对象、list集合保存到值栈中,在jsp页面中获取的方法
- 自己动手写C语言编译器(2)
- 我的游戏之路——服务器之IO篇
- Oracle性能优化读书笔记(2)-SQL语句和索引优化