or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

code-generation.mdcommand-line.mdindex.mdparsing-ast.mdruntime.mdtransformation.mdtype-system.md

parsing-ast.mddocs/

0

# Parsing and AST

1

2

Comprehensive parsing of Fortran 90/95/2003/2008 source code into a structured Abstract Syntax Tree (AST) with full support for modern Fortran constructs including modules, derived types, procedures, and interfaces.

3

4

## Capabilities

5

6

### Source File Parsing

7

8

Parse Fortran source files into a complete Abstract Syntax Tree representation.

9

10

```python { .api }

11

def read_files(args, doc_plugin_filename=None):

12

"""

13

Parse Fortran source files into AST.

14

15

Parameters:

16

- args: list of Fortran source file paths

17

- doc_plugin_filename: optional documentation plugin file

18

19

Returns:

20

Root AST node containing parsed tree

21

"""

22

```

23

24

### AST Node Classes

25

26

#### Base Node Classes

27

28

```python { .api }

29

class Fortran(object):

30

"""Base class for all AST nodes."""

31

32

class Root(Fortran):

33

"""Root node of the parse tree."""

34

35

class Program(Fortran):

36

"""Fortran program node."""

37

38

class Module(Fortran):

39

"""Fortran module node with name, procedures, types."""

40

```

41

42

#### Procedure Node Classes

43

44

```python { .api }

45

class Procedure(Fortran):

46

"""Base class for procedures (subroutines and functions)."""

47

48

class Subroutine(Procedure):

49

"""Subroutine node with arguments, local variables."""

50

51

class Function(Procedure):

52

"""Function node with arguments, return value, local variables."""

53

54

class Interface(Fortran):

55

"""Interface block node containing procedure prototypes."""

56

57

class Prototype(Fortran):

58

"""Procedure prototype within an interface."""

59

60

class Binding(Fortran):

61

"""Type-bound procedure binding."""

62

```

63

64

#### Type and Variable Node Classes

65

66

```python { .api }

67

class Type(Fortran):

68

"""Derived type definition with components and procedures."""

69

70

class Declaration(Fortran):

71

"""Variable or parameter declaration."""

72

73

class Element(Declaration):

74

"""Component element within a derived type."""

75

76

class Argument(Declaration):

77

"""Procedure argument with intent and attributes."""

78

```

79

80

### Tree Traversal and Analysis

81

82

#### Basic Traversal Functions

83

84

```python { .api }

85

def iter_fields(node):

86

"""Iterate over all fields of an AST node."""

87

88

def iter_child_nodes(node):

89

"""Iterate over all child nodes of an AST node."""

90

91

def walk(node):

92

"""Recursively walk the entire AST tree."""

93

94

def walk_modules(node):

95

"""Walk only module nodes in the tree."""

96

97

def walk_procedures(tree, include_ret_val=True):

98

"""Walk all procedure nodes in the tree."""

99

```

100

101

#### Search and Analysis Functions

102

103

```python { .api }

104

def find(tree, pattern):

105

"""Find nodes matching a specific pattern."""

106

107

def find_types(tree, skipped_types=None):

108

"""Find all derived type definitions in the tree."""

109

110

def find_procedure_module(tree, node):

111

"""

112

Find the module in tree that contains node.

113

114

Parameters:

115

- tree: AST tree to search

116

- node: procedure node to locate

117

118

Returns:

119

Module node containing the procedure, or None if not found

120

"""

121

122

def find_source(node):

123

"""Get source location information for a node."""

124

125

def print_source(node, out=None):

126

"""Print the source code representation of a node."""

127

128

def dump(node):

129

"""Debug dump of node structure and contents."""

130

```

131

132

### File Representation

133

134

```python { .api }

135

class F90File(object):

136

"""Represents a Fortran source file being parsed."""

137

```

138

139

### Parsing Functions

140

141

#### Structure Parsing

142

143

```python { .api }

144

def check_program(cl, file):

145

"""Parse PROGRAM statements."""

146

147

def check_module(cl, file):

148

"""Parse MODULE statements and module contents."""

149

150

def check_subt(cl, file, grab_hold_doc=True):

151

"""Parse SUBROUTINE and TYPE statements."""

152

153

def check_funct(cl, file, grab_hold_doc=True):

154

"""Parse FUNCTION statements."""

155

156

def check_type(cl, file):

157

"""Parse TYPE definitions and components."""

158

159

def check_interface(cl, file):

160

"""Parse INTERFACE blocks and contained procedures."""

161

```

162

163

#### Declaration Parsing

164

165

```python { .api }

166

def check_decl(cl, file):

167

"""Parse variable and parameter declarations."""

168

169

def check_arg(cl, file):

170

"""Parse procedure arguments with attributes."""

171

172

def check_binding(cl, file):

173

"""Parse type-bound procedure bindings."""

174

175

def check_prototype(cl, file):

176

"""Parse procedure prototypes in interfaces."""

177

```

