Skip to content

Parsing error message

Bastiaan Veelo edited this page Apr 14, 2020 · 2 revisions

Parsing error message

To obtain the parsing error message instead of the full parse tree in Pegged, just call the failMsg member function of ParseTree:

import pegged.grammar;
import std.stdio;

mixin(grammar(`
Gram:
    A < (B C :eol? )* :eoi
    B <- 'b'*
    C <- 'c'
`));

auto g =
   "bbbc
   bc
   c
   h
   bbc
   ";
auto parseTree = Gram(g);
writeln(parseTree.failMsg); // Shows: Failure at line 3, col 3, after "c\n   c\n   " expected "end of input", but got "h\n   bbc\n "

Custom error message

The failMsg member function of ParseTree can accept two optional parameters to customize the generated message. The first parameter is a delegate function that allows you to customize the message for when the parse fails. The second parameter is the string returned when the parse succeeds:

import pegged.grammar;
import std.stdio;
import std.conv : to;

mixin(grammar(`
Gram:
    A < (B C :eol? )* :eoi
    B <- 'b'*
    C <- 'c'
`));


auto g =
   "bbbc
   bc
   c
   h
   bbc
   ";
auto parseTree = Gram(g);
string msg = parseTree.failMsg((Position pos, string left, string right, const ParseTree p) => 
      "Failure at line " ~ to!string(pos.line) ~ ", col " ~ to!string(pos.col) ~ "."
      , "Ok!");
writeln(msg); // Now shows : Failure at line 3, col 3.

For reference, this is the default error formatting function:

/**
  * Default fail message formating function
  */
auto defaultFormatFailMsg = delegate (Position pos, string left, string right, const ParseTree pt) 
{
    return "Failure at line " ~ to!string(pos.line) ~ ", col " ~ to!string(pos.col) ~ ", "
        ~ (left.length > 0 ? "after " ~ left.stringified ~ " " : "")
        ~ "expected " ~ (pt.matches.length > 0 ? pt.matches[$ - 1].stringified : "NO MATCH")
        ~ `, but got ` ~ right.stringified;
};