cmFortranParser.y 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. %{
  2. /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  3. file Copyright.txt or https://cmake.org/licensing for details. */
  4. /*-------------------------------------------------------------------------
  5. Portions of this source have been derived from makedepf90 version 2.8.8,
  6. Copyright (C) 2000--2006 Erik Edelmann <erik.edelmann@iki.fi>
  7. The code was originally distributed under the GPL but permission
  8. from the copyright holder has been obtained to distribute this
  9. derived work under the CMake license.
  10. -------------------------------------------------------------------------*/
  11. /*
  12. This file must be translated to C and modified to build everywhere.
  13. Run bison like this:
  14. bison --yacc --name-prefix=cmFortran_yy
  15. --defines=cmFortranParserTokens.h
  16. -ocmFortranParser.cxx
  17. cmFortranParser.y
  18. Modify cmFortranParser.cxx:
  19. - "#if 0" out yyerrorlab block in range ["goto yyerrlab1", "yyerrlab1:"]
  20. */
  21. #include "cmConfigure.h" // IWYU pragma: keep
  22. #include "cmsys/String.h"
  23. #include <stdlib.h>
  24. #include <string.h>
  25. /*-------------------------------------------------------------------------*/
  26. #define cmFortranParser_cxx
  27. #include "cmFortranParser.h" /* Interface to parser object. */
  28. #include "cmFortranParserTokens.h" /* Need YYSTYPE for YY_DECL. */
  29. /* Forward declare the lexer entry point. */
  30. YY_DECL;
  31. /* Helper function to forward error callback from parser. */
  32. static void cmFortran_yyerror(yyscan_t yyscanner, const char* message)
  33. {
  34. cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
  35. cmFortranParser_Error(parser, message);
  36. }
  37. /* Disable some warnings in the generated code. */
  38. #ifdef _MSC_VER
  39. # pragma warning (disable: 4102) /* Unused goto label. */
  40. # pragma warning (disable: 4065) /* Switch contains default but no case. */
  41. # pragma warning (disable: 4701) /* Local variable may not be initialized. */
  42. # pragma warning (disable: 4702) /* Unreachable code. */
  43. # pragma warning (disable: 4127) /* Conditional expression is constant. */
  44. # pragma warning (disable: 4244) /* Conversion to smaller type, data loss. */
  45. #endif
  46. %}
  47. /* Generate a reentrant parser object. */
  48. %define api.pure
  49. /* Configure the parser to use a lexer object. */
  50. %lex-param {yyscan_t yyscanner}
  51. %parse-param {yyscan_t yyscanner}
  52. %define parse.error verbose
  53. %union {
  54. char* string;
  55. }
  56. /*-------------------------------------------------------------------------*/
  57. /* Tokens */
  58. %token EOSTMT ASSIGNMENT_OP GARBAGE
  59. %token CPP_LINE_DIRECTIVE
  60. %token CPP_INCLUDE F90PPR_INCLUDE COCO_INCLUDE
  61. %token F90PPR_DEFINE CPP_DEFINE F90PPR_UNDEF CPP_UNDEF
  62. %token CPP_IFDEF CPP_IFNDEF CPP_IF CPP_ELSE CPP_ELIF CPP_ENDIF
  63. %token F90PPR_IFDEF F90PPR_IFNDEF F90PPR_IF
  64. %token F90PPR_ELSE F90PPR_ELIF F90PPR_ENDIF
  65. %token COMMA COLON DCOLON LPAREN RPAREN
  66. %token <number> UNTERMINATED_STRING
  67. %token <string> STRING WORD
  68. %token <string> CPP_INCLUDE_ANGLE
  69. %token END
  70. %token INCLUDE
  71. %token INTERFACE
  72. %token MODULE
  73. %token SUBMODULE
  74. %token USE
  75. /*-------------------------------------------------------------------------*/
  76. /* grammar */
  77. %%
  78. code: /* empty */ | code stmt;
  79. stmt:
  80. INTERFACE EOSTMT {
  81. cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
  82. cmFortranParser_SetInInterface(parser, true);
  83. }
  84. | USE WORD other EOSTMT {
  85. cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
  86. cmFortranParser_RuleUse(parser, $2);
  87. free($2);
  88. }
  89. | MODULE WORD other EOSTMT {
  90. cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
  91. if (cmsysString_strcasecmp($2, "function") != 0 &&
  92. cmsysString_strcasecmp($2, "procedure") != 0 &&
  93. cmsysString_strcasecmp($2, "subroutine") != 0) {
  94. cmFortranParser_RuleModule(parser, $2);
  95. }
  96. free($2);
  97. }
  98. | SUBMODULE LPAREN WORD RPAREN WORD other EOSTMT {
  99. cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
  100. cmFortranParser_RuleUse(parser, $3);
  101. free($3);
  102. free($5);
  103. }
  104. | SUBMODULE LPAREN WORD COLON WORD RPAREN WORD other EOSTMT {
  105. cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
  106. cmFortranParser_RuleUse(parser, $3);
  107. free($3);
  108. free($5);
  109. free($7);
  110. }
  111. | INTERFACE WORD other EOSTMT {
  112. cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
  113. cmFortranParser_SetInInterface(parser, true);
  114. free($2);
  115. }
  116. | END INTERFACE other EOSTMT {
  117. cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
  118. cmFortranParser_SetInInterface(parser, false);
  119. }
  120. | USE DCOLON WORD other EOSTMT {
  121. cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
  122. cmFortranParser_RuleUse(parser, $3);
  123. free($3);
  124. }
  125. | USE COMMA WORD DCOLON WORD other EOSTMT {
  126. if (cmsysString_strcasecmp($3, "non_intrinsic") == 0) {
  127. cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
  128. cmFortranParser_RuleUse(parser, $5);
  129. }
  130. free($3);
  131. free($5);
  132. }
  133. | INCLUDE STRING other EOSTMT {
  134. cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
  135. cmFortranParser_RuleInclude(parser, $2);
  136. free($2);
  137. }
  138. | CPP_LINE_DIRECTIVE STRING other EOSTMT {
  139. cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
  140. cmFortranParser_RuleLineDirective(parser, $2);
  141. free($2);
  142. }
  143. | CPP_INCLUDE_ANGLE other EOSTMT {
  144. cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
  145. cmFortranParser_RuleInclude(parser, $1);
  146. free($1);
  147. }
  148. | include STRING other EOSTMT {
  149. cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
  150. cmFortranParser_RuleInclude(parser, $2);
  151. free($2);
  152. }
  153. | define WORD other EOSTMT {
  154. cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
  155. cmFortranParser_RuleDefine(parser, $2);
  156. free($2);
  157. }
  158. | undef WORD other EOSTMT {
  159. cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
  160. cmFortranParser_RuleUndef(parser, $2);
  161. free($2);
  162. }
  163. | ifdef WORD other EOSTMT {
  164. cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
  165. cmFortranParser_RuleIfdef(parser, $2);
  166. free($2);
  167. }
  168. | ifndef WORD other EOSTMT {
  169. cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
  170. cmFortranParser_RuleIfndef(parser, $2);
  171. free($2);
  172. }
  173. | if other EOSTMT {
  174. cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
  175. cmFortranParser_RuleIf(parser);
  176. }
  177. | elif other EOSTMT {
  178. cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
  179. cmFortranParser_RuleElif(parser);
  180. }
  181. | else other EOSTMT {
  182. cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
  183. cmFortranParser_RuleElse(parser);
  184. }
  185. | endif other EOSTMT {
  186. cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
  187. cmFortranParser_RuleEndif(parser);
  188. }
  189. | EOSTMT
  190. | error EOSTMT /* tolerate unknown statements until their end */
  191. ;
  192. include: CPP_INCLUDE | F90PPR_INCLUDE | COCO_INCLUDE ;
  193. define: CPP_DEFINE | F90PPR_DEFINE;
  194. undef: CPP_UNDEF | F90PPR_UNDEF ;
  195. ifdef: CPP_IFDEF | F90PPR_IFDEF ;
  196. ifndef: CPP_IFNDEF | F90PPR_IFNDEF ;
  197. if: CPP_IF | F90PPR_IF ;
  198. elif: CPP_ELIF | F90PPR_ELIF ;
  199. else: CPP_ELSE | F90PPR_ELSE ;
  200. endif: CPP_ENDIF | F90PPR_ENDIF ;
  201. other: /* empty */ | other misc_code ;
  202. misc_code:
  203. WORD { free ($1); }
  204. | END
  205. | INCLUDE
  206. | INTERFACE
  207. | MODULE
  208. | SUBMODULE
  209. | USE
  210. | STRING { free ($1); }
  211. | GARBAGE
  212. | ASSIGNMENT_OP
  213. | COLON
  214. | DCOLON
  215. | LPAREN
  216. | RPAREN
  217. | COMMA
  218. | UNTERMINATED_STRING
  219. ;
  220. %%
  221. /* End of grammar */