or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

grammar-management.mdindex.mdparsing-and-matching.mdparsing-expressions.mdsemantic-actions.mdutilities-and-extras.md

parsing-and-matching.mddocs/

0

# Parsing and Matching

1

2

Grammar parsing capabilities with support for incremental parsing, detailed error reporting, and trace visualization.

3

4

## Imports

5

6

```javascript

7

import { grammar } from "ohm-js";

8

```

9

10

For TypeScript:

11

12

```typescript

13

import { grammar, Grammar, MatchResult, Matcher, Interval, RuleInfo, LineAndColumnInfo } from "ohm-js";

14

```

15

16

## Capabilities

17

18

### Grammar Interface

19

20

Core interface for compiled grammar objects with parsing and semantic capabilities.

21

22

```typescript { .api }

23

/**

24

* An Ohm Grammar compiled from source code

25

*/

26

interface Grammar {

27

/** Name of the grammar */

28

name: string;

29

/** Parent grammar if this extends another grammar */

30

superGrammar: Grammar;

31

/** Dictionary of rule definitions in this grammar */

32

rules: {[ruleName: string]: RuleInfo};

33

34

/** Return true if the grammar is a built-in grammar, otherwise false */

35

isBuiltIn(): boolean;

36

37

/**

38

* Try to match input with this grammar, returning a MatchResult

39

* @param input - String to parse

40

* @param startRule - Optional rule name to start matching from

41

* @returns MatchResult indicating success or failure

42

*/

43

match(input: string, startRule?: string): MatchResult;

44

45

/**

46

* Create a new Matcher object which supports incrementally matching

47

* this grammar against a changing input string

48

* @returns Matcher instance for incremental parsing

49

*/

50

matcher(): Matcher;

51

52

/**

53

* Like match() except returns a trace object whose toString() returns

54

* a summary of each parsing step useful for debugging

55

* @param input - String to parse

56

* @param startRule - Optional rule name to start matching from

57

* @returns Trace object with debugging information

58

*/

59

trace(input: string, startRule?: string): Object;

60

61

/**

62

* Create a new Semantics object for this Grammar

63

* @returns Empty semantics instance

64

*/

65

createSemantics(): Semantics;

66

67

/**

68

* Create a new Semantics object for this Grammar that inherits all

69

* of the operations and attributes in superSemantics

70

* @param superSemantics - Parent semantics to inherit from

71

* @returns Extended semantics instance

72

*/

73

extendSemantics(superSemantics: Semantics): Semantics;

74

}

75

```

76

77

**Usage Examples:**

78

79

```javascript

80

import { grammar } from "ohm-js";

81

82

const g = grammar(`

83

Calculator {

84

expr = number ("+" number)*

85

number = digit+

86

}

87

`);

88

89

// Basic matching

90

const match = g.match("2+3+4");

91

if (match.succeeded()) {

92

console.log("Parsing succeeded!");

93

}

94

95

// Match with specific start rule

96

const numberMatch = g.match("42", "number");

97

98

// Check if grammar is built-in

99

console.log("Is built-in:", g.isBuiltIn()); // false

100

```

101

102

### Match Results

103

104

Result object returned by grammar match operations containing success/failure status and error information.

105

106

```typescript { .api }

107

/**

108

* Result of Grammar#match operation

109

*/

110

interface MatchResult {

111

/**

112

* True iff match succeeded

113

*/

114

succeeded(): boolean;

115

116

/**

117

* True iff match did not succeed

118

*/

119

failed(): boolean;

120

121

/**

122

* If match failed contains an error message indicating where and

123

* why the match failed. This message is suitable for end users of a

124

* language (i.e., people who do not have access to the grammar source).

125

*/

126

message?: string;

127

128

/**

129

* If match failed contains an abbreviated version of this.message that

130

* does not include an excerpt from the invalid input.

131

*/

132

shortMessage?: string;

133

134

/**

135

* If this MatchResult is a failure, returns an Interval indicating

136

* the position of the rightmost failure.

137

*/

138

getInterval(): Interval;

139

}

140

```

141

142

**Usage Examples:**

143

144

```javascript

145

const match = grammar.match("invalid input");

146

147

if (match.failed()) {

148

console.error("Parse error:", match.message);

149

console.error("Short error:", match.shortMessage);

150

151

const errorPos = match.getInterval();

152

console.error("Error at position:", errorPos.startIdx);

153

}

154

```

155

156

### Incremental Parsing

157

158

Matcher objects support incremental parsing for use in editors and IDEs where the input changes frequently.

159

160

```typescript { .api }

161

/**

162

* Matcher objects are used to incrementally match a changing input

163

* against a Grammar, e.g. in an editor or IDE.

164

*/

165

interface Matcher {

166

/** The grammar this matcher uses */

167

grammar: Grammar;

168

169

/**

170

* Return the current input string

171

*/

172

getInput(): string;

173

174

/**

175

* Set the input string to `str`

176

* @param str - New input string

177

*/

178

setInput(str: string): void;

179

180

/**

181

* Edit the current input string, replacing the characters between

182

* `startIdx` and `endIdx` with `str`

183

* @param startIdx - Start position of replacement

184

* @param endIdx - End position of replacement

185

* @param str - Replacement string

186

* @returns This matcher for chaining

187

*/

188

replaceInputRange(startIdx: number, endIdx: number, str: string): Matcher;

189

190

/**

191

* Like Grammar#match, but operates incrementally

192

* @param optStartRule - Optional start rule name

193

* @returns MatchResult from current input

194

*/

195

match(optStartRule?: string): MatchResult;

196

197

/**

198

* Like Grammar#trace, but operates incrementally

199

* @param optStartRule - Optional start rule name

200

* @returns Trace object for debugging

201

*/

202

trace(optStartRule?: string): Object;

203

}

204

```

205

206

**Usage Examples:**

207

208

```javascript

209

const matcher = grammar.matcher();

210

211

// Set initial input

212

matcher.setInput("2 + 3");

213

let result = matcher.match();

214

215

// Edit the input incrementally

216

matcher.replaceInputRange(0, 1, "5"); // Changes "2 + 3" to "5 + 3"

217

result = matcher.match();

218

219

// Get current input

220

console.log("Current input:", matcher.getInput());

221

```

222

223

### Rule Information

224

225

Metadata about individual grammar rules.

226

227

```typescript { .api }

228

interface RuleInfo {

229

/** Parsing expression body of the rule */

230

body: PExpr;

231

/** Formal parameter names for parameterized rules */

232

formals: string[];

233

/** Description string from grammar source */

234

description: string;

235

/** Source interval where rule is defined */

236

source: Interval;

237

}

238

```

239

240

### Interval Information

241

242

Represents a subset of a string with position and content information.

243

244

```typescript { .api }

245

/**

246

* An Interval represents a subset of a string

247

*/

248

interface Interval {

249

/** The string containing the interval */

250

sourceString: string;

251

/** The start index of the interval in `sourceString` */

252

startIdx: number;

253

/** The end index of the interval in `sourceString` */

254

endIdx: number;

255

/** Contents of interval */

256

contents: string;

257

258

/** Returns a new Interval at the start of this one */

259

collapsedLeft(): Interval;

260

/** Returns a new Interval at the end of this one */

261

collapsedRight(): Interval;

262

/** Returns a new Interval that covers this and all argument Intervals */

263

coverageWith(...intervals: Interval[]): Interval;

264

/** Returns a nicely-formatted string describing the start of the Interval */

265

getLineAndColumnMessage(): string;

266

/** Returns structure with line and column number information */

267

getLineAndColumn(): LineAndColumnInfo;

268

/** Returns array of intervals representing the difference operation */

269

minus(that: Interval): Interval[];

270

/** Returns a new Interval relative to another interval */

271

relativeTo(that: Interval): Interval;

272

/** Returns a new Interval with whitespace trimmed from both ends */

273

trimmed(): Interval;

274

/** Returns a new Interval with given length at startIdx + offset */

275

subInterval(offset: number, len: number): Interval;

276

}

277

278

interface LineAndColumnInfo {

279

offset: number;

280

lineNum: number;

281

colNum: number;

282

line: string;

283

prevLine: string;

284

nextLine: string;

285

toString(...ranges: number[][]): string;

286

}

287

```

288

289

## Error Handling and Debugging

290

291

### Trace Support

292

293

Ohm provides detailed tracing capabilities for debugging grammar matching:

294

295

```javascript

296

// Get detailed trace information

297

const trace = grammar.trace("invalid input");

298

console.log(trace.toString()); // Prints step-by-step parsing trace

299

```

300

301

### Error Messages

302

303

Match failures provide human-readable error messages:

304

305

```javascript

306

const match = grammar.match("2 +"); // Incomplete expression

307

308

if (match.failed()) {

309

// Full error message with context

310

console.error(match.message);

311

312

// Shorter error without input excerpt

313

console.error(match.shortMessage);

314

315

// Get error position for highlighting

316

const errorInterval = match.getInterval();

317

console.error(`Error at line ${errorInterval.getLineAndColumn().lineNum}`);

318

}

319

```