cmFortranParser.y 7.37 KB
Newer Older
1
%{
2
3
/*============================================================================
  CMake - Cross Platform Makefile Generator
4
  Copyright 2000-2015 Kitware, Inc., Insight Software Consortium
5

6
7
  Distributed under the OSI-approved BSD License (the "License");
  see accompanying file Copyright.txt for details.
8

9
10
11
12
  This software is distributed WITHOUT ANY WARRANTY; without even the
  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the License for more information.
============================================================================*/
13
/*-------------------------------------------------------------------------
14
  Portions of this source have been derived from makedepf90 version 2.8.8,
15

16
   Copyright (C) 2000--2006 Erik Edelmann <erik.edelmann@iki.fi>
17
18
19
20
21
22
23
24
25
26
27
28

  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:

29
30
31
32
  bison --yacc --name-prefix=cmFortran_yy
        --defines=cmFortranParserTokens.h
         -ocmFortranParser.cxx
          cmFortranParser.y
33

34
Modify cmFortranParser.cxx:
Brad King's avatar
Brad King committed
35
  - "#if 0" out yyerrorlab block in range ["goto yyerrlab1", "yyerrlab1:"]
36
37
*/

38
/*-------------------------------------------------------------------------*/
39
40
41
#define cmFortranParser_cxx
#include "cmFortranParser.h" /* Interface to parser object.  */
#include "cmFortranParserTokens.h" /* Need YYSTYPE for YY_DECL.  */
42

43
44
#include <cmsys/String.h>

45
46
/* Forward declare the lexer entry point.  */
YY_DECL;
47

Brad King's avatar
Brad King committed
48
49
/* Helper function to forward error callback from parser.  */
static void cmFortran_yyerror(yyscan_t yyscanner, const char* message)
50
{
51
52
  cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
  cmFortranParser_Error(parser, message);
53
}
54

55
static bool cmFortranParserIsKeyword(const char* word,
56
57
                                            const char* keyword)
{
58
  return cmsysString_strcasecmp(word, keyword) == 0;
59
60
}

61
62
63
/* Disable some warnings in the generated code.  */
#ifdef _MSC_VER
# pragma warning (disable: 4102) /* Unused goto label.  */
64
# pragma warning (disable: 4065) /* Switch contains default but no case. */
65
66
67
68
# pragma warning (disable: 4701) /* Local variable may not be initialized.  */
# pragma warning (disable: 4702) /* Unreachable code.  */
# pragma warning (disable: 4127) /* Conditional expression is constant.  */
# pragma warning (disable: 4244) /* Conversion to smaller type, data loss. */
69
#endif
70
71
72
%}

/* Generate a reentrant parser object.  */
Brad King's avatar
Brad King committed
73
74
75
76
77
78
79
%define api.pure

/* Configure the parser to use a lexer object.  */
%lex-param   {yyscan_t yyscanner}
%parse-param {yyscan_t yyscanner}

%define parse.error verbose
80
81
82
83
84

%union {
  char* string;
}

85
86
/*-------------------------------------------------------------------------*/
/* Tokens */
87
%token EOSTMT ASSIGNMENT_OP GARBAGE
88
%token CPP_LINE_DIRECTIVE
89
90
91
%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
92
93
%token F90PPR_IFDEF F90PPR_IFNDEF F90PPR_IF
%token F90PPR_ELSE F90PPR_ELIF F90PPR_ENDIF
94
%token COMMA DCOLON
95
96
%token <number> UNTERMINATED_STRING
%token <string> STRING WORD
97
%token <string> CPP_INCLUDE_ANGLE
98

99
100
/*-------------------------------------------------------------------------*/
/* grammar */
101
102
%%

103
code: /* empty */ | code stmt;
104

105
stmt:
106
107
108
  WORD EOSTMT {
    if (cmFortranParserIsKeyword($1, "interface")) {
      cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
109
      cmFortranParser_SetInInterface(parser, true);
110
111
      }
    free($1);
112
113
114
115
  }