178

179

#### Utility Parsing Functions

180

181

```python { .api }

182

def check_uses(cline, file):

183

"""Parse USE statements and module imports."""

184

185

def check_doc(cline, file):

186

"""Parse documentation comments (Doxygen-style)."""

187

188

def check_doc_rv(cline, file):

189

"""Parse return value documentation."""

190

191

def check_cont(cline, file):

192

"""Handle line continuations in source code."""

193

```

194

195

### String and Name Processing

196

197

```python { .api }

198

def remove_delimited(line, d1, d2):

199

"""Remove delimited sections (quotes, comments) from code lines."""

200

201

def recover_delimited(line, d1, d2, delimited):

202

"""Restore previously removed delimited sections."""

203

204

def split_attribs(atr):

205

"""Parse Fortran attribute strings into components."""

206

207

def splitnames(names):

208

"""Split comma-separated name lists into individual names."""

209

```

210

211

### Type System Support

212

213

```python { .api }

214

def implicit_type_rule(var):

215

"""Apply Fortran implicit typing rules to variables."""

216

217

def implicit_to_explicit_arguments(argl, ag_temp):

218

"""Convert implicit argument lists to explicit form."""

219

```

220

221

### Visitor Pattern Classes

222

223

```python { .api }

224

class FortranVisitor(object):

225

"""Base visitor class for traversing AST nodes."""

226

227

class FortranTransformer(FortranVisitor):

228

"""Base transformer class for modifying AST nodes."""

229

230

class FortranTreeDumper(FortranVisitor):

231

"""Debug visitor for dumping tree structure."""

232

233

class LowerCaseConverter(FortranTransformer):

234

"""Convert all names in AST to lowercase."""

235

236

class RepeatedInterfaceCollapser(FortranTransformer):

237

"""Collapse interfaces that appear multiple times with identical signatures."""

238

239

class AccessUpdater(FortranTransformer):

240

"""Update access control attributes (public/private) throughout the tree."""

241

242

class PrivateSymbolsRemover(FortranTransformer):

243

"""Remove private symbols that should not be accessible from Python."""

244

```

245

246

### Utility Functions

247

248

```python { .api }

249

def fix_argument_attributes(node):

250

"""Fix parsing issues with argument attributes."""

251

252

def remove_private_symbols(node):

253

"""Remove private symbols from module nodes."""

254

```

255

256

## Usage Examples

257

258

### Basic Parsing

259

260

```python

261

import f90wrap.parser as parser

262

263

# Parse a single file

264

tree = parser.read_files(['source.f90'])

265

266

# Parse multiple files

267

tree = parser.read_files(['mod1.f90', 'mod2.f90', 'main.f90'])

268

269

# Parse with documentation plugin

270

tree = parser.read_files(['source.f90'], doc_plugin_filename='doc_plugin.py')

271

```

272

273

### Tree Traversal

274

275

```python

276

from f90wrap.fortran import walk, walk_modules, find_types

277

278

# Walk all nodes

279

for node in walk(tree):

280

print(f"Node type: {type(node).__name__}")

281

282

# Walk only modules

283

for module in walk_modules(tree):

284

print(f"Module: {module.name}")

285

286

# Find all derived types

287

types = find_types(tree)

288

for type_node in types:

289

print(f"Type: {type_node.name}")

290

```

291

292

### Using Visitors

293

294

```python

295

from f90wrap.fortran import FortranVisitor

296

297

class MyVisitor(FortranVisitor):

298

def visit_Module(self, node):

299

print(f"Visiting module: {node.name}")

300

self.generic_visit(node)

301

302

def visit_Subroutine(self, node):

303

print(f"Visiting subroutine: {node.name}")

304

self.generic_visit(node)

305

306

visitor = MyVisitor()

307

visitor.visit(tree)

308

```

309

310

## Supported Fortran Features

311

312

- **Modules**: Module definitions, USE statements, public/private access

313

- **Derived Types**: Type definitions, components, type-bound procedures

314

- **Procedures**: Subroutines, functions, interfaces, generic procedures

315

- **Arguments**: Intent specifications, optional arguments, keyword arguments

316

- **Arrays**: Explicit-shape, assumed-shape, allocatable, pointer arrays

317

- **Documentation**: Doxygen-style comments (partial support)

318

- **Modern Fortran**: Selected Fortran 2003/2008 features

319

320

## Parsing Limitations

321

322

- Complex generic interfaces may require manual adjustment

323

- Some Fortran 2008+ features have limited support

324

- Preprocessor directives are not fully processed

325

- Complex macro expansions may cause parsing issues