⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 code.cc

📁 a little DFA compiler.
💻 CC
📖 第 1 页 / 共 3 页
字号:
			}			if (y->depth < x->depth)			{				x->depth = y->depth;			}		}	}	if (x->depth == k)	{		do		{			(*--top)->depth = cInfinity;			(*top)->link = x;		}		while (*top != x);	}}static bool state_is_in_non_trivial_SCC(const State* s){		// does not link to self	if (s->link != s)	{		return true;	}		// or exists i: (s->go.spans[i].to->link == s)	//	// Note: (s->go.spans[i].to == s) is allowed, corresponds to s	// looping back to itself.	//	for (uint i = 0; i < s->go.nSpans; ++i)	{		const State* t = s->go.span[i].to;			if (t && t->link == s)		{			return true;		}	}	// otherwise no	return false;}uint maxDist(State *s){	if (s->depth != cInfinity)	{		// Already calculated, just return result.    	return s->depth;	}	uint mm = 0;	for (uint i = 0; i < s->go.nSpans; ++i)	{		State *t = s->go.span[i].to;		if (t)		{			uint m = 1;			if (!t->link) // marked as non-key state			{				if (t->depth == cInfinity)				{					t->depth = maxDist(t);				}				m += t->depth;			}			if (m > mm)			{				mm = m;			}		}	}	s->depth = mm;	return mm;}void calcDepth(State *head){	State* s;	// mark non-key states by s->link = NULL ;	for (s = head; s; s = s->next)	{		if (s != head && !state_is_in_non_trivial_SCC(s))		{			s->link = NULL;		}		//else: key state, leave alone	}		for (s = head; s; s = s->next)	{		s->depth = cInfinity;	}	// calculate max number of transitions before guarantied to reach	// a key state.	for (s = head; s; s = s->next)	{		maxDist(s);	}}void DFA::findSCCs(){	SCC scc(nStates);	State *s;	for (s = head; s; s = s->next)	{		s->depth = 0;		s->link = NULL;	}	for (s = head; s; s = s->next)	{		if (!s->depth)		{			scc.traverse(s);		}	}	calcDepth(head);}void DFA::split(State *s){	State *move = new State;	(void) new Move(move);	addState(&s->next, move);	move->link = s->link;	move->rule = s->rule;	move->go = s->go;	s->rule = NULL;	s->go.nSpans = 1;	s->go.span = new Span[1];	s->go.span[0].ub = ubChar;	s->go.span[0].to = move;}void DFA::findBaseState(){	Span *span = new Span[ubChar - lbChar];	for (State *s = head; s; s = s->next)	{		if (!s->link)		{			for (uint i = 0; i < s->go.nSpans; ++i)			{				State *to = s->go.span[i].to;				if (to && to->isBase)				{					to = to->go.span[0].to;					uint nSpans = merge(span, s, to);					if (nSpans < s->go.nSpans)					{						delete [] s->go.span;						s->go.nSpans = nSpans;						s->go.span = new Span[nSpans];						memcpy(s->go.span, span, nSpans*sizeof(Span));					}					break;				}			}		}	}	delete [] span;}void DFA::emit(std::ostream &o, uint ind){	State *s;	uint i, bitmap_brace = 0;	findSCCs();	head->link = head;	uint nRules = 0;	for (s = head; s; s = s->next)	{		s->depth = maxDist(s);		if (maxFill < s->depth)		{			maxFill = s->depth;		}		if (s->rule && s->rule->accept >= nRules)		{			nRules = s->rule->accept + 1;		}	}	uint nSaves = 0;	uint *saves = new uint[nRules];	memset(saves, ~0, (nRules)*sizeof(*saves));	// mark backtracking points	bool bSaveOnHead = false;	for (s = head; s; s = s->next)	{		if (s->rule)		{			for (i = 0; i < s->go.nSpans; ++i)			{				if (s->go.span[i].to && !s->go.span[i].to->rule)				{					delete s->action;					s->action = NULL;					if (saves[s->rule->accept] == ~0u)					{						saves[s->rule->accept] = nSaves++;					}					bSaveOnHead |= s == head;					(void) new Save(s, saves[s->rule->accept]); // sets s->action				}			}		}	}	// insert actions	State **rules = new State * [nRules];	memset(rules, 0, (nRules)*sizeof(*rules));	State *accept = NULL;	Accept *accfixup = NULL;	for (s = head; s; s = s->next)	{		State * ow;		if (!s->rule)		{			ow = accept;		}		else		{			if (!rules[s->rule->accept])			{				State *n = new State;				(void) new Rule(n, s->rule);				rules[s->rule->accept] = n;				addState(&s->next, n);			}			ow = rules[s->rule->accept];		}		for (i = 0; i < s->go.nSpans; ++i)		{			if (!s->go.span[i].to)			{				if (!ow)				{					ow = accept = new State;					accfixup = new Accept(accept, nRules, saves, rules);					addState(&s->next, accept);				}				s->go.span[i].to = ow;			}		}	}		if (accfixup)	{		accfixup->genRuleMap();	}	// split ``base'' states into two parts	for (s = head; s; s = s->next)	{		s->isBase = false;		if (s->link)		{			for (i = 0; i < s->go.nSpans; ++i)			{				if (s->go.span[i].to == s)				{					s->isBase = true;					split(s);					if (bFlag)					{						BitMap::find(&s->next->go, s);					}					s = s->next;					break;				}			}		}	}	// find ``base'' state, if possible	findBaseState();	delete head->action;	head->action = NULL;	if (bFlag)	{		o << indent(ind++) << "{\n";		bitmap_brace = 1;		BitMap::gen(o, ind, lbChar, ubChar <= 256 ? ubChar : 256);	}	bUsedYYAccept = false;		uint start_label = next_label;	(void) new Initial(head, next_label++, bSaveOnHead);	if (bUseStartLabel)	{		if (startLabelName.empty())		{			vUsedLabels.insert(start_label);		}	}	for (s = head; s; s = s->next)	{		s->label = next_label++;	}	// Save 'next_fill_index' and compute information about code generation	// while writing to null device.	uint save_fill_index = next_fill_index;	null_stream  null_dev;	for (s = head; s; s = s->next)	{		bool readCh = false;		s->emit(null_dev, ind, readCh);		s->go.genGoto(null_dev, ind, s, s->next, readCh);	}	if (last_fill_index < next_fill_index)	{		last_fill_index = next_fill_index;	}	next_fill_index = save_fill_index;	// Generate prolog	o << "\n" << outputFileInfo;	o << indent(ind++) << "{\n";	if (!fFlag)	{		o << indent(ind) << mapCodeName["YYCTYPE"] << " " << mapCodeName["yych"] << ";\n";		if (bUsedYYAccept)		{			o << indent(ind) << "unsigned int "<< mapCodeName["yyaccept"] << " = 0;\n";		}	}	else	{		o << "\n";	}	genGetState(o, ind, start_label);	if (vUsedLabels.count(1))	{		vUsedLabels.insert(0);		o << indent(ind) << "goto " << labelPrefix << "0;\n";	}	// Generate code	for (s = head; s; s = s->next)	{		bool readCh = false;		s->emit(o, ind, readCh);		s->go.genGoto(o, ind, s, s->next, readCh);	}	// Generate epilog	o << indent(--ind) << "}\n";	if (bitmap_brace)	{		o << indent(--ind) << "}\n";	}	// Cleanup	if (BitMap::first)	{		delete BitMap::first;		BitMap::first = NULL;	}	delete [] saves;	delete [] rules;	bUseStartLabel = false;}void genGetState(std::ostream &o, uint& ind, uint start_label){	if (fFlag && !bWroteGetState)	{		vUsedLabels.insert(start_label);		o << indent(ind) << "switch(" << mapCodeName["YYGETSTATE"] << "()) {\n";		if (bUseStateAbort)		{			o << indent(ind) << "default: abort();\n";			o << indent(ind) << "case -1: goto " << labelPrefix << start_label << ";\n";		}		else		{			o << indent(ind) << "default: goto " << labelPrefix << start_label << ";\n";		}		for (size_t i=0; i<last_fill_index; ++i)		{			o << indent(ind) << "case " << i << ": goto " << mapCodeName["yyFillLabel"] << i << ";\n";		}		o << indent(ind) << "}\n";		if (bUseStateNext)		{			o << mapCodeName["yyNext"] << ":\n";		}		bWroteGetState = true;	}}std::ostream& operator << (std::ostream& o, const file_info& li){	if (li.ln && !iFlag)	{		o << "#line " << li.ln->get_line() << " \"" << li.fname << "\"\n";	}	return o;}uint Scanner::get_line() const{	return cline;}void Scanner::config(const Str& cfg, int num){	if (cfg.to_string() == "indent:top")	{		if (num < 0)		{			fatal("configuration 'indent:top' must be a positive integer");		}		topIndent = num;	}	else if (cfg.to_string() == "yybm:hex")	{		yybmHexTable = num != 0;	}	else if (cfg.to_string() == "startlabel")	{		bUseStartLabel = num != 0;		startLabelName = "";	}	else if (cfg.to_string() == "state:abort")	{		bUseStateAbort = num != 0;	}	else if (cfg.to_string() == "state:nextlabel")	{		bUseStateNext = num != 0;	}	else if (cfg.to_string() == "yyfill:enable")	{		bUseYYFill = num != 0;	}	else if (cfg.to_string() == "yyfill:parameter")	{		bUseYYFillParam = num != 0;	}	else if (cfg.to_string() == "cgoto:threshold")	{		cGotoThreshold = num;	}	else if (cfg.to_string() == "yych:conversion")	{		if (num)		{			yychConversion  = "(";			yychConversion += mapCodeName["YYCTYPE"];			yychConversion += ")";		}		else		{			yychConversion  = "";		}	}	else	{		fatal("unrecognized configuration name or illegal integer value");	}}static std::set<std::string> mapVariableKeys;static std::set<std::string> mapDefineKeys;static std::set<std::string> mapLabelKeys;void Scanner::config(const Str& cfg, const Str& val){	if (mapDefineKeys.empty())	{		mapVariableKeys.insert("variable:yyaccept");		mapVariableKeys.insert("variable:yybm");		mapVariableKeys.insert("variable:yych");		mapVariableKeys.insert("variable:yytarget");		mapDefineKeys.insert("define:YYCTXMARKER");		mapDefineKeys.insert("define:YYCTYPE");		mapDefineKeys.insert("define:YYCURSOR");		mapDefineKeys.insert("define:YYDEBUG");		mapDefineKeys.insert("define:YYFILL");		mapDefineKeys.insert("define:YYGETSTATE");		mapDefineKeys.insert("define:YYLIMIT");		mapDefineKeys.insert("define:YYMARKER");		mapDefineKeys.insert("define:YYSETSTATE");		mapLabelKeys.insert("label:yyFillLabel");		mapLabelKeys.insert("label:yyNext");	}	std::string strVal;	if (val.len >= 2 && val.str[0] == val.str[val.len-1] 	&& (val.str[0] == '"' || val.str[0] == '\''))	{		SubStr tmp(val.str + 1, val.len - 2);		unescape(tmp, strVal);	}	else	{		strVal = val.to_string();	}	if (cfg.to_string() == "indent:string")	{		indString = strVal;	}	else if (cfg.to_string() == "startlabel")	{		startLabelName = strVal;		bUseStartLabel = !startLabelName.empty();	}	else if (cfg.to_string() == "labelprefix")	{		labelPrefix = strVal;	}	else if (mapVariableKeys.find(cfg.to_string()) != mapVariableKeys.end())    {    	if (bFirstPass && !mapCodeName.insert(    			std::make_pair(cfg.to_string().substr(sizeof("variable:") - 1), strVal)    			).second)    	{			fatal("variable already being used and cannot be changed");    	}    }	else if (mapDefineKeys.find(cfg.to_string()) != mapDefineKeys.end())    {    	if (bFirstPass && !mapCodeName.insert(    			std::make_pair(cfg.to_string().substr(sizeof("define:") - 1), strVal)    			).second)    	{ 			fatal("define already being used and cannot be changed"); 		}    }	else if (mapLabelKeys.find(cfg.to_string()) != mapLabelKeys.end())    {    	if (bFirstPass && !mapCodeName.insert(    			std::make_pair(cfg.to_string().substr(sizeof("label:") - 1), strVal)    			).second)    	{			fatal("label already being used and cannot be changed");    	}    }	else	{		fatal("unrecognized configuration name or illegal string value");	}}} // end namespace re2c

⌨️ 快捷键说明

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