| WORD WORD other EOSTMT {
    if (cmFortranParserIsKeyword($1, "use")) {
      cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
116
      cmFortranParser_RuleUse(parser, $2);
117
118
    } else if (cmFortranParserIsKeyword($1, "module")) {
      cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
119
      cmFortranParser_RuleModule(parser, $2);
120
121
    } else if (cmFortranParserIsKeyword($1, "interface")) {
      cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
122
      cmFortranParser_SetInInterface(parser, true);
123
124
125
    } else if (cmFortranParserIsKeyword($2, "interface") &&
               cmFortranParserIsKeyword($1, "end")) {
      cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
126
      cmFortranParser_SetInInterface(parser, false);
127
    }
128
    free($1);
129
    free($2);
130
131
132
133
  }
| WORD DCOLON WORD other EOSTMT {
    if (cmFortranParserIsKeyword($1, "use")) {
      cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
134
      cmFortranParser_RuleUse(parser, $3);
135
    }
136
137
    free($1);
    free($3);
138
139
  }
| WORD COMMA WORD DCOLON WORD other EOSTMT {
140
    if (cmFortranParserIsKeyword($1, "use") &&
141
142
        cmFortranParserIsKeyword($3, "non_intrinsic") ) {
      cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
143
      cmFortranParser_RuleUse(parser, $5);
144
    }
145
146
147
    free($1);
    free($3);
    free($5);
148
149
150
151
  }
| WORD STRING other EOSTMT {
    if (cmFortranParserIsKeyword($1, "include")) {
      cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
152
      cmFortranParser_RuleInclude(parser, $2);
153
    }
154
155
    free($1);
    free($2);
156
157
158
  }
| CPP_LINE_DIRECTIVE STRING other EOSTMT {
    cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
159
160
    cmFortranParser_RuleLineDirective(parser, $2);
    free($2);
161
162
163
  }
| CPP_INCLUDE_ANGLE other EOSTMT {
    cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
164
    cmFortranParser_RuleInclude(parser, $1);
165
    free($1);
166
167
168
  }
| include STRING other EOSTMT {
    cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
169
    cmFortranParser_RuleInclude(parser, $2);
170
    free($2);
171
172
  }
| define WORD other EOSTMT {
173
174
    cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
    cmFortranParser_RuleDefine(parser, $2);
175
    free($2);
176
177
  }
| undef WORD other EOSTMT {
178
179
    cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
    cmFortranParser_RuleUndef(parser, $2);
180
    free($2);
181
182
  }
| ifdef WORD other EOSTMT {
183
184
    cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
    cmFortranParser_RuleIfdef(parser, $2);
185
    free($2);
186
187
  }
| ifndef WORD other EOSTMT {
188
189
    cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
    cmFortranParser_RuleIfndef(parser, $2);
190
    free($2);
191
192
  }
| if other EOSTMT {
193
194
    cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
    cmFortranParser_RuleIf(parser);
195
196
  }
| elif other EOSTMT {
197
198
    cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
    cmFortranParser_RuleElif(parser);
199
200
  }
| else other EOSTMT {
201
202
    cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
    cmFortranParser_RuleElse(parser);
203
204
  }
| endif other EOSTMT {
205
206
    cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
    cmFortranParser_RuleEndif(parser);
207
  }
208
| EOSTMT
209
| error EOSTMT /* tolerate unknown statements until their end */
210
211
;

212
213
214
215


include: CPP_INCLUDE | F90PPR_INCLUDE | COCO_INCLUDE ;
define: CPP_DEFINE | F90PPR_DEFINE;
216
217
218
219
220
221
222
223
224
225
226
227
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); }
228
229
| GARBAGE
| ASSIGNMENT_OP
230
231
| DCOLON
| COMMA
232
233
234
235
| UNTERMINATED_STRING
;

%%
236
/* End of grammar */