diff options
author | Brad King <brad.king@kitware.com> | 2005-01-26 20:33:38 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2005-01-26 20:33:38 (GMT) |
commit | 19f977bad7261d9e8f8d6c5d2764c079d35cc014 (patch) | |
tree | fdafaf2f6202af5d14201fd1b81e9858e9209162 /Source | |
parent | aaac6f2c3ac9e9f95f0fdad7d77b4de21568ed52 (diff) | |
download | CMake-19f977bad7261d9e8f8d6c5d2764c079d35cc014.zip CMake-19f977bad7261d9e8f8d6c5d2764c079d35cc014.tar.gz CMake-19f977bad7261d9e8f8d6c5d2764c079d35cc014.tar.bz2 |
ENH: Added Fortran dependency scanner implementation.
Diffstat (limited to 'Source')
-rw-r--r-- | Source/cmDependsFortran.cxx | 384 | ||||
-rw-r--r-- | Source/cmDependsFortran.h | 64 | ||||
-rw-r--r-- | Source/cmDependsFortranLexer.in.l | 203 | ||||
-rw-r--r-- | Source/cmDependsFortranParser.h | 70 | ||||
-rw-r--r-- | Source/cmDependsFortranParser.y | 165 |
5 files changed, 886 insertions, 0 deletions
diff --git a/Source/cmDependsFortran.cxx b/Source/cmDependsFortran.cxx new file mode 100644 index 0000000..459476e --- /dev/null +++ b/Source/cmDependsFortran.cxx @@ -0,0 +1,384 @@ +/*========================================================================= + + Program: CMake - Cross-Platform Makefile Generator + Module: $RCSfile$ + Language: C++ + Date: $Date$ + Version: $Revision$ + + Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved. + See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +#include "cmDependsFortran.h" + +#include "cmSystemTools.h" + +#include "cmDependsFortranLexer.h" /* Interface to lexer object. */ +#include "cmDependsFortranParser.h" /* Interface to parser object. */ + +#include <stack> + +//---------------------------------------------------------------------------- +// Parser methods not included in generated interface. +extern "C" +{ + // Get the current buffer processed by the lexer. + YY_BUFFER_STATE cmDependsFortranLexer_GetCurrentBuffer(yyscan_t yyscanner); + + // The parser entry point. + int cmDependsFortranParser_yyparse(yyscan_t); +} + +// Define parser object internal structure. +struct cmDependsFortranFile +{ + FILE* File; + YY_BUFFER_STATE Buffer; + std::string Directory; +}; +struct cmDependsFortranParser_s +{ + cmDependsFortranParser_s(cmDependsFortran* self); + ~cmDependsFortranParser_s(); + + // Pointer back to the main class. + cmDependsFortran* Self; + + // Lexical scanner instance. + yyscan_t Scanner; + + // Stack of open files in the translation unit. + std::stack<cmDependsFortranFile> FileStack; + + // Buffer for string literals. + std::string TokenString; + + // Flag for whether lexer is reading from inside an interface. + int InInterface; + + // Set of provided and required modules. + std::set<cmStdString> Provides; + std::set<cmStdString> Requires; + + // Set of files included in the translation unit. + std::set<cmStdString> Includes; +}; + +//---------------------------------------------------------------------------- +cmDependsFortran::cmDependsFortran(const char* dir, const char* targetFile): + cmDepends(dir, targetFile), + m_SourceFile(), + m_IncludePath(0) +{ +} + +//---------------------------------------------------------------------------- +cmDependsFortran::cmDependsFortran(const char* dir, const char* targetFile, + const char* sourceFile, + std::vector<std::string> const& includes): + cmDepends(dir, targetFile), + m_SourceFile(sourceFile), + m_IncludePath(&includes) +{ +} + +//---------------------------------------------------------------------------- +cmDependsFortran::~cmDependsFortran() +{ +} + +//---------------------------------------------------------------------------- +bool cmDependsFortran::WriteDependencies(std::ostream& os) +{ + // Make sure this is a scanning instance. + if(m_SourceFile == "") + { + cmSystemTools::Error("Cannot scan dependencies without an source file."); + return false; + } + if(!m_IncludePath) + { + cmSystemTools::Error("Cannot scan dependencies without an include path."); + return false; + } + + // Create the parser object. + cmDependsFortranParser parser(this); + + // Push on the starting file. + cmDependsFortranParser_FilePush(&parser, m_SourceFile.c_str()); + + // Parse the translation unit. + if(cmDependsFortranParser_yyparse(parser.Scanner) != 0) + { + // Failed to parse the file. Report failure to write dependencies. + return false; + } + + // Write the dependencies to the output stream. + const std::set<cmStdString>& dependencies = parser.Includes; + for(std::set<cmStdString>::const_iterator i=dependencies.begin(); + i != dependencies.end(); ++i) + { + os << m_TargetFile.c_str() << ": " + << cmSystemTools::ConvertToOutputPath(i->c_str()).c_str() + << std::endl; + } + os << std::endl; + + return true; +} + +//---------------------------------------------------------------------------- +bool cmDependsFortran::CheckDependencies(std::istream&) +{ + return true; +} + +//---------------------------------------------------------------------------- +bool cmDependsFortran::FindIncludeFile(const char* dir, + const char* includeName, + std::string& fileName) +{ + // If the file is a full path, include it directly. + if(cmSystemTools::FileIsFullPath(includeName)) + { + fileName = includeName; + return cmSystemTools::FileExists(fileName.c_str()); + } + else + { + // Check for the file in the directory containing the including + // file. + std::string fullName = dir; + fullName += "/"; + fullName += includeName; + if(cmSystemTools::FileExists(fullName.c_str())) + { + fileName = fullName; + return true; + } + + // Search the include path for the file. + for(std::vector<std::string>::const_iterator i = m_IncludePath->begin(); + i != m_IncludePath->end(); ++i) + { + fullName = *i; + fullName += "/"; + fullName += includeName; + if(cmSystemTools::FileExists(fullName.c_str())) + { + fileName = fullName; + return true; + } + } + } + return false; +} + +//---------------------------------------------------------------------------- +cmDependsFortranParser_s::cmDependsFortranParser_s(cmDependsFortran* self): + Self(self) +{ + this->InInterface = 0; + + // Initialize the lexical scanner. + cmDependsFortranLexer_yylex_init(&this->Scanner); + cmDependsFortranLexer_yyset_extra(this, this->Scanner); + + // Create a dummy buffer that is never read but is the fallback + // buffer when the last file is popped off the stack. + YY_BUFFER_STATE buffer = + cmDependsFortranLexer_yy_create_buffer(0, 4, this->Scanner); + cmDependsFortranLexer_yy_switch_to_buffer(buffer, this->Scanner); +} + +//---------------------------------------------------------------------------- +cmDependsFortranParser_s::~cmDependsFortranParser_s() +{ + cmDependsFortranLexer_yylex_destroy(this->Scanner); +} + +//---------------------------------------------------------------------------- +int cmDependsFortranParser_FilePush(cmDependsFortranParser* parser, + const char* fname) +{ + // Open the new file and push it onto the stack. Save the old + // buffer with it on the stack. + if(FILE* file = fopen(fname, "rb")) + { + YY_BUFFER_STATE current = + cmDependsFortranLexer_GetCurrentBuffer(parser->Scanner); + std::string dir = cmSystemTools::GetParentDirectory(fname); + cmDependsFortranFile f = {file, current, dir}; + YY_BUFFER_STATE buffer = + cmDependsFortranLexer_yy_create_buffer(0, 16384, parser->Scanner); + cmDependsFortranLexer_yy_switch_to_buffer(buffer, parser->Scanner); + parser->FileStack.push(f); + return 1; + } + else + { + return 0; + } +} + +//---------------------------------------------------------------------------- +int cmDependsFortranParser_FilePop(cmDependsFortranParser* parser) +{ + // Pop one file off the stack and close it. Switch the lexer back + // to the next one on the stack. + if(parser->FileStack.empty()) + { + return 0; + } + else + { + cmDependsFortranFile f = parser->FileStack.top(); parser->FileStack.pop(); + fclose(f.File); + YY_BUFFER_STATE current = + cmDependsFortranLexer_GetCurrentBuffer(parser->Scanner); + cmDependsFortranLexer_yy_delete_buffer(current, parser->Scanner); + cmDependsFortranLexer_yy_switch_to_buffer(f.Buffer, parser->Scanner); + return 1; + } +} + +//---------------------------------------------------------------------------- +int cmDependsFortranParser_Input(cmDependsFortranParser* parser, + char* buffer, size_t bufferSize) +{ + // Read from the file on top of the stack. If the stack is empty, + // the end of the translation unit has been reached. + if(!parser->FileStack.empty()) + { + FILE* file = parser->FileStack.top().File; + return (int)fread(buffer, 1, bufferSize, file); + } + return 0; +} + +//---------------------------------------------------------------------------- +void cmDependsFortranParser_StringStart(cmDependsFortranParser* parser) +{ + parser->TokenString = ""; +} + +//---------------------------------------------------------------------------- +const char* cmDependsFortranParser_StringEnd(cmDependsFortranParser* parser) +{ + return parser->TokenString.c_str(); +} + +//---------------------------------------------------------------------------- +void cmDependsFortranParser_StringAppend(cmDependsFortranParser* parser, + char c) +{ + parser->TokenString += c; +} + +//---------------------------------------------------------------------------- +void cmDependsFortranParser_SetInInterface(cmDependsFortranParser* parser, + int in) +{ + parser->InInterface = in; +} + +//---------------------------------------------------------------------------- +int cmDependsFortranParser_GetInInterface(cmDependsFortranParser* parser) +{ + return parser->InInterface; +} + +//---------------------------------------------------------------------------- +void cmDependsFortranParser_Error(cmDependsFortranParser*, const char*) +{ + // If there is a parser error just ignore it. The source will not + // compile and the user will edit it. Then dependencies will have + // to be regenerated anyway. +} + +//---------------------------------------------------------------------------- +void cmDependsFortranParser_RuleUse(cmDependsFortranParser* parser, + const char* name) +{ + parser->Requires.insert(name); +} + +//---------------------------------------------------------------------------- +void cmDependsFortranParser_RuleInclude(cmDependsFortranParser* parser, + const char* name) +{ + // If processing an include statement there must be an open file. + assert(!parser->FileStack.empty()); + + // Get the directory containing the source in which the include + // statement appears. This is always the first search location for + // Fortran include files. + std::string dir = parser->FileStack.top().Directory; + + // Find the included file. If it cannot be found just ignore the + // problem because either the source will not compile or the user + // does not care about depending on this included source. + std::string fullName; + if(parser->Self->FindIncludeFile(dir.c_str(), name, fullName)) + { + // Found the included file. Save it in the set of included files. + parser->Includes.insert(fullName); + + // Parse it immediately to translate the source inline. + cmDependsFortranParser_FilePush(parser, fullName.c_str()); + } +} + +//---------------------------------------------------------------------------- +void cmDependsFortranParser_RuleModule(cmDependsFortranParser* parser, + const char* name) +{ + parser->Provides.insert(name); +} + +//---------------------------------------------------------------------------- +void cmDependsFortranParser_RuleDefine(cmDependsFortranParser*, const char*) +{ +} + +//---------------------------------------------------------------------------- +void cmDependsFortranParser_RuleUndef(cmDependsFortranParser*, const char*) +{ +} + +//---------------------------------------------------------------------------- +void cmDependsFortranParser_RuleIfdef(cmDependsFortranParser*, const char*) +{ +} + +//---------------------------------------------------------------------------- +void cmDependsFortranParser_RuleIfndef(cmDependsFortranParser*, const char*) +{ +} + +//---------------------------------------------------------------------------- +void cmDependsFortranParser_RuleIf(cmDependsFortranParser*) +{ +} + +//---------------------------------------------------------------------------- +void cmDependsFortranParser_RuleElif(cmDependsFortranParser*) +{ +} + +//---------------------------------------------------------------------------- +void cmDependsFortranParser_RuleElse(cmDependsFortranParser*) +{ +} + +//---------------------------------------------------------------------------- +void cmDependsFortranParser_RuleEndif(cmDependsFortranParser*) +{ +} diff --git a/Source/cmDependsFortran.h b/Source/cmDependsFortran.h new file mode 100644 index 0000000..7cd920d --- /dev/null +++ b/Source/cmDependsFortran.h @@ -0,0 +1,64 @@ +/*========================================================================= + + Program: CMake - Cross-Platform Makefile Generator + Module: $RCSfile$ + Language: C++ + Date: $Date$ + Version: $Revision$ + + Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved. + See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +#ifndef cmDependsFortran_h +#define cmDependsFortran_h + +#include "cmDepends.h" + +/** \class cmDependsFortran + * \brief Dependency scanner for Fortran object files. + */ +class cmDependsFortran: public cmDepends +{ +public: + /** Checking instances need to know the build directory name and the + relative path from the build directory to the target file. */ + cmDependsFortran(const char* dir, const char* targetFile); + + /** Scanning need to know the build directory name, the relative + path from the build directory to the target file, the source + file from which to start scanning, and the include file search + path. */ + cmDependsFortran(const char* dir, const char* targetFile, + const char* sourceFile, std::vector<std::string> const& includes); + + /** Virtual destructor to cleanup subclasses properly. */ + virtual ~cmDependsFortran(); + + /** Method to find an included file in the include path. Fortran + always searches the directory containing the including source + first. */ + bool FindIncludeFile(const char* dir, const char* includeName, + std::string& fileName); + +protected: + // Implement writing/checking methods required by superclass. + virtual bool WriteDependencies(std::ostream& os); + virtual bool CheckDependencies(std::istream& is); + + // The source file from which to start scanning. + std::string m_SourceFile; + + // The include file search path. + std::vector<std::string> const* m_IncludePath; + +private: + cmDependsFortran(cmDependsFortran const&); // Purposely not implemented. + void operator=(cmDependsFortran const&); // Purposely not implemented. +}; + +#endif diff --git a/Source/cmDependsFortranLexer.in.l b/Source/cmDependsFortranLexer.in.l new file mode 100644 index 0000000..4a6518fb --- /dev/null +++ b/Source/cmDependsFortranLexer.in.l @@ -0,0 +1,203 @@ +%{ +/*========================================================================= + + Program: CMake - Cross-Platform Makefile Generator + Module: $RCSfile$ + Language: C++ + Date: $Date$ + Version: $Revision$ + + Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved. + See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +/*------------------------------------------------------------------------- + Portions of this source have been derived from makefdep90 version 2.6.2, + + Copyright (C) 2000,2001 Erik Edelmann <eedelman@beam.helsinki.fi>. + + The code was originally distributed under the GPL but permission + from the copyright holder has been obtained to distribute this + derived work under the CMake license. +-------------------------------------------------------------------------*/ + +/* + +This file must be translated to C and modified to build everywhere. + +Run flex like this: + + flex --prefix=cmDependsFortran_yy --header-file=cmDependsFortranLexer.h -ocmDependsFortranLexer.c cmDependsFortranLexer.in.l + +Modify cmDependsFortranLexer.c: + - remove TABs + - add a statement "(void)yyscanner;" to the top of these methods: + yy_fatal_error, yyalloc, yyrealloc, yyfree + - remove all YY_BREAK lines occurring right after return statements + +Modify cmDependsFortranLexer.h: + - remove TABs + - remove the yy_init_globals function + - add these lines around all function declarations: + #ifdef __cplusplus + extern "C" + { + #endif + ... + #ifdef __cplusplus + } + #endif + +*/ + +#include "cmDependsFortranParser.h" /* Interface to parser object. */ + +/* Disable some warnings. */ +#if defined(_MSC_VER) +# pragma warning ( disable : 4127 ) +# pragma warning ( disable : 4131 ) +# pragma warning ( disable : 4244 ) +# pragma warning ( disable : 4251 ) +# pragma warning ( disable : 4267 ) +# pragma warning ( disable : 4305 ) +# pragma warning ( disable : 4309 ) +# pragma warning ( disable : 4706 ) +# pragma warning ( disable : 4786 ) +#endif + +/* Disable features we do not need. */ +#define YY_NEVER_INTERACTIVE 1 +#define YY_NO_UNISTD_H 1 +#define ECHO + +/* Setup the proper yylex declaration. */ +#define YY_EXTRA_TYPE cmDependsFortranParser* +#define YY_DECL int cmDependsFortran_yylex(YYSTYPE* yylvalp, yyscan_t yyscanner) + +/* Replace the lexer input function. */ +#undef YY_INPUT +#define YY_INPUT(buf, result, max_size) \ + { result = cmDependsFortranParser_Input(yyextra, buf, max_size); } + +/* Include the set of tokens from the parser. */ +#include "cmDependsFortranParserTokens.h" + +/*--------------------------------------------------------------------------*/ +%} + +%option reentrant +%option noyywrap +%pointer + +%s free_fmt fixed_fmt +%x str_sq str_dq + +%% + +\" { + cmDependsFortranParser_StringStart(yyextra); + BEGIN(str_dq); +} + +' { + cmDependsFortranParser_StringStart(yyextra); + BEGIN(str_sq); +} + +<str_dq>\" | +<str_sq>' { + yylvalp->string = strdup(cmDependsFortranParser_StringEnd(yyextra)); + return STRING; +} + +<str_dq,str_sq>&[ \t]*\n | +<str_dq,str_sq>&[ \t]*\n[ \t]*& /* Ignore (continued strings, free fmt) */ + +<fixed_fmt,str_dq,str_sq>\n[ ]{5}[^ \t\n] /*Ignore (cont. strings, fixed fmt) */ + +<str_dq,str_sq>\n { + unput ('\n'); + BEGIN(INITIAL); + return UNTERMINATED_STRING; +} + +<str_sq,str_dq>. { + cmDependsFortranParser_StringAppend(yyextra, yytext[0]); +} + +!.*\n { return EOSTMT; } /* Treat comments like */ +<fixed_fmt>^[cC*dD].*\n { return EOSTMT; } /* empty lines */ + +#[ \t]*include { return CPP_INCLUDE; } +\$[ \t]*include { return F90PPR_INCLUDE; } +\?\?[ \t]*include { return COCO_INCLUDE; } +INCLUDE { return F_INCLUDE; } +USE { return USE; } + +END" "*INTERFACE { + cmDependsFortranParser_SetInInterface(yyextra, 0); +} +INTERFACE { + cmDependsFortranParser_SetInInterface(yyextra, 1); +} + +END" "*MODULE /* Ignore */ +MODULE { + if(!cmDependsFortranParser_GetInInterface(yyextra)) + { + return MODULE; + } +} + +#[ \t]*define { return CPP_DEFINE; } +\$[ \t]*DEFINE { return F90PPR_DEFINE; } + +#[ \t]*undef { return CPP_UNDEF; } +\$[ \t]*UNDEF { return F90PPR_UNDEF; } + +#[ \t]*ifdef { return CPP_IFDEF; } +#[ \t]*ifndef { return CPP_IFNDEF; } +#[ \t]*if { return CPP_IF; } +#[ \t]*elif { return CPP_ELIF; } +#[ \t]*else { return CPP_ELSE; } +#[ \t]*endif { return CPP_ENDIF; } + +$[ \t]*ifdef { return F90PPR_IFDEF; } +$[ \t]*ifndef { return F90PPR_IFNDEF; } +$[ \t]*if { return F90PPR_IF; } +$[ \t]*elif { return F90PPR_ELIF; } +$[ \t]*else { return F90PPR_ELSE; } +$[ \t]*endif { return F90PPR_ENDIF; } + +&[ \t]*\n | +&[ \t]*\n[ \t]*& /* Ignore */ + + +[^ \t\n\r;,!'""']+ { yylvalp->string = strdup(yytext); return WORD; } + +;|\n { return EOSTMT; } + +[ \t\r,] /* Ignore */ + +. { return *yytext; } + +<<EOF>> { + if(!cmDependsFortranParser_FilePop(yyextra)) + { + return YY_NULL; + } +} + +%% + +/*--------------------------------------------------------------------------*/ +YY_BUFFER_STATE cmDependsFortranLexer_GetCurrentBuffer(yyscan_t yyscanner) +{ + /* Hack into the internal flex-generated scanner to get the buffer. */ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return YY_CURRENT_BUFFER; +} diff --git a/Source/cmDependsFortranParser.h b/Source/cmDependsFortranParser.h new file mode 100644 index 0000000..44cb1d5 --- /dev/null +++ b/Source/cmDependsFortranParser.h @@ -0,0 +1,70 @@ +/*========================================================================= + + Program: CMake - Cross-Platform Makefile Generator + Module: $RCSfile$ + Language: C++ + Date: $Date$ + Version: $Revision$ + + Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved. + See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +#ifndef cmDependsFortranParser_h +#define cmDependsFortranParser_h + +/* Forward declare parser object type. */ +typedef struct cmDependsFortranParser_s cmDependsFortranParser; + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Functions to enter/exit #include'd files in order. */ +int cmDependsFortranParser_FilePush(cmDependsFortranParser* parser, + const char* fname); +int cmDependsFortranParser_FilePop(cmDependsFortranParser* parser); + +/* Callbacks for lexer. */ +int cmDependsFortranParser_Input(cmDependsFortranParser* parser, + char* buffer, size_t bufferSize); +void cmDependsFortranParser_StringStart(cmDependsFortranParser* parser); +const char* cmDependsFortranParser_StringEnd(cmDependsFortranParser* parser); +void cmDependsFortranParser_StringAppend(cmDependsFortranParser* parser, + char c); +void cmDependsFortranParser_SetInInterface(cmDependsFortranParser* parser, + int in); +int cmDependsFortranParser_GetInInterface(cmDependsFortranParser* parser); + +/* Callbacks for parser. */ +void cmDependsFortranParser_Error(cmDependsFortranParser* parser, + const char* message); +void cmDependsFortranParser_RuleUse(cmDependsFortranParser* parser, + const char* name); +void cmDependsFortranParser_RuleInclude(cmDependsFortranParser* parser, + const char* name); +void cmDependsFortranParser_RuleModule(cmDependsFortranParser* parser, + const char* name); +void cmDependsFortranParser_RuleDefine(cmDependsFortranParser* parser, + const char* name); +void cmDependsFortranParser_RuleUndef(cmDependsFortranParser* parser, + const char* name); +void cmDependsFortranParser_RuleIfdef(cmDependsFortranParser* parser, + const char* name); +void cmDependsFortranParser_RuleIfndef(cmDependsFortranParser* parser, + const char* name); +void cmDependsFortranParser_RuleIf(cmDependsFortranParser* parser); +void cmDependsFortranParser_RuleElif(cmDependsFortranParser* parser); +void cmDependsFortranParser_RuleElse(cmDependsFortranParser* parser); +void cmDependsFortranParser_RuleEndif(cmDependsFortranParser* parser); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/Source/cmDependsFortranParser.y b/Source/cmDependsFortranParser.y new file mode 100644 index 0000000..ba3ea59 --- /dev/null +++ b/Source/cmDependsFortranParser.y @@ -0,0 +1,165 @@ +%{ +/*========================================================================= + + Program: CMake - Cross-Platform Makefile Generator + Module: $RCSfile$ + Language: C++ + Date: $Date$ + Version: $Revision$ + + Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved. + See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +/*------------------------------------------------------------------------- + Portions of this source have been derived from makefdep90 version 2.6.2, + + Copyright (C) 2000,2001 Erik Edelmann <eedelman@beam.helsinki.fi>. + + The code was originally distributed under the GPL but permission + from the copyright holder has been obtained to distribute this + derived work under the CMake license. +-------------------------------------------------------------------------*/ + +/* + +This file must be translated to C and modified to build everywhere. + +Run bison like this: + + bison --yacc --name-prefix=cmDependsFortran_yy --defines=cmDependsFortranParserTokens.h -ocmDependsFortranParser.c cmDependsFortranParser.y + +*/ + +/* Configure the parser to use a lexer object. */ +#define YYPARSE_PARAM yyscanner +#define YYLEX_PARAM yyscanner +#define YY_DECL int cmDependsFortran_yylex(YYSTYPE* yylvalp, yyscan_t yyscanner) +#define YYERROR_VERBOSE 1 +#define cmDependsFortran_yyerror(x) \ + cmDependsFortranError(yyscanner, x) + +#include "cmDependsFortranLexer.h" /* Interface to lexer object. */ +#include "cmDependsFortranParser.h" /* Interface to parser object. */ + +/* Internal utility functions. */ +static void cmDependsFortranError(yyscan_t yyscanner, const char* message); + +%} + +/* Generate a reentrant parser object. */ +%pure_parser + +%union { + char* string; +} + +%token USE F_INCLUDE MODULE EOSTMT +%token CPP_INCLUDE F90PPR_INCLUDE COCO_INCLUDE +%token F90PPR_DEFINE CPP_DEFINE F90PPR_UNDEF CPP_UNDEF +%token CPP_IFDEF CPP_IFNDEF CPP_IF CPP_ELSE CPP_ELIF CPP_ENDIF +%token F90PPR_IFDEF F90PPR_IFNDEF F90PPR_IF F90PPR_ELSE F90PPR_ELIF F90PPR_ENDIF +%token UNTERMINATED_STRING +%token <string> CPP_TOENDL STRING WORD + +%% + +code: /* empty */ | code stmt ; + +stmt: + USE WORD other eostmt + { + cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner); + cmDependsFortranParser_RuleUse(parser, $2); + free($2); + } +| include STRING other eostmt + { + cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner); + cmDependsFortranParser_RuleInclude(parser, $2); + free($2); + } +| CPP_INCLUDE WORD other eostmt /* Ignore */ +| MODULE WORD eostmt + { + cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner); + cmDependsFortranParser_RuleModule(parser, $2); + free($2); + } +| define WORD other eostmt + { + cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner); + cmDependsFortranParser_RuleDefine(parser, $2); + free($2); + } +| undef WORD other eostmt + { + cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner); + cmDependsFortranParser_RuleUndef(parser, $2); + free($2); + } +| ifdef WORD other eostmt + { + cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner); + cmDependsFortranParser_RuleIfdef(parser, $2); + free($2); + } +| ifndef WORD other eostmt + { + cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner); + cmDependsFortranParser_RuleIfndef(parser, $2); + free($2); + } +| if other eostmt + { + cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner); + cmDependsFortranParser_RuleIf(parser); + } +| elif other eostmt + { + cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner); + cmDependsFortranParser_RuleElif(parser); + } +| else other eostmt + { + cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner); + cmDependsFortranParser_RuleElse(parser); + } +| endif other eostmt + { + cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner); + cmDependsFortranParser_RuleEndif(parser); + } +| other eostmt /* Ignore */ +; + +eostmt: /* empty */ | EOSTMT ; +include: F_INCLUDE | CPP_INCLUDE | F90PPR_INCLUDE | COCO_INCLUDE ; +define: CPP_DEFINE | F90PPR_DEFINE ; +undef: CPP_UNDEF | F90PPR_UNDEF ; +ifdef: CPP_IFDEF | F90PPR_IFDEF ; +ifndef: CPP_IFNDEF | F90PPR_IFNDEF ; +if: CPP_IF | F90PPR_IF ; +elif: CPP_ELIF | F90PPR_ELIF ; +else: CPP_ELSE | F90PPR_ELSE ; +endif: CPP_ENDIF | F90PPR_ENDIF ; +other: /* empty */ | other misc_code ; + +misc_code: + WORD { free ($1); } +| STRING { free ($1); } +| UNTERMINATED_STRING +; + +%% + +/*--------------------------------------------------------------------------*/ +void cmDependsFortranError(yyscan_t yyscanner, const char* message) +{ + cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner); + cmDependsFortranParser_Error(parser, message); +} |