-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
custom error messages? #3
Comments
I think this is a good idea (i have considered it previously) but has to be designed carefully. Two possible designs come to mind immediately:
The first option is less invasive and probably easier to implement, but I suspect the second one to be more useful. For the second option, an important design decision is whether encountering a (defrule python-class-statement
(and "class" (+ whitespace)
(or identifier (fail "Class name must follow class keyword")) …)
…) What do you think?
I relayed this suggestion to Nikodemus. |
thanks for the reply! okay, I've thought some more and I think I misnamed the issue; I was actually thinking of manually labelling rule for the benefits I described. but your idea for a new expression kind is also interesting, and certainly much more flexible. plus it corresponds better to the title of my issue (sorry about being confusing!) I was looking into megaparsec and it has constructs equivalent to both things ( in the example you gave, you would be using |
I see.
In Esrap, there are (at least) the following dimensions which could be affected by these new constructs:
Megaparsec's
I explored this some more and ended up with the following example: ;;;; Esrap example: custom error messages
(cl:require :esrap)
(cl:defpackage #:esrap-example.custom-errors
(:use #:cl #:esrap))
(cl:in-package #:esrap-example.custom-errors)
(defrule identifier
(+ (character-ranges (#\a #\z) #\_)))
(defrule identifier!
(or identifier
(esrap::fail "Invalid characters in identifier"
"Allowed characters are [a-z] and _")))
(defrule python-class
(and "class" parser.common-rules:whitespace+
(or identifier (esrap::fail "An identifier, the class name, must follow the `class' keyword."
"An identifier"))
(? (and parser.common-rules:whitespace* #\( identifier! #\)))))
(parse 'python-class "class 1")
#|
At
class 1
^ (Line 1, Column 6, Position 6)
In context PYTHON-CLASS:
While parsing PYTHON-CLASS. Problem:
An identifier, the class name, must follow the `class' keyword.
Expected:
"An identifier"
or a character in [a-z] or [_]
|#
(parse 'python-class "class foo (1)")
#|
At
class foo (1)
^ (Line 1, Column 11, Position 11)
In context IDENTIFIER!:
While parsing IDENTIFIER!. Problem:
Invalid characters in identifier
Expected:
"Allowed characters are [a-z] and _"
or a character in [a-z] or [_]
|# Is this close to what you want to achieve in terms of 2., 3. and 4. or do you want to replace the error report more completely (say getting rid of the "In context …" and "While parsing …" parts)? This addresses your valid concern of extra work at each use of the With a (defrule identifier!
identifier
(:report :complaint "Invalid characters in identifier"
:expected "Allowed characters are [a-z] and _")) or (defrule identifier!
identifier
(:report "Invalid characters in identifier"
"Allowed characters are [a-z] and _")) instead. Do you think having two ways of specifying custom error messages is worth it? This only covers 3. and 4. in the list above since source locations of errors are not directly affected. I did not consider fatal failures and that issue might in fact be completely orthogonal. |
I'd be happy with customizing only this part of the error report! more information doesn't hurt at all, even if an end-user can't understand it well.
so yeah, your example looks great to me!
I'm not sure I'm following exactly, but taking your example I thought of something like this (defrule identifier
(+ (character-ranges (#\a #\z) #\_))
(:report "Invalid characters in identifier"
"Allowed characters are [a-z] and _"))
(defrule python-class
(and "class" parser.common-rules:whitespace+
(or identifier (esrap::fail "An identifier, the class name, must follow the `class' keyword."
"An identifier"))
(? (and parser.common-rules:whitespace* #\( identifier! #\))))) with the behaviour being that in the case of the that would give the user a way of providing a custom error message (the
even though it seems to me we could define one in terms of the other, both seem useful to me in terms of syntax; with only it's okay if you feel like you need more time to think of a cleaner design :) |
it would be nice to have an option in the
defrule
macro to add custom error messages.in the case of complex rules there might be a domain-specific way of describing them that is simpler than the automatically generated one, and in the rules where we have internal logic we don't want to disclose (e.g., I have a rule that I publish as being stricter as it really is, like requiring one space where the actual rule will accept any number of spaces or tabs).
do you think this is worthwhile?
ps: I notice lots of places (like the awesome-cl list used to until today) still link to https://github.com/nikodemus/esrap, even though this is the current quicklisp distribution; if you have nikodemus blessing, it would be nice to have him write something on the readme of his fork so that people are aware!
The text was updated successfully, but these errors were encountered: