#ifndef ACTIONSANDRULES_H #define ACTIONSANDRULES_H ///////////////////////////////////////////////////////////////////// // ActionsAndRules.h - declares new parsing rules and actions // // ver 1.1 // // Lanaguage: Visual C++ 2005 // // Platform: Dell Dimension 9150, Windows XP SP2 // // Application: Prototype for CSE687 Pr1, Sp06 // // Author: Jim Fawcett, CST 2-187, Syracuse University // // (315) 443-3948, jfawcett@twcny.rr.com // ///////////////////////////////////////////////////////////////////// /* Module Operations: ================== This module defines several action classes. Its classes provide specialized services needed for specific applications. The modules Parser, SemiExpression, and Tokenizer, are intended to be reusable without change. This module provides a place to put extensions of these facilities and is not expected to be reusable. Public Interface: ================= Toker t(someFile); // create tokenizer instance SemiExp se(&t); // create a SemiExp attached to tokenizer Parser parser(se); // now we have a parser Rule1 r1; // create instance of a derived Rule class Action1 a1; // create a derived action r1.addAction(&a1); // register action with the rule parser.addRule(&r1); // register rule with parser while(se.getSemiExp()) // get semi-expression parser.parse(); // and parse it Build Process: ============== Required files - Parser.h, Parser.cpp, ActionsAndRules.h, ActionsAndRules.cpp, SemiExpression.h, SemiExpression.cpp, tokenizer.h, tokenizer.cpp Build commands (either one) - devenv Project1HelpS06.sln - cl /EHsc /DTEST_PARSER parser.cpp ActionsAndRules.cpp \ semiexpression.cpp tokenizer.cpp /link setargv.obj Maintenance History: ==================== ver 1.1 : 30 Mar 06 - moved IRule, IAction, addAction, and doActions from parser to ActionsAndRules. ver 1.0 : 12 Jan 06 - first release */ // #include #include #include "semiexpression.h" /////////////////////////////////////////////////////////////// // abstract base class for parsing actions // - when a rule succeeds, it invokes any registered action class IAction { public: virtual ~IAction() {} virtual void doAction(SemiExp& se)=0; }; /////////////////////////////////////////////////////////////// // abstract base class for parser language construct detections // - rules are registered with the parser for use class IRule { public: virtual ~IRule() {} void addAction(IAction* pAction); void doActions(SemiExp& se); virtual bool doTest(SemiExp& se)=0; static void updateLineCount(SemiExp& se); static int lineCount(); protected: std::vector actions; static int count; }; /////////////////////////////////////////////////////////////// // rule to detect preprocessor statements class PreprocStatement : public IRule { public: bool doTest(SemiExp& se) { if(se.find("#") < se.length()) { doActions(se); return true; } return false; } }; /////////////////////////////////////////////////////////////// // rule to detect function definitions class FunctionDefinition : public IRule { public: bool isSpecialKeyWord(const std::string& tok) { const static std::string keys[] = { "for", "while", "switch", "if", "catch" }; for(int i=0; i<5; ++i) if(tok == keys[i]) return true; return false; } bool doTest(SemiExp& se) { if(se[se.length()-1] == "{") { int len = se.find("("); if(len < se.length() && !isSpecialKeyWord(se[len-1])) { doActions(se); return true; } } return false; } }; // /////////////////////////////////////////////////////////////// // action to print preprocessor statement to console class PrintPreproc : public IAction { public: void doAction(SemiExp& se) { std::cout << "\n\n Preproc Stmt: " << se.showSemiExp().c_str(); } }; /////////////////////////////////////////////////////////////// // action to send semi-expression that starts a function def // to console class PrintFunction : public IAction { public: void doAction(SemiExp& se) { std::cout << "\n\n line number = " << IRule::lineCount(); std::cout << "\n FuncDef Stmt: " << se.showSemiExp().c_str(); } }; /////////////////////////////////////////////////////////////// // action to send signature of a function def to console class PrettyPrintFunction : public IAction { public: void doAction(SemiExp& se) { SemiExp temp = se; temp.remove("public"); temp.remove(":"); temp.trimFront(); int len = temp.find(")"); std::cout << "\n\n Pretty Stmt: "; for(int i=0; i* pQ; public: PreprocToQ(std::queue& resultQ) : pQ(&resultQ) { } void doAction(SemiExp& se) { pQ->push("Preproc Stmt: " + se.showSemiExp()); } }; /////////////////////////////////////////////////////////////// // action to store function signature in queue class PrettyPrintToQ : public IAction { std::queue* pQ; public: PrettyPrintToQ(std::queue& resultQ) : pQ(&resultQ) { } void doAction(SemiExp& se) { SemiExp temp = se; temp.remove("public"); temp.remove(":"); temp.trimFront(); int len = temp.find(")"); std::string tempStr = "Pretty Stmt: "; for(int i=0; ipush(tempStr); } }; #endif