-
I am having trouble creating a control class. Does anyone have any examples to supplant the JSON parser example. I believe I have followed the example, but for some reason am getting linking errors on some of my rules. Additionally I am wondering if control classes are the best way to determine what rule a parse fails on? If there is a better alternative could someone suggest it to me. Also what is the significance of these lines in the exaample JSON build one file. Lines(168-171)
|
Beta Was this translation helpful? Give feedback.
Replies: 9 comments
-
First, what exactly are the linker errors? Further, for normal use cases it is not necessary to use the control class to determine which rule failed during a parsing run; it might make sense to use a custom control class to throw custom exceptions that contain other information ( The quoted lines from the |
Beta Was this translation helpful? Give feedback.
-
The linking error declares that I have an undefined reference to a rule that is already included in the file. Can you clarify your statement "it is not necessary to use the control class to determine which rule failed during a parsing run". Are you stating that there is a better way to return what rule a parse fails on? |
Beta Was this translation helpful? Give feedback.
-
It would be helpful if we could see the code in question and the exact text of the linker error. |
Beta Was this translation helpful? Give feedback.
-
I cant post that code, but I have attempted to complete a more simple example using the hello world code included with PEGTL. // Copyright (c) 2014-2017 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/
#include <tao/pegtl.hpp>
#include <string>
#include <iostream>
#include <tao/pegtl.hpp>
#include "test.h"
#include "control.h"
using namespace tao::pegtl;
namespace hello
{
// Parsing rule that matches a literal "Hello, ".
struct prefix
: string< 'H', 'e', 'l', 'l', 'o', ',', ' ' >
{};
// Parsing rule that matches a non-empty sequence of
// alphabetic ascii-characters with greedy-matching.
struct name
: must<plus< alpha >>
{};
// Parsing rule that matches a sequence of the 'prefix'
// rule, the 'name' rule, a literal "!", and 'eof'
// (end-of-file/input), and that throws an exception
// on failure.
struct grammar
: must< year, eof >
{};
// Class template for user-defined actions that does
// nothing by default.
template< typename Rule >
struct action
: nothing< Rule >
{};
// Specialisation of the user-defined action to do
// something when the 'name' rule succeeds; is called
// with the portion of the input that matched the rule.
template<>
struct action< name >
{
template< typename Input >
static void apply( const Input& in, std::string& v )
{
v = in.string();
}
};
template< typename Rule > struct control : examples::errors< Rule > {};
} // namespace hello
int main( int argc, char* argv[] )
{
if( argc > 1 ) {
// Start a parsing run of argv[1] with the string
// variable 'name' as additional argument to the
// action; then print what the action put there.
std::string name;
file_input<> in( argv[1] );
parse< hello::grammar, hello::action, control >( in, name );
/*
try {
parse< hello::grammar, hello::action, control >( in, name );
} catch(tao::TAOCPP_PEGTL_NAMESPACE::parse_error ex){
std::cout << ex.what() << std::endl;
}
*/
std::cout << "Good bye, " << name << "!" << std::endl;
}
} #pragma once
#include <tao/pegtl.hpp>
//this is for readability. it's not ideal since every file that includes this file will
//have this aliased namespace as well, which is less than desirable, but not so undesirable
//that it outweighs the impacts to readability in this file.
namespace tp = tao::pegtl;
// - Abbreviaton for a month (I.E Apr)
struct year:
tp::rep<4, tp::digit>{}; // Copyright (c) 2014-2017 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/
#pragma once
#include <tao/pegtl.hpp>
#include "test.h"
namespace examples
{
// This file shows how to throw exceptions with
// custom error messages for parse errors. A custom
// control class is created that delegates everything
// to the PEGTL default control class tao::TAOCPP_PEGTL_NAMESPACE::normal<>
// except for the throwing of exceptions:
template< typename Rule >
struct errors
: public tao::TAOCPP_PEGTL_NAMESPACE::normal< Rule >
{
static const std::string error_message;
template< typename Input, typename... States >
static void raise( const Input& in, States&&... )
{
throw tao::TAOCPP_PEGTL_NAMESPACE::parse_error( error_message, in );
}
};
// The following specialisations of the static string
// member are then used in the exception messages:
// clang-format off
template<> const std::string errors<year>::error_message = "that is not a year zzzzzzz";
// clang-format on
// The raise()-function-template is instantiated exactly
// for the specialisations of errors< Rule > for which a
// parse error can be generated, therefore the string
// error_message needs to be supplied only for these rules
// (and the compiler will complain if one is missing).
} // examples I am getting this error with this code I think I am mostly confused with the parse function due to the templating as well as how a control class works. Clarification on that would be helpful. |
Beta Was this translation helpful? Give feedback.
-
a) Please learn how to format you messages properly. I edited yours, see how the source looks now.
|
Beta Was this translation helpful? Give feedback.
-
@d-frey Thanks for the help. On my previous question regarding returning what rule a parse fails on. Do you think creating custom errors using a control class is the most effective and logical way of accomplishing this using PEGTL? Additionally I am testing out how the error messages work in regards to nested grammar rules.
|
Beta Was this translation helpful? Give feedback.
-
The control class is one way, there are other options. The PEGTL usually tries to get out of the way and enable you to choose what is best for your use-case. Note that you don't need your own control class if you don't specialize it - you can use the For your example: Do you mean Note that the |
Beta Was this translation helpful? Give feedback.
-
Do you have any further questions, or can we close this issue? Happy hacking! |
Beta Was this translation helpful? Give feedback.
-
I don't have any more questions. Thanks for the help! |
Beta Was this translation helpful? Give feedback.
a) Please learn how to format you messages properly. I edited yours, see how the source looks now.
b) If you have multiple files, tell us the names and in the error message, tell use which file and line it refers to.
c) You did not qualify
control
. Inmain
you are outside of namespacehello
, so you need to qualifyhello::control
when callingparse
: