or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.mdlanguages.mdparsing.md

parsing.mddocs/

0

# High-Level Parsing

1

2

The GherkinParser provides the main entry point for parsing Gherkin feature files into structured data formats. It supports multiple input sources and configurable output options through a builder pattern.

3

4

## Capabilities

5

6

### GherkinParser Creation

7

8

Create and configure a GherkinParser instance using the builder pattern.

9

10

```java { .api }

11

/**

12

* Create a new GherkinParser builder

13

* @return Builder instance for configuration

14

*/

15

public static GherkinParser.Builder builder();

16

17

/**

18

* Builder for configuring GherkinParser options

19

*/

20

public static final class Builder {

21

/**

22

* Configure whether to include source information in output

23

* @param includeSource true to include source data (default: true)

24

* @return this builder for chaining

25

*/

26

public Builder includeSource(boolean includeSource);

27

28

/**

29

* Configure whether to include GherkinDocument AST in output

30

* @param includeGherkinDocument true to include AST (default: true)

31

* @return this builder for chaining

32

*/

33

public Builder includeGherkinDocument(boolean includeGherkinDocument);

34

35

/**

36

* Configure whether to include compiled Pickles in output

37

* @param includePickles true to include pickles (default: true)

38

* @return this builder for chaining

39

*/

40

public Builder includePickles(boolean includePickles);

41

42

/**

43

* Set custom ID generator for element identification

44

* @param idGenerator custom ID generator implementation

45

* @return this builder for chaining

46

*/

47

public Builder idGenerator(IdGenerator idGenerator);

48

49

/**

50

* Build the configured GherkinParser instance

51

* @return configured parser ready for use

52

*/

53

public GherkinParser build();

54

}

55

```

56

57

### File Parsing

58

59

Parse Gherkin content from various sources including files, streams, and byte arrays.

60

61

```java { .api }

62

/**

63

* Parse a Gherkin feature file from filesystem path

64

* @param source Path to the .feature file

65

* @return Stream of Envelope messages containing parse results

66

* @throws IOException if file cannot be read

67

*/

68

public Stream<Envelope> parse(Path source) throws IOException;

69

70

/**

71

* Parse Gherkin content from InputStream

72

* @param uri URI identifier for the source (used in messages)

73

* @param source InputStream containing Gherkin content

74

* @return Stream of Envelope messages containing parse results

75

* @throws IOException if stream cannot be read

76

*/

77

public Stream<Envelope> parse(String uri, InputStream source) throws IOException;

78

79

/**

80

* Parse Gherkin content from byte array

81

* @param uri URI identifier for the source (used in messages)

82

* @param source byte array containing Gherkin content

83

* @return Stream of Envelope messages containing parse results

84

*/

85

public Stream<Envelope> parse(String uri, byte[] source);

86

87

/**

88

* Parse Gherkin content from existing Envelope message

89

* @param envelope Envelope containing Source message with Gherkin content

90

* @return Stream of Envelope messages containing parse results

91

*/

92

public Stream<Envelope> parse(Envelope envelope);

93

```

94

95

**Usage Examples:**

96

97

```java

98

// Parse from file path

99

GherkinParser parser = GherkinParser.builder().build();

100

Stream<Envelope> messages = parser.parse(Paths.get("features/login.feature"));

101

102

// Parse from string content

103

String gherkinContent = """

104

Feature: User Login

105

Scenario: Valid credentials

106

Given a user exists

107

When they enter valid credentials

108

Then they should be logged in

109

""";

110

Stream<Envelope> messages = parser.parse("test.feature",

111

gherkinContent.getBytes(StandardCharsets.UTF_8));

112

113

// Configure parser options

114

GherkinParser customParser = GherkinParser.builder()

115

.includeSource(false) // Skip source in output

116

.includePickles(true) // Include executable pickles

117

.idGenerator(() -> "custom-id") // Use custom ID generation

118

.build();

119

```

120

121

### Message Processing

122

123

Process the stream of Envelope messages returned by parsing operations.

124

125

```java { .api }

126

// Core message types returned in Envelope stream

127

interface Envelope {

128

Optional<Source> getSource(); // Original source content

129

Optional<GherkinDocument> getGherkinDocument(); // Parsed AST

130

Optional<Pickle> getPickle(); // Executable scenario

131

Optional<ParseError> getParseError(); // Parse error details

132

}

133

134

interface GherkinDocument {

135

String getUri();

136

Optional<Feature> getFeature();

137

List<Comment> getComments();

138

}

139

140

interface Pickle {

141

String getId();

142

String getUri();

143

String getName();

144

String getLanguage();

145

List<PickleStep> getSteps();

146

List<PickleTag> getTags();

147

List<String> getAstNodeIds();

148

}

149

```

