Skip to content

Commit

Permalink
fix(parser): handle lexer errors
Browse files Browse the repository at this point in the history
Fix #11
See #10
  • Loading branch information
larsgw committed Apr 25, 2022
1 parent 8cc9398 commit ec672d4
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 2 deletions.
48 changes: 46 additions & 2 deletions src/parser/kdl.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* @memberof module:kdljs.parser
*/

const { Lexer } = require('chevrotain')
const { Lexer, MismatchedTokenException, createTokenInstance } = require('chevrotain')
const { BaseParser } = require('./base.js')
const Tokens = require('./tokens.js')

Expand Down Expand Up @@ -308,6 +308,41 @@ class KdlParser extends BaseParser {
}
}

/**
* @access private
* @memberof module:kdljs.parser.kdl
* @param {Object} error
* @param {string} error.message
* @param {number} error.offset
* @param {number} error.length
* @param {number} error.line
* @param {number} error.column
* @param {Object[]} tokens
* @param {string} text
* @return {Object}
*/
function transformLexerError (error, tokens, text) {
const endOffset = error.offset + error.length
const image = text.slice(error.offset, endOffset)
const lines = image.split(/\r?\n/g)
const prevToken = tokens.find(token => token.endOffset + 1 === error.offset)

return new MismatchedTokenException(
error.message,
createTokenInstance(
Tokens.Unknown,
image,
error.offset,
endOffset,
error.line,
error.line + lines.length - 1,
error.column,
error.column + lines[lines.length - 1].length
),
prevToken
)
}

const lexer = new Lexer(tokens)
/**
* @constant {module:kdljs.parser.kdl.KdlParser}
Expand All @@ -330,7 +365,16 @@ const parser = new KdlParser()
* @return {module:kdljs.parser.kdl.ParseResult} Output
*/
module.exports.parse = function parse (text) {
parser.input = lexer.tokenize(text).tokens
const { tokens, errors } = lexer.tokenize(text)

if (errors.length) {
return {
output: undefined,
errors: errors.map(error => transformLexerError(error, tokens, text))
}
}

parser.input = tokens
const output = parser.document()

return {
Expand Down
2 changes: 2 additions & 0 deletions src/parser/tokens.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ const RightBrace = createToken({ name: 'RightBrace', pattern: /\}/ })
const LeftParenthesis = createToken({ name: 'LeftParenthesis', pattern: /\(/ })
const RightParenthesis = createToken({ name: 'RightParenthesis', pattern: /\)/ })
const EscLine = createToken({ name: 'EscLine', pattern: /\\/ })
const Unknown = createToken({ name: 'Unknown', pattern: /[^]/ })

// String
const OpenQuote = createToken({ name: 'OpenQuote', pattern: /"/, push_mode: 'string' })
Expand Down Expand Up @@ -148,5 +149,6 @@ module.exports = {
Accessor,
Comma,

Unknown,
EOF
}

0 comments on commit ec672d4

Please sign in to comment.