Skip to content

Commit

Permalink
implement Transition class
Browse files Browse the repository at this point in the history
  • Loading branch information
ghatchue committed Aug 4, 2013
1 parent 227eaf2 commit b81507e
Show file tree
Hide file tree
Showing 3 changed files with 229 additions and 1 deletion.
72 changes: 72 additions & 0 deletions runtime/Cpp/include/antlr/atn/Transition.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,86 @@
#define TRANSITION_H

#include <antlr/Definitions.h>
#include <antlr/misc/HashMap.h>
#include <antlr/misc/IntervalSet.h>
#include <memory>
#include <string>
#include <typeinfo>
#include <vector>


namespace antlr4 { namespace atn { class ATNState; } }

using namespace antlr4::misc;

namespace antlr4 {
namespace atn {

/** An ATN transition between any two ATN states. Subclasses define
* atom, set, epsilon, action, predicate, rule transitions.
* <p/>
* This is a one way link. It emanates from a state (usually via a list of
* transitions) and has a target state.
* <p/>
* Since we never have to change the ATN transitions once we construct it,
* we can fix these transitions as specific classes. The DFA transitions
* on the other hand need to update the labels as it adds transitions to
* the states. We'll use the term Edge for the DFA to distinguish them from
* ATN transitions.
*/
class ANTLR_API Transition
{
public:

~Transition();

static antlr_int32_t getSerializationType(const std::type_info& type);

virtual antlr_int32_t getSerializationType() const = 0;

/** Are we epsilon, action, sempred? */
virtual bool isEpsilon() const;

ANTLR_NULLABLE
virtual std::auto_ptr<IntervalSet> label() const;

virtual bool matches(antlr_int32_t symbol, antlr_int32_t minVocabSymbol, antlr_int32_t maxVocabSymbol) const = 0;

protected:

Transition(ANTLR_NOTNULL const ATNState* target);

private:

static std::vector<std::string> getSerializationNames();

#if defined(HAVE_CX11)
static HashMap<std::size_t, antlr_int32_t> getSerializationTypes();
static const HashMap<std::size_t, antlr_int32_t> serializationTypes;
#else
typedef std::pair<const std::type_info*, antlr_int32_t> TypeInfo;
static std::vector<TypeInfo> getSerializationTypes();
static const std::vector<TypeInfo> serializationTypes;
#endif

public:

// constants for serialization
static const antlr_int32_t EPSILON;
static const antlr_int32_t RANGE;
static const antlr_int32_t RULE;
static const antlr_int32_t PREDICATE;
static const antlr_int32_t ATOM;
static const antlr_int32_t ACTION;
static const antlr_int32_t SET;
static const antlr_int32_t NOT_SET;
static const antlr_int32_t WILDCARD;

static const std::vector<std::string> serializationNames;

/** The target of this transition. */
ANTLR_NOTNULL
const ATNState* target;

};

Expand Down
24 changes: 23 additions & 1 deletion runtime/Cpp/include/antlr/misc/Utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,13 @@ class ANTLR_API Utils
{
static std::string valueOf(const T& value);
};

template <typename Iter, typename T>
static antlr_int32_t binarySearch(Iter begin, Iter end, const T& value);

template <typename Iter, typename T, typename Comp>
static antlr_int32_t binarySearch(Iter begin, Iter end, const T& value, Comp cmp);

template<typename T>
static bool equals(const antlr_auto_ptr<T>& a, const antlr_auto_ptr<T>& b);
};
Expand Down Expand Up @@ -183,6 +186,25 @@ antlr_int32_t Utils::binarySearch(Iter begin, Iter end, const T& value)
return result;
}

template <typename Iter, typename T, typename Comp>
antlr_int32_t Utils::binarySearch(Iter begin, Iter end, const T& value, Comp cmp)
{
antlr_int32_t result;
Iter it = std::upper_bound(begin, end, value, cmp);
if (it == begin) {
result = -1;
} else {
if (*(it-1) == value) {
// value was found
result = it-1 - begin;
} else {
// value was not found
result = -(it - begin) - 1;
}
}
return result;
}

