#ifndef GRAMMAR_H #define GRAMMAR_H ///////////////////////////////////////////////////////////////////// // grammar.h - provides detectors for grammatical constructs // // ver 1.5 // // // // Language: Visual C++, ver 7.0 // // Platfrom: Dell Dimension 8100, Windows 2000, SP 2.0 // // Application: Prototype for CSE687 Pr#2, Spring 2003 // // Author: Jim Fawcett, CST 2-187, Syracuse University // // (315) 443-3948, jfawcett@twcny.rr.com // ///////////////////////////////////////////////////////////////////// /* Module Operation: ================= The grammar module provides a set of detector functions that identify gramatical constructs captured by the tokens in a semiExp object. It provides the following classes: grammar: supplys many detectors and processors for C++ syntactic constructs scopeStack: provides processing of scope contexts, e.g., namespaces and classes typeTable: holds identifiers and their types Note that grammar also holds a set of types to help it conduct its own business. Public Interface: ================= The grammar class now has a very big public interface. It is badly in need of refactoring into smaller cohesive pieces. I will do that before putting my solution on the class directory (I'll do that shortly after turning in grades for this class). */ // ///////////////////////////////////////////////////////////////////// // Build Process // ///////////////////////////////////////////////////////////////////// // Required Files: // // grammar.h, grammar.cpp, semi.h, semi.cpp, tok.h, tok.cpp // // // // Compiler command: // // cl /DTEST_SCANNER grammar.cpp semi.cpp tok.cpp display.cpp // ///////////////////////////////////////////////////////////////////// /* Maintenance History: ==================== ver 1.5 : 04/28/03 - cosmetic modification: typeTable::show now takes an optional integer argument to specify number of leading spaces. ver 1.4 : 04/27/03 - strengthed existing detectors and added a few more to handle special cases. ver 1.3 : 04/27/03 - based on bug report by Divyanand Kutagulla, I've fixed a bug in grammar::invocation() that caused crashes for expressions with initial parens, e.g., (ptr->method1()).method2(); ver 1.2 : 04/26/03 - based on bug report from Abhishek Jain I fixed a bug in grammar::qualifiedType. "namespace" string was missing. ver 1.1 : 04/25/03 - now has a collection of tools for type analysis ver 1.0 : 02/08/03 - first release */ #include "semi.h" #include #include #include #include #include typedef std::string sstr; typedef const std::string csstr; /////////////////////////////////////////////////////////////// // scope element holds scope type and name, e.g., class X struct scope { scope(sstr type,sstr name) : _type(type),_name(name) {} sstr _type; sstr _name; }; // /////////////////////////////////////////////////////////////// // scopeStack is a stack of scope elements, e.g., context class scopeStack { public: void push(sstr type, sstr name); // push qualified type and name void pop(); // remove last context item sstr type(); // return type of stack top sstr name(); // return name of stack top sstr context(); // display entire context scope top(); // peek at top item size_t size(); // return size of stack private: std::vector stack; }; inline size_t scopeStack::size() { return stack.size(); } inline scope scopeStack::top() { if(stack.size() == 0) return scope("empty","empty"); return stack[stack.size()-1]; } inline void scopeStack::push(sstr type, sstr name) { stack.push_back(scope(type,name)); } inline void scopeStack::pop() { stack.pop_back(); } inline sstr scopeStack::type() { return top()._type; } inline sstr scopeStack::name() { return top()._name; } // /////////////////////////////////////////////////////////////// // type table stores identifiers and their types class typeTable { public: typedef std::map::iterator iterator; void push(csstr& name, csstr& type); // add table entry bool defined(csstr& name); // is object in table? sstr type(csstr& name); // return object's type size_t size(); // return table size sstr show(size_t leadingSpaces=2); // display all contents private: std::map table; }; inline void typeTable::push(csstr& name, csstr& type) { table[name] = type; } inline bool typeTable::defined(csstr& name) { return (table.find(name) != table.end()); } inline size_t typeTable::size() { return table.size(); } // /////////////////////////////////////////////////////////////// // grammar detects C++ grammatical constructs class grammar { public: grammar(semiExp &se); bool include(); // include detector bool functionDef(); // function definition detector bool functionDec(); // function declaration detector size_t invocation(size_t len); // multiple invocation detector bool accessSpecifier(const sstr& tok); // public, ... ? bool specifier(const sstr& tok); // is this token a specifier? bool prefixOper(const sstr& tok); // is prefix declar operator? bool postfixOper(const sstr& tok);// is postfix declar operator? bool keyword(const sstr& tok); // is tok a keyword? bool declar(); // declaration statement detector bool intoScope(); // pushes type on scopeStack if "{" bool outofScope(); // pops scopeStack if "}" void processScope(); // pushes and pops context stack sstr context(); // gets context: namesp::class:: sstr scopeName(); // returns name of current scope sstr scopeType(); // returns type of current scope sstr showScope(); // displays the current scope bool qualifiedType(csstr& tok); // is this namespace, class, ... bool identifier(csstr& tok); // is this token an identifier void saveType(); // extract type declaration if any void saveParamsAndTypes(typeTable& t); void saveIdAndType(typeTable& t); // save declared identifier with type sstr getQualifiedIdentifier(size_t pos); // collect complete identity static void saveType(csstr& type); // save this type in table static bool typeKnown(csstr& name); // have we seen this type? static sstr showTypes(); // show all known types private: std::list compress(); // strip scope qualifiers and templ args bool getScopeInfo(); // helper for intoScope size_t getQualifiedType(); // find position of qualified type bool specialKeys(csstr &s); // is for, while, switch, ... sstr complement(csstr &tok); // find complement, e.g., ">" for "<" semiExp& _se; static scopeStack scope; // all grammar instances share scope static std::set types; // all grammar instances share types }; //----< initializes a grammar object with a semiExp >---------- inline grammar::grammar(semiExp &se) : _se(se) {} //----< detects #include statements >-------------------------- inline bool grammar::include() { return (_se[0]=="#" && _se[1]=="include"); } //----< return context string >-------------------------------- inline sstr grammar::context() { return scope.context(); } // //----< returns current scope identifier >--------------------- inline sstr grammar::scopeName() { return scope.name(); } //----< returns current scope type >--------------------------- inline sstr grammar::scopeType() { return scope.type(); } //----< store type in typeTable >------------------------------ inline void grammar::saveType(csstr& type) { types.insert(type); } //----< is this identifier of know type? >--------------------- inline bool grammar::typeKnown(csstr& name) { return (types.find(name) != types.end()); } #endif