//////////////////////////////////////////////////////////////////////////// /// Automaton for recognizing valid C identifiers /// @author Suradet Jitprapaikulsarn /// @date 2005 June 28 /// @remark Microsoft Visual C++ 2003 /// @note Copyright (C) 2005 Suradet Jitprapaikulsarn //////////////////////////////////////////////////////////////////////////// #include "State.h" #include "InputSymbol.h" #include #include #include #include //************************************************************************** // Prototypes //************************************************************************** bool scan(const std::string & fileName); InputSymbol checkType(char ch); //************************************************************************** // main //************************************************************************** int main() { std::string fileName; std::cout << "Please enter the C source file name : "; std::cin >> fileName; if ( !scan(fileName) ) { std::cerr << "Error!!! Failed to scan the file " << fileName << "\n"; } return 0; } //========================================================================== // @description scan a file for valid C idenifiers assuming there is no comment // @param fileName the name of the input file // @return true if success, false otherwise // @contract scan: string -> bool // @example scan("test.c") == false // @example scan("scan.cpp") == true // @example scan("state.h") == true //========================================================================== bool scan(const std::string & fileName) { std::ifstream ifs(fileName.c_str()); // Check if the file can be opened if ( !ifs ) return false; char ch; State currentState = s0; InputSymbol type; std::string token = ""; while (ifs) { ch = ifs.get(); type = checkType(ch); switch (currentState) { case s0: switch (type) { case English: token += ch; currentState = s1; break; case Underscore: token += ch; currentState = s1; break; case Number: break; case Others: break; default: std::cerr << "Invalid type of symbols\n"; } // switch type break; case s1: switch (type) { case English: token += ch; break; case Underscore: token += ch; break; case Number: token += ch; break; case Others: std::cout << "token = " << token << "\n"; currentState = s0; token = ""; break; default: std::cerr << "Invalid type of symbols\n"; } // switch type break; default: std::cerr << "Invalid state\n"; } // switch state } // while return true; } //========================================================================== // @description determine the group of symbols of the input character // @param ch the input character // @return the name of the group of symbols // @contract checkType : int -> InputSymbol // @example checkType('c') == English // @example checkType('_') == Underscore // @example checkType('5') == Number // @example checkType(' ') == Others //========================================================================== InputSymbol checkType(char ch) { if ( std::isalpha(ch) ) { return English; } else if ( ch == '_' ) { return Underscore; } else if ( std::isdigit(ch) ) { return Number; } else { return Others; } }