summaryrefslogtreecommitdiffstats
path: root/lib/antlr/antlr/TreeParser.hpp
blob: aeee3f9d1352f51400eea94c8cddb30bda4a5233 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#ifndef INC_TreeParser_hpp__
#define INC_TreeParser_hpp__

/* ANTLR Translator Generator
 * Project led by Terence Parr at http://www.jGuru.com
 * Software rights: http://www.antlr.org/license.html
 *
 * $Id$
 */

#include <antlr/config.hpp>
#include <antlr/AST.hpp>
#include <antlr/ASTFactory.hpp>
#include <antlr/BitSet.hpp>
#include <antlr/RecognitionException.hpp>
#include <antlr/MismatchedTokenException.hpp>
#include <antlr/TreeParserSharedInputState.hpp>

#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
namespace antlr {
#endif

class ANTLR_API TreeParser {
public:
	TreeParser()
	: astFactory(0)
	, inputState(new TreeParserInputState())
	, traceDepth(0)
	{
	}

	TreeParser(const TreeParserSharedInputState& state)
	: astFactory(0)
	, inputState(state)
	, traceDepth(0)
	{
	}

	virtual ~TreeParser()
	{
	}

	/// Get the AST return value squirreled away in the parser
	virtual RefAST getAST() = 0;

	/** Make sure current lookahead symbol matches the given set
	 * Throw an exception upon mismatch, which is caught by either the
	 * error handler or by a syntactic predicate.
	 */
	virtual void match(RefAST t, const BitSet& b)
	{
		if ( !t || t==ASTNULL || !b.member(t->getType()) )
			throw MismatchedTokenException( getTokenNames(), getNumTokens(),
													  t, b, false );
	}

	/** Specify the AST factory to be used during tree building. (Compulsory)
	 * Setting the factory is compulsory (if you intend to modify
	 * the tree in the treeparser). The AST Factory is shared between
	 * parser (who builds the initial AST) and treeparser.
	 * @see Parser::getASTFactory()
	 */
	virtual void setASTFactory(ASTFactory* factory)
	{
		astFactory = factory;
	}
	/// Return pointer to ASTFactory
	virtual ASTFactory* getASTFactory() const
	{
		return astFactory;
	}
	/// Get the name for token 'num'
	virtual const char* getTokenName(int num) const = 0;
	/// Return the number of tokens defined
	virtual int getNumTokens() const = 0;
	/// Return an array of getNumTokens() token names
	virtual const char* const* getTokenNames() const = 0;

	/// Parser error-reporting function can be overridden in subclass
	virtual void reportError(const RecognitionException& ex);
	/// Parser error-reporting function can be overridden in subclass
	virtual void reportError(const ANTLR_USE_NAMESPACE(std)string& s);
	/// Parser warning-reporting function can be overridden in subclass
	virtual void reportWarning(const ANTLR_USE_NAMESPACE(std)string& s);

	/// These are used during when traceTreeParser commandline option is passed.
	virtual void traceIndent();
	virtual void traceIn(const char* rname, RefAST t);
	virtual void traceOut(const char* rname, RefAST t);

	/** The AST Null object; the parsing cursor is set to this when
	 * it is found to be null.  This way, we can test the
	 * token type of a node without having to have tests for 0
	 * everywhere.
	 */
	static RefAST ASTNULL;

protected:
	virtual void match(RefAST t, int ttype)
	{
		if (!t || t == ASTNULL || t->getType() != ttype )
			throw MismatchedTokenException( getTokenNames(), getNumTokens(),
													  t, ttype, false );
	}

	virtual void matchNot(RefAST t, int ttype)
	{
		if ( !t || t == ASTNULL || t->getType() == ttype )
			throw MismatchedTokenException( getTokenNames(), getNumTokens(),
													  t, ttype, true );
	}

	/** AST support code; parser and treeparser delegate to this object */
	ASTFactory* astFactory;

	/// The input state of this tree parser.
	TreeParserSharedInputState inputState;

	/** Used to keep track of indent depth with -traceTreeParser */
	int traceDepth;

	/** Utility class which allows tracing to work even when exceptions are
	 * thrown.
	 */
	class Tracer {
	private:
		TreeParser* parser;
		const char* text;
		RefAST tree;
	public:
		Tracer(TreeParser* p, const char* t, RefAST a)
		: parser(p), text(t), tree(a)
		{
			parser->traceIn(text,tree);
		}
		~Tracer()
		{
			parser->traceOut(text,tree);
		}
	private:
		Tracer(const Tracer&);							// undefined
		const Tracer& operator=(const Tracer&);	// undefined
	};

private:
	// no copying of treeparser instantiations...
	TreeParser(const TreeParser& other);
	TreeParser& operator=(const TreeParser& other);
};

#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
}
#endif

#endif //INC_TreeParser_hpp__