150

151

**Message Processing Examples:**

152

153

```java

154

// Process all message types

155

parser.parse(featureFile).forEach(envelope -> {

156

// Handle source information

157

envelope.getSource().ifPresent(source ->

158

System.out.println("Parsing: " + source.getUri()));

159

160

// Handle parsed AST

161

envelope.getGherkinDocument().ifPresent(doc -> {

162

doc.getFeature().ifPresent(feature ->

163

System.out.println("Feature: " + feature.getName()));

164

});

165

166

// Handle executable scenarios

167

envelope.getPickle().ifPresent(pickle -> {

168

System.out.println("Scenario: " + pickle.getName());

169

pickle.getSteps().forEach(step ->

170

System.out.println(" " + step.getText()));

171

});

172

173

// Handle parse errors

174

envelope.getParseError().ifPresent(error ->

175

System.err.println("Parse error: " + error.getMessage()));

176

});

177

178

// Collect only pickles for test execution

179

List<Pickle> scenarios = parser.parse(featureFile)

180

.map(Envelope::getPickle)

181

.filter(Optional::isPresent)

182

.map(Optional::get)

183

.collect(Collectors.toList());

184

185

// Extract feature metadata

186

Optional<Feature> feature = parser.parse(featureFile)

187

.map(Envelope::getGherkinDocument)

188

.filter(Optional::isPresent)

189

.map(Optional::get)

190

.map(GherkinDocument::getFeature)

191

.filter(Optional::isPresent)

192

.map(Optional::get)

193

.findFirst();

194

```

195

196

### Error Handling

197

198

Handle parsing errors and exceptions during Gherkin processing.

199

200

```java { .api }

201

// Exception types thrown by the parser (package-private but visible to users)

202

ParserException.NoSuchLanguageException // Unsupported language code

203

ParserException.UnexpectedTokenException // Syntax errors in Gherkin

204

ParserException.UnexpectedEOFException // Premature end of file

205

ParserException.CompositeParserException // Multiple parsing errors

206

ParserException.AstBuilderException // AST construction failures

207

GherkinException // General processing errors

208

```

209

210

**Error Handling Examples:**

211

212

```java

213

import io.cucumber.gherkin.ParserException;

214

import io.cucumber.gherkin.GherkinException;

215

216

try {

217

Stream<Envelope> messages = parser.parse(featureFile);

218

219

// Check for parse errors in the stream

220

List<ParseError> errors = messages

221

.map(Envelope::getParseError)

222

.filter(Optional::isPresent)

223

.map(Optional::get)

224

.collect(Collectors.toList());

225

226

if (!errors.isEmpty()) {

227

errors.forEach(error ->

228

System.err.println("Parse error at " +

229

error.getSource().getLocation().getLine() + ": " +

230

error.getMessage()));

231

}

232

233

} catch (ParserException.NoSuchLanguageException e) {

234

System.err.println("Unsupported language in feature file: " + e.getMessage());

235

236

} catch (ParserException.UnexpectedTokenException e) {

237

System.err.println("Syntax error in Gherkin at line " +

238

e.location.getLine() + ": " + e.getMessage());

239

System.err.println("Expected: " + String.join(", ", e.expectedTokenTypes));

240

241

} catch (ParserException.CompositeParserException e) {

242

System.err.println("Multiple parsing errors found:");

243

e.errors.forEach(error ->

244

System.err.println(" - " + error.getMessage()));

245

246

} catch (GherkinException e) {

247

System.err.println("General parsing error: " + e.getMessage());

248

if (e.getCause() != null) {

249

System.err.println("Caused by: " + e.getCause().getMessage());

250

}

251

252

} catch (IOException e) {

253

System.err.println("Failed to read feature file: " + e.getMessage());

254

}

255

```

256

257

**Language Error Example:**

258

259

```java

260

// This will throw NoSuchLanguageException

261

String invalidLanguageFeature = """

262

# language: xyz-invalid

263

Feature: Test

264

Scenario: Example

265

Given something

266

""";

267

268

try {

269

parser.parse("test.feature", invalidLanguageFeature.getBytes());

270

} catch (ParserException.NoSuchLanguageException e) {

271

System.err.println("Language 'xyz-invalid' is not supported");

272

273

// Show available languages

274

GherkinDialectProvider provider = new GherkinDialectProvider();

275

System.out.println("Available languages: " + provider.getLanguages());

276

}

277

```