ENH: Added Fortran dependency scanner implementation.

This commit is contained in:
Brad King 2005-01-26 15:33:38 -05:00
parent aaac6f2c3a
commit 19f977bad7
5 changed files with 886 additions and 0 deletions

384
Source/cmDependsFortran.cxx Normal file
View File

@ -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*)
{
}

64
Source/cmDependsFortran.h Normal file
View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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);
}