whale.h.svn-base

来自「Complete support for EBNF notation; Obje」· SVN-BASE 代码 · 共 422 行

SVN-BASE
422
字号
//#define _RWSTD_BOUNDS_CHECKING#ifndef __WHALE__WHALE_H#define __WHALE__WHALE_H#define WHALE_VERSION "0.3.2"#define WHALE_RELEASE_DATE "17 April, 2002"#define SHORT_COPYRIGHT_NOTICE "Whale " WHALE_VERSION ", a parser generator. " "(C) A. Okhotin and V. Prus, 1999-2002.\n"#define COPYRIGHT_NOTICE_FOR_GENERATED_FILES "\t\x22" "%s generated by Whale " WHALE_VERSION " (" WHALE_RELEASE_DATE ").\\n\x22\n" 	"\t\x22" "(C) Alexander Okhotin <okhotin@aha.ru>, 1999-2002.\\n\x22\n" "\t\x22" "(C) Vladimir Prus <ghost@cs.msu.su>, 2000-2002.\\n\x22"#define FIRST_LINE_FOR_GENERATED_FILES "\n/* %s generated by Whale */\n"#define COMMAND_LINE_SYNTAX "Command line syntax: whale filename.whl\n"#if '\xff'<'\x0'	#error This program requires char to be unsigned.#endif#include "assert.h"#include <string.h>#include <vector>#include <set>#include <map>#include <string>#include <exception>struct QuietException : std::exception{};struct NullTerminatedStringCompare : std::binary_function<char *, char *, bool>{	bool operator ()(const char *s1, const char *s2) const	{		return strcmp(s1, s2)<0;	}};class SymbolNumber{	int n;	explicit SymbolNumber(int supplied_n) { n=supplied_n; }public:	bool is_terminal() const { return n>0; }	bool is_nonterminal() const { return n<0; }	bool is_end_marker() const { return n==1; }	bool is_start_symbol() const { return n==-1; }	int nonterminal_number() const { return -(n+1); }	int terminal_number() const { return n-1; }	int get_n() const { return n; }	operator int() const { return n; }	// these functions should be used as constructors.	static SymbolNumber for_nonterminal(int n) { return SymbolNumber(-(n+1)); }	static SymbolNumber for_terminal(int n) { return SymbolNumber(n+1); }	static SymbolNumber error() { return SymbolNumber(0); }};inline bool operator <(SymbolNumber sn1, SymbolNumber sn2){	if(int(sn1)<0 && int(sn2)<0)		return int(sn1)>int(sn2);	else		return int(sn1)<int(sn2);}#include "classes.h"#include "lr.h"#include "precedence.h"#include "variables.h"#include "tuple.h"#include "tables.h"namespace Whale{	class Terminal;	class NonterminalExpression;	class NonterminalExpressionCode;	class NonterminalExpressionConnectUp;	class NonterminalExpressionPrecedence;	class NonterminalOptionStatement;	class NonterminalS;}struct TerminalData{	char *name;	Whale::Terminal *declaration;	ClassHierarchy::Class *type;	TerminalData()	{		name=NULL;		declaration=NULL;		type=NULL;	}	void print_where_it_was_declared(std::ostream &os);};struct AlternativeData{	Whale::Terminal *declaration;	ClassHierarchy::Class *type;	Whale::NonterminalExpression *expr;	std::vector<int> creator_nn;	bool connect_up;	AlternativeData()	{		declaration=NULL;		type=NULL;		expr=NULL;		connect_up=false;	}};struct NonterminalData{	enum Category	{		NORMAL,		// An ordinary nonterminal.		EXTERNAL,	// A nonterminal defined by 'external'				// statement. Its internal data type is hidden				// from the user.		START,		// S', the start symbol of the augmented grammar.		BODY,		// Iteration body. For each iteration used				// one (or two for iteration_pair) body is				// created. For example, the EBNF rule				//	A -> (a (b c)+)*				// causes bodies A-BodyI and A-BodyII and rules				//	A -> A-IteratorI				//	A -> e				//	A-BodyI -> a A-IteratorII				//	A-BodyII -> b c				// to be created.		ITERATOR,	// Iterator is a symbol used to accumulate				// a series of bodies. In the example above,				// two iterators, A-IteratorI and A-IteratorII,				// and rules				//	A-IteratorI -> A-IteratorI A-BodyI				//	A-IteratorI -> A-BodyI				//	A-IteratorII -> A-IteratorII A-BodyII				//	A-IteratorII -> A-BodyII				// would be created.		INVOKER,	// A purpose of invoker is to invoke user code				// placed in the middle of a rule. Declaration				//	B -> a { cout << "Here!\n"; } b;				// would result in rules				//	B -> a B-InvokerI b				//	B-InvokerI -> e				// where user code is attached to Reduce by				// the latter rule.		CREATOR,	// (ought to write it someday)		UPDATER,		CONNECTOR	};	char *name;	Whale::Terminal *declaration;	ClassHierarchy::Class *type;		// the internal type.	ClassHierarchy::Class *external_type;	// (category==NORMAL || category==EXTERNAL) <=> is_ancillary==false	bool is_ancillary;	Category category;	int master_nn, master_an; // if is_ancillary==true	Whale::NonterminalExpressionCode *code_invoker_declaration; // for code invokers	std::vector<int> rules_where_ancillary_symbol_is_used; // for creators and updaters.	std::vector<Whale::NonterminalExpressionConnectUp *> requests_to_connect_up;	bool multiple_alternatives_mode;	std::vector<AlternativeData> alternatives;	std::set<int> first;			// a: A ==>* a alpha	bool is_nullable;			// true if (A ==>* epsilon)	std::set<int> first_nonterminals;	// B: A ==>* B alpha	std::set<int> follow;	int number_of_iterators;	int number_of_invokers;	int number_of_creators;	int number_of_updaters;	int first_rule, last_rule; // number_of_rules=last_rule-first_rule	NonterminalData()	{		name=NULL;		declaration=NULL;		type=NULL;		external_type=NULL;		is_ancillary=false;		code_invoker_declaration=NULL;		master_nn=-1;		master_an=-1;		number_of_iterators=0;		number_of_invokers=0;		number_of_creators=0;		number_of_updaters=0;	}	void print_where_it_was_declared(std::ostream &os);};struct RuleData{	int nn, an;	std::vector<SymbolNumber> body;	std::vector<Whale::NonterminalExpression *> expr_body;	Whale::NonterminalExpressionCode *code_to_execute_upon_reduce;	std::vector<Whale::NonterminalExpressionPrecedence *> precedence_expressions;	// creator_nn==-1 <==> create_and_undate_operator_locations.size()==0	std::vector<int> create_and_update_operator_locations;	int creator_nn;	int precedence_symbol_number;//	bool precedence_symbol_explicitly_set;	RuleData(int supplied_nn, int supplied_an)	{		nn=supplied_nn, an=supplied_an;		code_to_execute_upon_reduce=NULL;		precedence_symbol_number=-1;	//	precedence_symbol_explicitly_set=false;		creator_nn=-1;	}	std::string in_printable_form() const;};bool operator <(const RuleData &r1, const RuleData &r2);struct PrecedenceSymbolData{	enum Associativity { ASSOC_UNDEFINED, ASSOC_LEFT, ASSOC_NONE,		ASSOC_RIGHT };	char *name;	Associativity associativity;	Whale::Terminal *declared_at;	bool was_implicitly_declared;	PrecedenceSymbolData()	{		name=NULL;		associativity=ASSOC_LEFT;		declared_at=NULL;		was_implicitly_declared=false;	}	void print_where_it_was_declared(std::ostream &os);};struct AssignmentData{	enum ValueType {VALUE_TRUE, VALUE_FALSE, VALUE_ID, VALUE_NUMBER,		VALUE_STRING, VALUE_CODE};	Whale::NonterminalOptionStatement *declaration;	std::vector<std::pair<char *, ValueType> > parameters; // those within brackets	std::vector<std::pair<char *, ValueType> > values; // those after the '=' sign	AssignmentData()	{		declaration=NULL;	}};class WhaleData{public:	Whale::NonterminalS *S;	std::vector<TerminalData> terminals;	std::vector<NonterminalData> nonterminals;	int start_nonterminal_number, eof_terminal_number, error_terminal_number;	std::vector<RuleData> rules;	std::vector<PrecedenceSymbolData> precedence_symbols;	std::string file_name;	bool first_computed, first_nonterminals_computed, follow_computed;	PrecedenceDatabase precedence_database;	LRAutomaton lr_automaton;	std::set<LRConflictResolutionPrecedent> lr_conflict_resolution_precedents;	std::map<char *, std::vector<AssignmentData>, NullTerminatedStringCompare> assignments;	Variables variables;	struct Tables	{	#if 0		std::vector<int> rule_bodies;		std::vector<int> rule_body_indices;	#endif		std::vector<int> lr_action;		std::vector<IndexEntry> lr_action_indices;		std::vector<int> lr_action_error_map;		std::vector<IndexEntry> lr_action_error_map_indices;		std::vector<int> lr_goto;		std::vector<IndexEntry> lr_goto_indices;		std::vector<ClassHierarchy::DataMember *> all_data_members;	};	Tables tables;	int find_terminal(const char *s)	{		// time is not essential here, using plain linear searching.		for(int i=0; i<terminals.size(); i++)			if(!strcmp(s, terminals[i].name))				return i;		return -1;	}	int find_nonterminal(const char *s)	{		for(int i=0; i<nonterminals.size(); i++)			if(!strcmp(s, nonterminals[i].name))				return i;		return -1;	}	SymbolNumber find_symbol(const char *s)	{		int tn=find_terminal(s);		if(tn!=-1) return SymbolNumber::for_terminal(tn);		int nn=find_nonterminal(s);		if(nn!=-1) return SymbolNumber::for_nonterminal(nn);		return SymbolNumber::error();	}	int find_precedence_symbol(const char *s)	{		for(int i=0; i<precedence_symbols.size(); i++)			if(!strcmp(s, precedence_symbols[i].name))				return i;		return -1;	}	char *symbol_name(SymbolNumber sn)	{		if(sn.is_terminal())			return terminals[sn.terminal_number()].name;		else if(sn.is_nonterminal())			return nonterminals[sn.nonterminal_number()].name;		else			return NULL;	}	std::string full_symbol_name(SymbolNumber sn, bool capital)	{		if(sn.is_terminal())			return std::string(capital ? "Terminal " : "terminal ")+terminals[sn.terminal_number()].name;		else if(sn.is_nonterminal())			return std::string(capital ? "Nonterminal " : "nonterminal ")+nonterminals[sn.nonterminal_number()].name;		else			return std::string("(internal error)");	}	ClassHierarchy::Class *symbol_type(SymbolNumber sn)	{		if(sn.is_terminal())			return terminals[sn.terminal_number()].type;		else if(sn.is_nonterminal())			return nonterminals[sn.nonterminal_number()].type;		else			assert(false);	}	ClassHierarchy::Class *get_class_assigned_to_alternative(int nn, int an)	{		if(nonterminals[nn].multiple_alternatives_mode)			return nonterminals[nn].alternatives[an].type;		else			return nonterminals[nn].type;	}	AlternativeData &access_alternative(int nn, int an)	{		return nonterminals[nn].alternatives[an];	}	WhaleData();private:	WhaleData(const WhaleData &prototype)	{	}};extern WhaleData data;struct TerminalNamePrinter : std::binary_function<std::ostream &, int, std::ostream &>{	std::ostream &operator ()(std::ostream &os, int i)	{		os << data.terminals[i].name;	}};struct NonterminalNamePrinter : std::binary_function<std::ostream &, int, std::ostream &>{	std::ostream &operator ()(std::ostream &os, int i)	{		os << data.nonterminals[i].name;	}};struct PrecedenceNamePrinter : std::binary_function<std::ostream &, int, std::ostream &>{	std::ostream &operator ()(std::ostream &os, int i)	{		os << data.precedence_symbols[i].name;	}};#endif

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?