template<typename T>
bool Utils::equals(const antlr_auto_ptr<T>& a, const antlr_auto_ptr<T>& b)
{
Expand Down
134 changes: 134 additions & 0 deletions runtime/Cpp/src/atn/Transition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,144 @@
*/

#include <antlr/atn/Transition.h>
#include <antlr/atn/EpsilonTransition.h>
#include <antlr/atn/RangeTransition.h>
#include <antlr/atn/RuleTransition.h>
#include <antlr/atn/PredicateTransition.h>
#include <antlr/atn/AtomTransition.h>
#include <antlr/atn/ActionTransition.h>
#include <antlr/atn/SetTransition.h>
#include <antlr/atn/NotSetTransition.h>
#include <antlr/atn/WildcardTransition.h>
#include <antlr/misc/Utils.h>
#include <algorithm>
#include <stdexcept>


using namespace antlr4::misc;

namespace antlr4 {
namespace atn {


// constants for serialization
const antlr_int32_t Transition::EPSILON = 1;
const antlr_int32_t Transition::RANGE = 2;
const antlr_int32_t Transition::RULE = 3;
const antlr_int32_t Transition::PREDICATE = 4; // e.g., {isType(input.LT(1))}?
const antlr_int32_t Transition::ATOM = 5;
const antlr_int32_t Transition::ACTION = 6;
const antlr_int32_t Transition::SET = 7; // ~(A|B) or ~atom, wildcard, which convert to next 2
const antlr_int32_t Transition::NOT_SET = 8;
const antlr_int32_t Transition::WILDCARD = 9;

const std::vector<std::string> Transition::serializationNames =
Transition::getSerializationNames();

#if defined(HAVE_CX11)
const HashMap<std::size_t, antlr_int32_t> Transition::serializationTypes =
Transition::getSerializationTypes();
#else
const std::vector<Transition::TypeInfo> Transition::serializationTypes =
Transition::getSerializationTypes();
#endif

Transition::Transition(ANTLR_NOTNULL const ATNState* target)
: target(target)
{
if (target == NULL) {
throw std::logic_error("target cannot be null.");
}
}

Transition::~Transition()
{
}

std::vector<std::string> Transition::getSerializationNames()
{
const char* names[] = {
"INVALID",
"EPSILON",
"RANGE",
"RULE",
"PREDICATE",
"ATOM",
"ACTION",
"SET",
"NOT_SET",
"WILDCARD"
};
return std::vector<std::string>(names, names + sizeof(names)/sizeof(names[0]));
}

#if defined(HAVE_CX11)

antlr_int32_t Transition::getSerializationType(const std::type_info& type)
{
antlr_int32_t* type = serializationTypes.get(type.hash_code());
if (type == NULL) {
throw std::logic_error("type not found");
}
return *type;
}

HashMap<std::size_t, antlr_int32_t> Transition::getSerializationTypes()
{
HashMap<std::size_t, antlr_int32_t> types;
types.put(typeid(EpsilonTransition).hash_code(), EPSILON);
types.put(typeid(RangeTransition).hash_code(), RANGE);
types.put(typeid(RuleTransition).hash_code(), RULE);
types.put(typeid(PredicateTransition).hash_code(), PREDICATE);
types.put(typeid(AtomTransition).hash_code(), ATOM);
types.put(typeid(ActionTransition).hash_code(), ACTION);
types.put(typeid(SetTransition).hash_code(), SET);
types.put(typeid(NotSetTransition).hash_code(), NOT_SET);
types.put(typeid(WildcardTransition).hash_code(), WILDCARD);
return types;
}

#else /* HAVE_CX11 */

antlr_int32_t Transition::getSerializationType(const std::type_info& type)
{
for (std::vector<TypeInfo>::const_iterator it = serializationTypes.begin();
it != serializationTypes.end(); it++)
{
if (type == *it->first) {
return it->second;
}
}
throw std::logic_error("type not found");
}

std::vector<Transition::TypeInfo> Transition::getSerializationTypes()
{
std::vector<TypeInfo> types;
types.push_back(TypeInfo(&typeid(EpsilonTransition), EPSILON));
types.push_back(TypeInfo(&typeid(RangeTransition), RANGE));
types.push_back(TypeInfo(&typeid(RuleTransition), RULE));
types.push_back(TypeInfo(&typeid(PredicateTransition), PREDICATE));
types.push_back(TypeInfo(&typeid(AtomTransition), ATOM));
types.push_back(TypeInfo(&typeid(ActionTransition), ACTION));
types.push_back(TypeInfo(&typeid(SetTransition), SET));
types.push_back(TypeInfo(&typeid(NotSetTransition), NOT_SET));
types.push_back(TypeInfo(&typeid(WildcardTransition), WILDCARD));
return types;
}

#endif

/** Are we epsilon, action, sempred? */
bool Transition::isEpsilon() const
{
return false;
}

std::auto_ptr<IntervalSet> Transition::label() const
{
return std::auto_ptr<IntervalSet>();
}

} /* namespace atn */
} /* namespace antlr4 */

0 comments on commit b81507e

Please sign in to comment.