Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- typedef unsigned int uint;
- #define STORE_INDEX() uint tempIndex=cxt.index
- #define LOAD_INDEX() cxt.index=tempIndex
- struct Node {
- std::string ident;
- std::string content;
- Node* parent;
- std::vector<Node*> nodes;
- };
- Node* newNode(std::string ident, std::string content, Node* parent) {
- Node* node = new Node;
- node->content=content;
- node->ident = ident;
- node->parent = parent;
- return node;
- }
- void destroy_node(Node* node) {
- for(Node* child : node->nodes) {
- destroy_node(child);
- }
- delete node;
- }
- Node* startNewNode(Context& cxt, std::string ident, std::string content) {
- Node* node = newNode(ident, content, cxt.currNode);
- cxt.currNode->nodes.push_back(node);
- cxt.currNode = node;
- return node;
- }
- void destroy_context(Context& cxt) {
- Node* curr = cxt.currNode;
- if(curr==nullptr) {
- return;
- }
- while(curr->parent!=nullptr) {
- curr = curr->parent;
- }
- destroy_node(curr);
- }
- struct Context {
- std::string code;
- uint index;
- uint codeSize;
- Node* currNode;
- };
- bool accept(Context& cxt, char c, bool addToNode=true) {
- if(cxt.index>=cxt.codeSize) {
- return false;
- }
- if(cxt.code[cxt.index]==c) {
- ++cxt.index;
- if(cxt.currNode!=nullptr) {
- cxt.currNode->content+=c;
- }
- return true;
- }
- return false;
- }
- bool acceptLowerChar(Context& cxt, bool addToNode=true) {
- if(cxt.index>=cxt.codeSize) {
- return false;
- }
- char c = cxt.code[cxt.index];
- if(c>='a' && c<='z') {
- ++cxt.index;
- if(cxt.currNode!=nullptr) {
- cxt.currNode->content+=c;
- }
- return true;
- }
- return false;
- }
- bool acceptDigit(Context& cxt, bool nullAllowed, bool addToNode=true) {
- if(cxt.index>=cxt.codeSize) {
- return false;
- }
- char c = cxt.code[cxt.index];
- if( (c=='0' && nullAllowed) || (c>='1' && c<='9')) {
- ++cxt.index;
- if(cxt.currNode!=nullptr) {
- cxt.currNode->content+=c;
- }
- return true;
- }
- return false;
- }
- bool whitespace(Context& cxt) {
- if(accept(cxt, ' ') || accept(cxt, '\t')) {
- return true;
- }
- return false;
- }
- bool skipWhitespaces(Context& cxt) {
- bool res=false;
- while(whitespace(cxt)) {
- res=true;
- };
- return res;
- }
- bool skipLine(Context& cxt) {
- STORE_INDEX();
- skipWhitespaces(cxt);
- if(accept(cxt, '\n')) {
- return true;
- }
- LOAD_INDEX();
- return false;
- }
- bool skipLines(Context& cxt) {
- bool res=false;
- while(skipLine(cxt)) {
- res=true;
- }
- return res;
- }
- bool literal(Context& cxt, std::string lit, bool addNewNode=true) {
- STORE_INDEX();
- for(int i=0; i<lit.size(); ++i) {
- char c=lit[i];
- if(!accept(cxt, c)) {
- LOAD_INDEX();
- return false;
- }
- }
- if(addNewNode) {
- startNewNode(cxt, "literal", lit);
- }
- return true;
- }
- bool identifier(Context& cxt) {
- bool res=false;
- while(acceptLowerChar(cxt)) {
- res=true;
- }
- if(res) {
- startNewNode();
- }
- return res;
- }
- bool number(Context& cxt) {
- STORE_INDEX();
- bool res=false;
- if(acceptDigit(cxt, false)) {
- while(acceptDigit(cxt, true));
- return true;
- } else if(acceptDigit(cxt, true) && !acceptDigit(cxt)) {
- return true;
- }
- LOAD_INDEX();
- return false;
- }
- bool valueExpression(Context& cxt) {
- return (identifier(cxt) || number(cxt));
- }
- bool definition(Context& cxt) {
- STORE_INDEX();
- skipWhitespaces(cxt);
- if(identifier(cxt)) {
- skipWhitespaces(cxt);
- if(literal(cxt, ":=")) {
- skipWhitespaces(cxt);
- if(identifier(cxt) || number(cxt)) {
- skipLine(cxt);
- return true;
- }
- }
- }
- LOAD_INDEX();
- return false;
- }
- bool definitions(Context& cxt) {
- bool res=false;
- skipLines(cxt);
- while(definition(cxt)) {
- skipLines(cxt);
- res=true;
- }
- return res;
- }
- bool program(Context& cxt) {
- STORE_INDEX();
- skipLines(cxt);
- skipWhitespaces(cxt);
- if(literal(cxt, "program") && definitions(cxt) ) {
- skipLines(cxt);
- skipWhitespaces(cxt);
- if(literal(cxt, "endprogram")) {
- return true;
- }
- }
- //LOAD_INDEX();
- return false;
- }
Advertisement
Add Comment
Please, Sign In to add comment