Code Monkey home page Code Monkey logo

Comments (4)

d-frey avatar d-frey commented on May 16, 2024

I'd try to keep things simple. What you really want is a custom error message that is embedded in the grammar. There is no need to tie that to the previous rule that did not match, hence instead of must_err< Rule, ERROR_MACRO("...") >, I'd just use sor< Rule, RAISE_MACRO("...") > where the latter macro throws an exception with a custom error message (like raise<>). Now the question is whether you want/need to route that through the Control class' raise()-method. If you do not need that, you could simply try and add

template< char... Cs >
struct raise_message
{
   using analyze_t = analysis::generic< analysis::rule_type::ANY >;

   template< typename Input >
   static void raise( const Input& in, const std::initializer_list< char >& l )
   {
      throw parse_error( std::string( &*l.begin(), l.size() ), in );
   }

   template< apply_mode A,
             rewind_mode,
             template< typename... > class Action,
             template< typename... > class Control,
             typename Input,
             typename... States >
   static bool match( Input& in, States&&... /*unused*/ )
   {
      raise( in, { Cs... } );
   }
};

#define TAO_PEGTL_RAISE( x ) \
   TAO_PEGTL_INTERNAL_STRING( raise_message, x )

(Note: The above is untested, I currently have some trouble running my development VM)

About your final point: parse_error has what() to access the actual message, and a public member for the positions. The latter is a std::vector<position>, as an error may result from a file included by another file or from expanding a macro or what have you. You can access e.positions.front().source or e.positions.front().line. The information is there, but not as convenient as you hope. OTOH, the nesting makes it kind of wrong to add accessors on a higher level. But I'll discuss it with Colin, let's see if we'll add some convenience accessors.

from pegtl.

engelant avatar engelant commented on May 16, 2024

The member std::vector<position> inside parse_error makes sense, honestly I overlooked it.

Regarding keeping it simple and the sor< Rule, RAISE_MACRO("...") > construct, yes, that would work. But since there are other rules defined for convenience this leaves me with the question: Am I using this wrong? Am I supposed to split my rules into (wierdly?) named sub rules and define their error_control::message?
If I'm not misusing this library then this would be a common situation, and I suggest It would make sense to add those "convenience" rule and/or macro to the library header.

from pegtl.

d-frey avatar d-frey commented on May 16, 2024

I don't think it is wrong, it is just another style. We don't want to force any style on you, instead we try to support as many (reasonable) styles as possible. Feel free to experiment with it, having your own custom-rules when using the PEGTL is quite normal.

Our reasons for separating the error message definitions from the actual grammar are: The grammar is shorter and easier to read, must and the convenience rules based on must provide convenient error hooks and help to reason about the grammar itself. Writing grammars is complicated enough already :) Additionally, you could have different error messages, e.g. localized to different languages, without changing the grammar.

We'll consider adding more convenience rules at another time, if you (or us) have more experience with the style you proposed.

from pegtl.

engelant avatar engelant commented on May 16, 2024

Ok, so be it (for now). I will continue to implement my parser mith my own style and see if it all comes together.

from pegtl.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.