2
\$\begingroup\$

I'm working on a project (in C++98) that uses a grammar validation service to validate mapping expressions for a small DSL. To simplify the project code, I've written a small interface for using the validator service, which I'm hoping to get some feedback on.

exprval_expressionvalidator.h:

#ifndef EXPRVAL_EXPRESSIONVALIDATOR_H
#define EXPRVAL_EXPRESSIONVALIDATOR_H

#include "gval_stub_validator.h"

#include <map>
#include <string>

namespace exprval {

// Abstract base implementation of validator for expressions of arbitrary type.
// Derived class must implement a public interface method to call the private
// templated method `validate()`.
template <typename EXPR_T>
class ExpressionValidator {

public:

    // Return codes for validation success
    enum ReturnCode { INVALID, VALID };

    // Destructor
    virtual ~ExpressionValidator();

private:

    // Return `VALID` if `expr` is valid, else return `INVALID`.
    virtual ReturnCode validate(const EXPR_T& expr) = 0;

};

template <typename EXPR_T>
inline ExpressionValidator<EXPR_T>::~ExpressionValidator() {}

class MappingExpressionValidator : public ExpressionValidator<std::string> {

public:

    // Return `VALID` if `mapping_expr` with inline tokens `inline_tokens` is
    // valid, else return `INVALID`.
    ReturnCode validate(const std::string& mapping_expr,
                        const std::map<unsigned int, std::string> inline_tokens);

private:

    // Stub for grammar validation service
    gval_stub::GrammarValSvcStub d_grammar_val_stub;

    // Return `VALID` if `expr` is valid, else return `INVALID`.
    virtual ReturnCode validate(const std::string& expr);

};

}  // Close namespace `exprval`

#endif

exprval_expressionvalidator.cpp:

#include "exprval_expressionvalidator.h"

namespace exprval {

typedef MappingExpressionValidator::ReturnCode RC;

RC MappingExpressionValidator::validate(const std::string& mapping_expr,
                                        const std::map<unsigned int,
                                              std::string>& inline_tokens) {
    typedef std::map<unsigned int, std::string>::const_iterator InlineTokenIt;

    for (InlineTokenIt it = inline_tokens.begin(); it != inline_tokens.end(); ++it) {
        const unsigned int token_id = it->first;
        const std::string& token_text = it->second;

        // Register token with grammar validation service
        d_grammar_val_stub.register_token(token_id, token_text);
    }

    return validate(mapping_expr);
}

RC MappingExpressionValidator::validate(const std::string& expr) {
    // Execute call to validation service
    return d_grammar_val_stub.is_valid_mapping_expr(expr);
}

}  // Close namespace `exprval`

(I've removed a few comments and parts of the code that is specific to our application.)

As I'm fairly new to C++, I am looking for overall feedback as far as language usage, with specific focus on the following items:

  • General C++ style and API design
  • Naming conventions
  • Documentation
  • Conformance to C++ template and inheritance usage paradigms
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.