Debuging a "SyntaxError: No parse at {error}" number

Hello,

I am currently creating a grammar to integrate some coloration for DAX language into codemirror.

I started my grammar step by step, trying to understand what I am doing (sorry for the french comment in the code). I managed to have a compiling grammar but… when I run my unit test with

import {MsDaxLanguage} from "../dist/index.js"
import {fileTests} from "@lezer/generator/dist/test"

import * as fs from "fs"
import * as path from "path"
import { fileURLToPath } from 'url';
let caseDir = path.dirname(fileURLToPath(import.meta.url))

for (let file of fs.readdirSync(caseDir)) {
  if (!/\.txt$/.test(file)) continue

  let name = /^[^\.]*/.exec(file)[0]
  describe(name, () => {
    for (let {name, run} of fileTests(fs.readFileSync(path.join(caseDir, file), "utf8"), file))
      it(name, () => run(MsDaxLanguage.parser))
  })
}

each tests are failing with a variant of

SyntaxError: No parse at {number}

For now I have 3 variants:
17, 43 and 13

Here is my grammar.

@tokens {
  // Tokens pour les littéraux
  space { $[ \t\n\r]+ }
  number {
    ($[0-9]+ "." $[0-9]+)
    | ($[0-9]+)
  }
  string {
    '"' (!["\\] | "\\" _)* '"'
  }

  // Tokens pour les identifiants
  identifier {
    $[a-zA-Z_] $[a-zA-Z0-9_]*
  }
  infoFunctionName {
  "INFO." space $[A-Z_]+
  }

  LineComment {
    "--" ![\n]*
  }
  Minus { "-" }

  // Tokens pour les opérateurs
  operator {
    "+" | "*" | "/" | "&&" | "||" | "=" | "<>" | "<" | ">" | "<=" | ">="
  }
  @precedence {LineComment, Minus}
  @precedence {infoFunctionName, identifier}
}

@top query { statement* }
@skip { space | LineComment }
@detectDelim
kw<word> { @specialize[@name={word}]<identifier, word> }

statement {
  defineStatement
  | evaluateStatement
  | fullExpression
}

fullExpression {
  expression
  | binaryOperation
}

expression {
  (functionCall
  | literal
  | tableExpression
  | columnReference
  | parenthesizedExpression) orderByClause?
}


functionCall {
  (identifier|infoFunctionName) "(" arguments? ")"
}

arguments {
  (fullExpression | identifier) ("," (fullExpression | identifier))*
}

binaryOperation {
  expression (binaryOperator | Minus) expression
}

binaryOperator {
  operator
}

literal[@dynamicPrecedence=1] {
  number
  | string
  | kw<"TRUE">
  | kw<"FALSE">
}

tableExpression {
  "{" row ("," row)* "}"
}

row {
  "{" expression ("," expression)* "}"
}

columnReference {
  (identifier "[" identifier "]") | (quotedIdentifier "[" identifier "]")
}

quotedIdentifier {
  "'" identifier "'"
}

parenthesizedExpression {
  "(" fullExpression ")"
}

defineStatement {
  kw<"DEFINE"> kw<"TABLE">?  variableDefinition ("," variableDefinition)*
}

variableDefinition {
  kw<"VAR"> identifier "=" expression
}

returnStatement {
  kw<"RETURN"> expression
}

evaluateStatement {
  kw<"EVALUATE"> fullExpression returnStatement?
}

orderByClause {
  kw<"ORDER"> kw<"BY"> columnReference (kw<"ASC"> | kw<"DESC">)?
}

How can I know what the “17” refers to?
How can I fix this issue,and in the future being more autonomous on this debug?

Regards

That’s an offset into the input string. So the parser fails to find a way to parse it after the 17th character.

If you’re running the test on the console, setting LOG=parse as an environment variable can help figure out what the parser is trying to do.

1 Like

Thank you for your help!
Indeed I managed to see where the errors were!
Now starts the difficult debugging. Thank you for that.