예제 #1
0
SymbolTable::SymbolTable(string file_name) {
	file = file_name;

	ifstream fin(file.c_str());
	ofstream fout("data/symbol_table.txt");
	Symbol symbol = Symbol(file);
	Table table[ symbol.GetCount() ];

	string line;
	int count = 0;
	int level_max = 0;
	/*------temp save for table------*/
	int level = 0;
	string symbol_name = "";
	string type_name = "";
	bool array_bool = false;
	bool function_bool = false;

	Origin();

	while(getline(fin, line)) {
		istringstream fin_word(line);
		string word = "";
		string remain = "";
		int pos = 0;

		while(fin_word >> word) {
			while(word != "") {
				if((pos = Check(word)) != -1) {
					if(pos != 0) {
						remain = word.substr(pos);
						word = word.substr(0, pos);
					}
					else {
						remain = word.substr(pos + length(word));
						word = word.substr(0, length(word));
					}
				}

				/*-----save in table------*/
				if( FindKeyWord(word) ) {
					type_name = word;
				}
				else {
					if(type_name != "") {
						if(word == ";" || word == "," || word == ")" || word == "=" || word == "(" || word == "[") {
							if(word == ";" || word == "," || word == ")" || word == "=") {
								array_bool = false;
								function_bool = false;
							}
							else if(word == "(") {
								level = 0;
								array_bool = false;
								function_bool = true;
							}
							else if(word == "[") {
								array_bool = true;
								function_bool = false;
							}

							table[count].Set(level, symbol_name, type_name, array_bool, function_bool);
							count = count + 1;
							type_name = "";
						}
						else {
							symbol_name = word;
						}
					}
				}

				if(word == "{" || word == "(") {
					level = level + 1;
				}
				else if(word == ")") {
					level = level - 1;
				}

				if(level > level_max) {
					level_max = level;
				}
				/*------------------------*/

				pos = 0;
				word = remain;
				remain = "";
			}
		}
	}

	int level_temp = 0;
	while(level_temp <= level_max) {
		for(int i = 0; i < (sizeof(table)/sizeof(*table)); i++) {
			if(table[i].GetLevel() == level_temp) {
				if(table[i].GetLevel() == table[i - 1].GetLevel() + 1) {
					scope = scope + 1;
				}
					table[i].SetScope(scope);
			}
		}

		level_temp = level_temp + 1;
	}

	//sort table
	for(int i = 0; i < (sizeof(table)/sizeof(*table)); i++) {
		for(int j = i + 1; j < (sizeof(table)/sizeof(*table)); j++) {
			if(table[j].GetScope() < table[i].GetScope()) {
				Table temp = Table();
				temp.Set(table[j].GetLevel(), table[j].GetSymbol(), table[j].GetType(), table[j].GetArray(), table[j].GetFunction());
				temp.SetScope(table[j].GetScope());

				for(int k = j; k >= i + 1; k--) {
					table[k].Set(table[k - 1].GetLevel(), table[k - 1].GetSymbol(), table[k - 1].GetType(), table[k - 1].GetArray(), table[k - 1].GetFunction());
					table[k].SetScope(table[k - 1].GetScope());
				}

				table[i].Set(temp.GetLevel(), temp.GetSymbol(), temp.GetType(), temp.GetArray(), temp.GetFunction());
				table[i].SetScope(temp.GetScope());
			}
		}
	}

	int temp = 0;
	for(int i = 0; i < (sizeof(table)/sizeof(*table)); i++) {
		if(temp != table[i].GetScope()) {
			temp = table[i].GetScope();
			fout << endl;
		}

		fout << table[i].GetScope() << " ";
		fout << table[i].GetSymbol() << " ";
		fout << table[i].GetType() << " ";
		fout << (table[i].GetArray() ? "true" : "false") << " ";
		fout << (table[i].GetFunction() ? "true" : "false") << " ";
		fout << endl;
	}

	fin.close();
	fout.close();
}
예제 #2
0
StsgRule::StsgRule(const Subgraph &fragment)
  : m_targetSide(fragment, true)
{
  // Source side

  const std::set<const Node *> &sinkNodes = fragment.GetLeaves();

  // Collect the subset of sink nodes that excludes target nodes with
  // empty spans.
  std::vector<const Node *> productiveSinks;
  productiveSinks.reserve(sinkNodes.size());
  for (std::set<const Node *>::const_iterator p = sinkNodes.begin();
       p != sinkNodes.end(); ++p) {
    const Node *sink = *p;
    if (!sink->GetSpan().empty()) {
      productiveSinks.push_back(sink);
    }
  }

  // Sort them into the order defined by their spans.
  std::sort(productiveSinks.begin(), productiveSinks.end(), PartitionOrderComp);

  // Build a map from target nodes to source-order indices, so that we
  // can construct the Alignment object later.
  std::map<const Node *, std::vector<int> > sinkToSourceIndices;
  std::map<const Node *, int> nonTermSinkToSourceIndex;

  m_sourceSide.reserve(productiveSinks.size());
  int srcIndex = 0;
  int nonTermCount = 0;
  for (std::vector<const Node *>::const_iterator p = productiveSinks.begin();
       p != productiveSinks.end(); ++p, ++srcIndex) {
    const Node &sink = **p;
    if (sink.GetType() == TREE) {
      m_sourceSide.push_back(Symbol("X", NonTerminal));
      sinkToSourceIndices[&sink].push_back(srcIndex);
      nonTermSinkToSourceIndex[&sink] = nonTermCount++;
    } else {
      assert(sink.GetType() == SOURCE);
      m_sourceSide.push_back(Symbol(sink.GetLabel(), Terminal));
      // Add all aligned target words to the sinkToSourceIndices map
      const std::vector<Node *> &parents(sink.GetParents());
      for (std::vector<Node *>::const_iterator q = parents.begin();
           q != parents.end(); ++q) {
        if ((*q)->GetType() == TARGET) {
          sinkToSourceIndices[*q].push_back(srcIndex);
        }
      }
    }
  }

  // Alignment

  std::vector<const Node *> targetLeaves;
  m_targetSide.GetTargetLeaves(targetLeaves);

  m_alignment.reserve(targetLeaves.size());
  m_nonTermAlignment.resize(nonTermCount);

  for (int i = 0, j = 0; i < targetLeaves.size(); ++i) {
    const Node *leaf = targetLeaves[i];
    assert(leaf->GetType() != SOURCE);
    if (leaf->GetSpan().empty()) {
      continue;
    }
    std::map<const Node *, std::vector<int> >::iterator p =
      sinkToSourceIndices.find(leaf);
    assert(p != sinkToSourceIndices.end());
    std::vector<int> &sourceNodes = p->second;
    for (std::vector<int>::iterator r = sourceNodes.begin();
         r != sourceNodes.end(); ++r) {
      int srcIndex = *r;
      m_alignment.push_back(std::make_pair(srcIndex, i));
    }
    if (leaf->GetType() == TREE) {
      m_nonTermAlignment[nonTermSinkToSourceIndex[leaf]] = j++;
    }
  }
}
예제 #3
0
void ObjectFile::ReadFile(const byte *begin)
{
 	const COFF_IMAGE_FILE_HEADER *header = (const COFF_IMAGE_FILE_HEADER *)begin;

	int i;
/*
	const COFF_IMAGE_SYMBOL *symtbl = (const COFF_IMAGE_SYMBOL *)(begin + header->PointerToSymbolTable);
	int nsym = header->NumberOfSymbols;
	const COFF_IMAGE_SYMBOL *symend = symtbl + nsym;
	const char *strtbl = (const char *)symend;
	symbols.Reserve(nsym);
	while(symtbl < symend)
	{
		String name;
		if(symtbl->N.Name.Short)
			name = MaxLenString(symtbl->N.ShortName, 8);
		else
			name = strtbl + symtbl->N.Name.Long;
		int atom = linkjob.Atomize(name);
		int naux = symtbl->NumberOfAuxSymbols;
		symbols.Add(atom, *symtbl++);
		while(--naux >= 0)
			symbols.Add(0, *symtbl++);
	}
*/
	const COFF_IMAGE_SECTION_HEADER *sechdr = (const COFF_IMAGE_SECTION_HEADER *)(begin
		+ sizeof(COFF_IMAGE_FILE_HEADER) + header->SizeOfOptionalHeader), *secptr;
	sections.SetCount(header->NumberOfSections + 1);
	Section& comdat = sections[0];
	comdat.type = SEC_ANON_COMDAT;
	comdat.name_atom = comdat.sec_atom = linkjob.bss_atom;
	comdat.flags = COFF_IMAGE_SCN_CNT_UNINITIALIZED_DATA | COFF_IMAGE_SCN_ALIGN_16BYTES
		| COFF_IMAGE_SCN_MEM_READ | COFF_IMAGE_SCN_MEM_WRITE;
	comdat.comdat_packing = 0;
	for(i = 1, secptr = sechdr; i < sections.GetCount(); i++, secptr++)
	{
		Section& sec = sections[i];
		sec.raw_size = secptr->SizeOfRawData;
		if(!(sec.size = secptr->Misc.VirtualSize))
			sec.size = sec.raw_size;
		sec.offset = secptr->PointerToRawData;
		ASSERT(sec.offset >= 0);
		sec.flags = secptr->Characteristics;
		sec.comdat_packing = 0;
		sec.coff_reloc_offset = secptr->VirtualAddress;
//		sec.comdat_assoc = 0;

		String secn = MaxLenString(secptr->Name, sizeof(secptr->Name));
/*
		if(linkjob.merge_gcc_sections && secn[0] == '/' && IsDigit(secn[1]))
		{
			if(sec.flags & COFF_IMAGE_SCN_CNT_CODE)
				secn = ".text$" + secn;
			else if(sec.flags & COFF_IMAGE_SCN_CNT_INITIALIZED_DATA)
				secn = ".data$" + secn;
			else
				secn = ".bss$" + secn;
		}
*/
		sec.name_atom = linkjob.Atomize(secn);
		secn = TrimClassName(secn);
		sec.sec_atom = linkjob.Atomize(secn);
		bool ctor_dtor_section = false;
		if(sec.sec_atom == linkjob.ctors_atom || sec.sec_atom == linkjob.dtors_atom)
		{
			sec.sec_atom = linkjob.data_atom;
//			sec.flags = (sec.flags & ~COFF_IMAGE_SCN_ALIGN_MASK) | COFF_IMAGE_SCN_ALIGN_4BYTES;
			has_ctors_dtors = ctor_dtor_section = true;
		}
		if(sec.sec_atom == linkjob.idata_atom)
			linkjob.idata_last = index;
		if(sec.name_atom == linkjob.idata_inull_atom)
			linkjob.idata_null_found = true;

		sec.type = (sec.sec_atom == linkjob.stab_atom
			? SEC_STAB : sec.sec_atom == linkjob.stabstr_atom
				? SEC_STABSTR : SEC_STD);
		if(sec.type == SEC_STAB)
			stab_index = i;
		else if(sec.type == SEC_STABSTR)
			stabstr_index = i;
		sec.autocollect = sec.type == SEC_STD
			&& (sec.sec_atom == linkjob.crt_atom
				|| ctor_dtor_section
				|| sec.sec_atom == linkjob.idata_atom
				|| sec.sec_atom == linkjob.rsrc_atom
				|| !linkjob.autocollect_crt_only && (sec.flags & COFF_IMAGE_SCN_CNT_INITIALIZED_DATA));
		if(sec.name_atom == linkjob.drectve_atom && (sec.flags & COFF_IMAGE_SCN_LNK_INFO))
		{
			String directives = String(begin + secptr->PointerToRawData, secptr->SizeOfRawData);
			linkjob.ReadCommand(directives, false);
		}
	}

	if(stab_index >= 0 && stabstr_index >= 0)
		linkjob.has_stabs = true;

	coff_symbols.SetCount(header->NumberOfSymbols);

	const COFF_IMAGE_SYMBOL *symtbl = (const COFF_IMAGE_SYMBOL *)(begin + header->PointerToSymbolTable), *symptr = symtbl;
	const char *strtbl = (const char *)(symtbl + header->NumberOfSymbols);
//	int xxxatom = linkjob.Atomize("?AppMain@@YAXXZ");
	for(i = 0; i < (int)header->NumberOfSymbols; i++, symptr++)
	{
//		if(symptr->SectionNumber > 0 && linkjob.NameAtom(*symptr, strtbl) == xxxatom)
//			__asm int 3;
//		RLOG(NFormat("%30<s SEC %04d VAL %08x %s", linkjob[linkjob.NameAtom(*symptr, strtbl)],
//			symptr->SectionNumber, (int)symptr->Value, file));

		if(symptr->SectionNumber < 0)
			coff_symbols[i] = Symbol(symptr->SectionNumber, symptr->Value);
		else if(symptr->StorageClass == COFF_IMAGE_SYM_CLASS_STATIC && symptr->SectionNumber != 0
		&& symptr->Value == 0 && symptr->NumberOfAuxSymbols >= 1)
//		&& linkjob.Atomize(TrimClassName(COFFSymbolName(*symptr, strtbl))) == sections[(int)symptr->SectionNumber].name_atom)
		{ // section aux symbol
			LinkJob::Symbol lsym;
			lsym.obj_sec.object = index;
			lsym.obj_sec.section = symptr->SectionNumber;
			lsym.value = 0;
			lsym.type = LinkJob::COFF_IMAGE_SYM_TYPE_SECTION;
			Section& sec = sections[(int)symptr->SectionNumber];
			if(sec.name_atom != linkjob.ctors_atom && sec.name_atom != linkjob.dtors_atom)
			{
				String secn = COFFSymbolName(*symptr, strtbl);
				sec.name_atom = linkjob.Atomize(secn);
				secn = TrimClassName(secn);
				sec.sec_atom = linkjob.Atomize(secn);
			}
			linkjob.AddGlobal(sec.name_atom, lsym);
			const COFF_IMAGE_AUX_SYMBOL *aux = (const COFF_IMAGE_AUX_SYMBOL *)(symptr + 1);
			if(sec.flags & COFF_IMAGE_SCN_LNK_COMDAT)
			{
				sec.comdat_packing = aux->Section.Selection;
				comdat_assoc.Add(aux->Section.Number, symptr->SectionNumber);
//				sec.comdat_assoc = aux->Section.Number;
				if(sec.comdat_packing == COFF_IMAGE_COMDAT_SELECT_EXACT_MATCH)
				{
					secptr = sechdr + (symptr->SectionNumber);
					sec.section_data.Reserve(secptr->SizeOfRawData + secptr->NumberOfRelocations * sizeof(COFF_IMAGE_RELOCATION));
					CatN(sec.section_data, secptr->SizeOfRawData, begin + secptr->PointerToRawData);
					const COFF_IMAGE_RELOCATION *relptr = (const COFF_IMAGE_RELOCATION *)(begin + secptr->PointerToRelocations);
					const COFF_IMAGE_RELOCATION *relend = relptr + secptr->NumberOfRelocations;
					while(relptr < relend)
					{
						COFF_IMAGE_RELOCATION r = *relptr++;
						r.SymbolTableIndex = linkjob.NameAtom(symtbl[r.SymbolTableIndex], strtbl);
						CatN(sec.section_data, sizeof(COFF_IMAGE_RELOCATION), &r);
					}
				}
			}
			coff_symbols[i] = Symbol(lsym.obj_sec.section, 0);
		}
		else if((symptr->StorageClass == COFF_IMAGE_SYM_CLASS_EXTERNAL || symptr->StorageClass == COFF_IMAGE_SYM_CLASS_STATIC)
		&& (symptr->SectionNumber != 0 || symptr->Value != 0))
		{
			bool glo = (symptr->StorageClass == COFF_IMAGE_SYM_CLASS_EXTERNAL);
			LinkJob::Symbol lsym;
			lsym.obj_sec.object = index;
			lsym.obj_sec.section = symptr->SectionNumber;
			lsym.value = symptr->Value;
			lsym.type = symptr->Type;
			lsym.external = glo;
			int atom = linkjob.NameAtom(*symptr, strtbl);
			linkjob.AddGlobal(atom, lsym);
			coff_symbols[i] = Symbol(glo ? ~atom : lsym.obj_sec.section, lsym.value);
		}
		else if(symptr->StorageClass == COFF_IMAGE_SYM_CLASS_WEAK_EXTERNAL && symptr->NumberOfAuxSymbols >= 1)
		{
			int refsym = symptr[1].N.Name.Short;
			int sym = linkjob.NameAtom(*symptr, strtbl);
			linkjob.AddWeakExternal(sym, linkjob.NameAtom(symtbl[refsym], strtbl));
			coff_symbols[i] = Symbol(~sym, symptr->Value);
		}
		else if(symptr->StorageClass == COFF_IMAGE_SYM_CLASS_EXTERNAL)
			coff_symbols[i] = Symbol(~linkjob.NameAtom(*symptr, strtbl), 0);
		else if(symptr->SectionNumber > 0)
			coff_symbols[i] = Symbol(symptr->SectionNumber, symptr->Value);
		i += symptr->NumberOfAuxSymbols;
		symptr += symptr->NumberOfAuxSymbols;
	}

	for(i = 1, secptr = sechdr; i < sections.GetCount(); i++, secptr++)
	{
		Section& sec = sections[i];
		sec.ref_sec_index = ref_sections.GetCount();
		sec.ref_ext_index = ref_externals.GetCount();
		if(sec.type == SEC_STD)
		{
			sec.coff_reloc.SetCount(secptr->NumberOfRelocations);
			memcpy(sec.coff_reloc.Begin(), (const COFF_IMAGE_RELOCATION *)(begin + secptr->PointerToRelocations),
				secptr->NumberOfRelocations * sizeof(COFF_IMAGE_RELOCATION));
			const COFF_IMAGE_RELOCATION *reloc = sec.coff_reloc.Begin();
			Index<int> ref_sec, ref_ext;
			for(int nreloc = secptr->NumberOfRelocations; --nreloc >= 0; reloc++)
			{
				const COFF_IMAGE_SYMBOL& sym = symtbl[reloc->SymbolTableIndex];
				if(sym.SectionNumber > 0 && sym.StorageClass != COFF_IMAGE_SYM_CLASS_EXTERNAL)
					ref_sec.FindAdd(sym.SectionNumber);
				if(sym.StorageClass == COFF_IMAGE_SYM_CLASS_STATIC && sym.SectionNumber > 0
				&& sym.Value == 0 && sym.NumberOfAuxSymbols >= 1 && !(sections[sym.SectionNumber].flags & COFF_IMAGE_SCN_LNK_COMDAT))
				{} // no-op for section externals
				else if(sym.StorageClass == COFF_IMAGE_SYM_CLASS_EXTERNAL
					|| sym.StorageClass == COFF_IMAGE_SYM_CLASS_WEAK_EXTERNAL
					|| sym.StorageClass == COFF_IMAGE_SYM_CLASS_STATIC)
				{
					int atom = linkjob.NameAtom(sym, strtbl);
					if(sym.SectionNumber == 0)
						linkjob.AddExternal(atom, ObjSec(index, i));
					ref_ext.FindAdd(atom);
				}
	/*
				{
					LinkJob::Symbol symbol;
					symbol.object = index;
					symbol.value = sym.Value;
					symbol.type = sym.Type;
					symbol.section = sym.SectionNumber;
					ref_ext.FindAdd(linkjob.AddGlobal(linkjob.NameAtom(sym, strtbl), symbol));
				}
	*/
			}
			ref_sections.AppendPick(ref_sec.PickKeys());
			ref_externals.AppendPick(ref_ext.PickKeys());
		}
/*
		else if(sec.type == SEC_STAB && stabstr_index >= 0)
		{
			ASSERT(sizeof(STAB_INFO) == 12);
			int count = sec.size / sizeof(STAB_INFO);
			stabs.SetCount(count);
			const byte *p = begin + sec.offset;
#ifdef CPU_LE // && CPU_32BIT
			memcpy(stabs.Begin(), p, count * sizeof(STAB_INFO));
#else
			for(STAB_INFO *sp = stabs.Begin(), *se = stabs.End(); sp < se; sp++, p += 12)
			{
				sp->strdx = PeekIL(p + STAB_STRDXOFF);
				sp->type = p[STAB_TYPEOFF];
				sp->other = p[STAB_OTHEROFF];
				sp->desc = PeekIW(p[STAB_DESCOFF]);
				sp->value = PeekIL(p[STAB_VALUEOFF]);
			}
#endif
			stab_ref.SetCount(count, 0);
			for(int nreloc = secptr->NumberOfRelocations; --nreloc >= 0; reloc++)
			{
				int entry = reloc->VirtualAddress / sizeof(STAB_INFO);
				if(entry < 0 || entry >= count)
					continue;
				const COFF_IMAGE_SYMBOL& sym = symtbl[reloc->SymbolTableIndex];
				if(sym.SectionNumber)
					stab_ref[entry] = ~sym.SectionNumber;
				else if(sym.StorageClass == COFF_IMAGE_SYM_CLASS_EXTERNAL || sym.StorageClass == COFF_IMAGE_SYM_CLASS_STATIC)
					stab_ref[entry] = linkjob.NameAtom(sym, strtbl);
			}
			if(linkjob.dump_flags & LinkJob::DUMP_STABS)
			{
				const Section& strsec = sections[stabstr_index];
				puts(NFormat("%s: %d stabs, .stab = %d bytes, .stabstr = %d bytes",
					ToString(), count, sec.size, strsec.size));
				const byte *str = begin + strsec.offset;
				for(int i = 0; i < stabs.GetCount(); i++)
				{
					const STAB_INFO& stab = stabs[i];
					String desc;
					desc << NFormat("[%d]: offset %08x, type %02x, desc %04x, value %08x, reloc %08x",
						i, stab.strdx, stab.type, stab.desc, stab.value, stab_ref[i]);
					puts(desc);
					if(stab.strdx)
						puts((const char *)(str + stab.strdx));
				}
			}
		}
*/
	}

	ref_sections.Shrink();
	ref_externals.Shrink();
}
예제 #4
0
파일: Parser.cpp 프로젝트: 123Phil/Compiler
bool Parser::Func()
{
	if (!("function" == lex)) {
		std::cout << "Function did not start with keyword 'function'\n";
		return false;
	} else {
		L.getTokLex(tok,lex);
	}
	
	std::string func_name;
	if (!("identifier" == tok)) {
		std::cout << "Invalid identifier in parameter list of function\n";
		return false;
	} else {
//		ident();
		func_name = lex;
		L.getTokLex(tok,lex);
	}

	if (!("(" == lex)) {
		std::cout << "Function parameters missing opening parenthesis\n";
		return false;
	} else {
		L.getTokLex(tok,lex);
	}
	
	if (!OptParamList()) return false;
	
	if (!(")" == lex)) {
		std::cout << "Function parameters missing closing parenthesis\n";
		return false;
	} else {
		L.getTokLex(tok,lex);
	}
	
	if (!(":" == lex)) {
		std::cout << "Function missing colon\n";
		return false;
	} else {
		L.getTokLex(tok,lex);
	}
	
	if (!Type()) return false;
	
	for (int i=0; i < funcs.size(); i++) {
		if (lex == funcs[i].id) {
			std::cout << "Error: function '" << lex << "' declared more than once.\n";
			return false;
		}
	}
	funcs.push_back(Symbol(f_curr_addr, func_name, curr_type));
	++f_curr_addr;
	
	if (!(";" == lex)) {
		std::cout << "Function type not followed by semicolon\n";
		return false;
	} else {
		L.getTokLex(tok,lex);
	}

// +++++++++++++++++++++	
// If functions actually implemented in working compiler, revise this
// to a functionDeclList, or note symbol scope.
	if (!OptDeclList()) return false;
	
	if (!("begin" == lex)) {
		std::cout << "Function body did not start with keyword 'begin'\n";
		return false;
	} else {
		L.getTokLex(tok,lex);
	}

// +++++++++++++++++++++
// If functions actually implemented in working compiler, revise this
// so that the function address jumps to these statements,
// and add a return at function end.
	if (!OptStmtList()) return false;
	
	if (!("end" == lex)) {
		std::cout << "Function body did not end with keyword 'end'\n";
		return false;
	} else {
		L.getTokLex(tok,lex);
	}
	
//	std::cout << "Func => function ident (OptParamList):Type; OptDeclList begin OptStmtList end\n";
	return true;
}
예제 #5
0
LoopStmt::LoopStmt(statement &body) : body(body)
{
	cond = symb_expr(Symbol("true"));
	is_tail_cond = false;
}
예제 #6
0
static QList<Symbol> tokenize(const DFA &dfa, const QString &input, Config *cfg, bool *ok = 0)
{
    QList<Symbol> symbols;
    Symbol lastSymbol;
    int state = 0;
    int lastAcceptingState = -1;
    QString lastAcceptingLexem;
    int lastAcceptingPos = -1;
    for (int i = 0; i < input.length(); ++i) {
        QChar ch = input.at(i);
        QChar chForInput = ch;
        if (cfg->caseSensitivity == Qt::CaseInsensitive)
            chForInput = chForInput.toLower();
        int next = dfa.at(state).transitions.value(chForInput.unicode());
        if (cfg->debug)
            qDebug() << "input" << input.at(i) << "leads to state" << next;
        if (next) {
            lastSymbol.lexem.append(input.at(i));
            lastSymbol.token = dfa.at(next).symbol;
            if (!lastSymbol.token.isEmpty()) {
                lastAcceptingState = next;
                lastAcceptingLexem = lastSymbol.lexem;
                lastAcceptingPos = i;
            }
            state = next;
        } else {
            if (lastAcceptingState != -1) {
                if (cfg->debug)
                    qDebug() << "adding" << dfa.at(lastAcceptingState).symbol << "and backtracking to" << lastAcceptingPos;
                Symbol s;
                s.token = dfa.at(lastAcceptingState).symbol;
                s.lexem = lastAcceptingLexem;
                symbols << s;
                lastSymbol = Symbol();
                state = 0;
                i = lastAcceptingPos;
                lastAcceptingPos = -1;
                lastAcceptingState = -1;
                continue;
            }
            if (state == 0 || lastSymbol.token.isEmpty()) {
                if (cfg->debug)
                    qDebug() << "invalid input";
                if (ok)
                    *ok = false;
                return symbols;
            }
            if (cfg->debug)
                qDebug() << "appending symbol with token" << lastSymbol.token;
            symbols << lastSymbol;
            lastSymbol = Symbol();
            state = 0;
            lastAcceptingState = -1;
            --i;
        }
    }
    if (!lastSymbol.token.isEmpty()) {
        if (cfg->debug)
            qDebug() << "appending (last) symbol with token" << lastSymbol.token;
        symbols << lastSymbol;
    } else if (lastAcceptingState != -1) {
        if (cfg->debug)
            qDebug() << "appending last accepting state with token" << dfa.at(lastAcceptingState).symbol;
        Symbol s;
        s.lexem = lastAcceptingLexem;
        s.token = dfa.at(lastAcceptingState).symbol;
        symbols << s;
    }
    if (ok)
        *ok = true;
    return symbols;
}
예제 #7
0
파일: main.cpp 프로젝트: Fale/qtmoko
int runMoc(int _argc, char **_argv)
{
    bool autoInclude = true;
    Preprocessor pp;
    Moc moc;
    pp.macros["Q_MOC_RUN"];
    pp.macros["__cplusplus"];
    QByteArray filename;
    QByteArray output;
    FILE *in = 0;
    FILE *out = 0;
    bool ignoreConflictingOptions = false;

    QVector<QByteArray> argv;
    argv.resize(_argc - 1);
    for (int n = 1; n < _argc; ++n)
        argv[n - 1] = _argv[n];
    int argc = argv.count();

    for (int n = 0; n < argv.count(); ++n) {
        if (argv.at(n).startsWith('@')) {
            QByteArray optionsFile = argv.at(n);
            optionsFile.remove(0, 1);
            if (optionsFile.isEmpty())
                error("The @ option requires an input file");
            QFile f(QString::fromLatin1(optionsFile.constData()));
            if (!f.open(QIODevice::ReadOnly | QIODevice::Text))
                error("Cannot open options file specified with @");
            argv.remove(n);
            while (!f.atEnd()) {
                QByteArray line = f.readLine().trimmed();
                if (!line.isEmpty())
                    argv.insert(n++, line);
            }
        }
    }

    // report Qt usage for commercial customers with a "metered license" (currently experimental)
#if QT_EDITION != QT_EDITION_OPENSOURCE
#ifdef QT_CONFIGURE_BINARIES_PATH
    const char *binariesPath = QT_CONFIGURE_BINARIES_PATH;
    QString reporterPath = QString::fromLocal8Bit(binariesPath) + QDir::separator()
                           + QLatin1String("qtusagereporter");
#if defined(Q_OS_WIN)
    reporterPath += QLatin1String(".exe");
#endif
    if (QFile::exists(reporterPath))
        system(qPrintable(reporterPath + QLatin1String(" moc")));
#endif
#endif

    argc = argv.count();

    for (int n = 0; n < argc; ++n) {
        QByteArray arg(argv[n]);
        if (arg[0] != '-') {
            if (filename.isEmpty()) {
                filename = arg;
                continue;
            }
            error("Too many input files specified");
        }
        QByteArray opt = arg.mid(1);
        bool more = (opt.size() > 1);
        switch (opt[0]) {
        case 'o': // output redirection
            if (!more) {
                if (!(n < argc-1))
                    error("Missing output file name");
                output = argv[++n];
            } else
                output = opt.mid(1);
            break;
        case 'E': // only preprocessor
            pp.preprocessOnly = true;
            break;
        case 'i': // no #include statement
            if (more)
                error();
            moc.noInclude        = true;
            autoInclude = false;
            break;
        case 'f': // produce #include statement
            if (ignoreConflictingOptions)
                break;
            moc.noInclude        = false;
            autoInclude = false;
            if (opt[1])                        // -fsomething.h
                moc.includeFiles.append(opt.mid(1));
            break;
        case 'p': // include file path
            if (ignoreConflictingOptions)
                break;
            if (!more) {
                if (!(n < argc-1))
                    error("Missing path name for the -p option.");
                moc.includePath = argv[++n];
            } else {
                moc.includePath = opt.mid(1);
            }
            break;
        case 'I': // produce #include statement
            if (!more) {
                if (!(n < argc-1))
                    error("Missing path name for the -I option.");
                pp.includes += Preprocessor::IncludePath(argv[++n]);
            } else {
                pp.includes += Preprocessor::IncludePath(opt.mid(1));
            }
            break;
        case 'F': // minimalistic framework support for the mac
            if (!more) {
                if (!(n < argc-1))
                    error("Missing path name for the -F option.");
                Preprocessor::IncludePath p(argv[++n]);
                p.isFrameworkPath = true;
                pp.includes += p;
            } else {
                Preprocessor::IncludePath p(opt.mid(1));
                p.isFrameworkPath = true;
                pp.includes += p;
            }
            break;
        case 'D': // define macro
            {
                QByteArray name;
                QByteArray value("1");
                if (!more) {
                    if (n < argc-1)
                        name = argv[++n];
                } else
                    name = opt.mid(1);
                int eq = name.indexOf('=');
                if (eq >= 0) {
                    value = name.mid(eq + 1);
                    name = name.left(eq);
                }
                if (name.isEmpty())
                    error("Missing macro name");
                Macro macro;
                macro.symbols += Symbol(0, PP_IDENTIFIER, value);
                pp.macros.insert(name, macro);

            }
            break;
        case 'U':
            {
                QByteArray macro;
                if (!more) {
                    if (n < argc-1)
                        macro = argv[++n];
                } else
                    macro = opt.mid(1);
                if (macro.isEmpty())
                    error("Missing macro name");
                pp.macros.remove(macro);

            }
            break;
        case 'v':  // version number
            if (more && opt != "version")
                error();
            fprintf(stderr, "Qt Meta Object Compiler version %d (Qt %s)\n",
                    mocOutputRevision, QT_VERSION_STR);
            return 1;
        case 'n': // don't display warnings
            if (ignoreConflictingOptions)
                break;
            if (opt != "nw")
                error();
            moc.displayWarnings = false;
            break;
        case 'h': // help
            if (more && opt != "help")
                error();
            else
                error(0); // 0 means usage only
            break;
        case '-':
            if (more && arg == "--ignore-option-clashes") {
                // -- ignore all following moc specific options that conflict
                // with for example gcc, like -pthread conflicting with moc's
                // -p option.
                ignoreConflictingOptions = true;
                break;
            }
            // fall through
        default:
            error();
        }
    }


    if (autoInclude) {
        int ppos = filename.lastIndexOf('.');
        moc.noInclude = (ppos >= 0
                         && tolower(filename[ppos + 1]) != 'h'
                         && tolower(filename[ppos + 1]) != QDir::separator().toLatin1()
                        );
    }
    if (moc.includeFiles.isEmpty()) {
        if (moc.includePath.isEmpty()) {
            if (filename.size()) {
                if (output.size())
                    moc.includeFiles.append(combinePath(filename, output));
                else
                    moc.includeFiles.append(filename);
            }
        } else {
            moc.includeFiles.append(combinePath(filename, filename));
        }
    }

    if (filename.isEmpty()) {
        filename = "standard input";
        in = stdin;
    } else {
#if defined(_MSC_VER) && _MSC_VER >= 1400
		if (fopen_s(&in, filename.data(), "rb")) {
#else
        in = fopen(filename.data(), "rb");
		if (!in) {
#endif
            fprintf(stderr, "moc: %s: No such file\n", (const char*)filename);
            return 1;
        }
        moc.filename = filename;
    }

    moc.currentFilenames.push(filename);

    // 1. preprocess
    moc.symbols = pp.preprocessed(moc.filename, in);
    fclose(in);

    if (!pp.preprocessOnly) {
        // 2. parse
        moc.parse();
    }

    // 3. and output meta object code

    if (output.size()) { // output file specified
#if defined(_MSC_VER) && _MSC_VER >= 1400
        if (fopen_s(&out, output.data(), "w"))
#else
        out = fopen(output.data(), "w"); // create output file
        if (!out)
#endif
        {
            fprintf(stderr, "moc: Cannot create %s\n", (const char*)output);
            return 1;
        }
    } else { // use stdout
        out = stdout;
    }

    if (pp.preprocessOnly) {
        fprintf(out, "%s\n", composePreprocessorOutput(moc.symbols).constData());
    } else {
        if (moc.classList.isEmpty())
            moc.warning("No relevant classes found. No output generated.");
        else
            moc.generate(out);
    }

    if (output.size())
        fclose(out);

    return 0;
}

QT_END_NAMESPACE

int main(int _argc, char **_argv)
{
    return QT_PREPEND_NAMESPACE(runMoc)(_argc, _argv);
}
예제 #8
0
inline Symbol Symbol::LoadJSON(const std::string &json_str) {
  op_map();
  SymbolHandle handle;
  CHECK_EQ(MXSymbolCreateFromJSON(json_str.c_str(), &(handle)), 0);
  return Symbol(handle);
}
예제 #9
0
inline Symbol Symbol::GetInternals() const {
  SymbolHandle handle;
  CHECK_EQ(MXSymbolGetInternals(GetHandle(), &handle), 0);
  return Symbol(handle);
}
예제 #10
0
MeshGenerator::MeshGenerator() {
    add(Symbol('F').action(forward_draw));
    add(Symbol('G').action(forward_draw));
    add(Symbol('g').action(forward_radius));
    add(Symbol('T').action(tropism));
    add(Symbol('f').action(forward));
    add(Symbol('+').action(turn_left));
    add(Symbol('-').action(turn_right));
    add(Symbol('&').action(pitch_down));
    add(Symbol('^').action(pitch_up));
    add(Symbol('\\').action(roll_left));
    add(Symbol('/').action(roll_right));
    add(Symbol('|').action(turn_around));
    add(Symbol('!').action(decrease_diameter));
    add(Symbol('@').action(decrease_length));
    add(Symbol('#').action(increase_length));
    add(Symbol('\'').action(next_color));
    add(Symbol('`').action(previous_color));
    add(Symbol('"').action(next_color_series));
    add(Symbol('[').startsGroup());
    add(Symbol(']').endsGroup());
    add(Symbol('{').startsGroup().action(begin_polygon));
    add(Symbol('}').endsGroup().action(end_polygon));
}
예제 #11
0
파일: Importer.cpp 프로젝트: Limvot/kraken
Importer::Importer(Parser* parserIn, std::vector<std::string> includePaths, std::string outputNameIn, bool only_parseIn) {
    only_parse = only_parseIn;
	//constructor
    outputName = outputNameIn;

    if (!only_parse) {
        if (mkdir(("./" + outputName).c_str(), 0755)) {
            //std::cerr << "\n\n =====IMPORTER===== \n\n" << std::endl;
            //std::cerr << "Could not make directory " << outputName << std::endl;
        }
    }

	parser = parserIn;
	this->includePaths = includePaths;
	ASTTransformer = new ASTTransformation(this);

	removeSymbols.push_back(Symbol("$NULL$", true));
	removeSymbols.push_back(Symbol("WS", false));
	removeSymbols.push_back(Symbol("\\(", true));
	removeSymbols.push_back(Symbol("\\)", true));
	removeSymbols.push_back(Symbol("var", true));
	removeSymbols.push_back(Symbol("fun", true));

	removeSymbols.push_back(Symbol(";", true));
	removeSymbols.push_back(Symbol("line_end", false));
	removeSymbols.push_back(Symbol("{", true));
	removeSymbols.push_back(Symbol("}", true));
	removeSymbols.push_back(Symbol("(", true));
	removeSymbols.push_back(Symbol(")", true));
	//removeSymbols.push_back(Symbol("import", true));
	removeSymbols.push_back(Symbol("if", true));
	removeSymbols.push_back(Symbol("while", true));
	removeSymbols.push_back(Symbol("__if_comp__", true));
	//removeSymbols.push_back(Symbol("simple_passthrough", true));
	removeSymbols.push_back(Symbol("comp_simple_passthrough", true));
	removeSymbols.push_back(Symbol("def_nonterm", false));
	removeSymbols.push_back(Symbol("obj_nonterm", false));
	removeSymbols.push_back(Symbol("adt_nonterm", false));
	removeSymbols.push_back(Symbol("template", true));
	removeSymbols.push_back(Symbol("\\|", true));
	//removeSymbols.push_back(Symbol("match", true));
    collapseSymbols.push_back(Symbol("case_statement_list", false));
    collapseSymbols.push_back(Symbol("opt_param_assign_list", false));
	collapseSymbols.push_back(Symbol("param_assign_list", false));
	collapseSymbols.push_back(Symbol("opt_typed_parameter_list", false));
	collapseSymbols.push_back(Symbol("opt_parameter_list", false));
	collapseSymbols.push_back(Symbol("identifier_list", false));
	collapseSymbols.push_back(Symbol("adt_option_list", false));
	collapseSymbols.push_back(Symbol("statement_list", false));
	collapseSymbols.push_back(Symbol("parameter_list", false));
	collapseSymbols.push_back(Symbol("typed_parameter_list", false));
	collapseSymbols.push_back(Symbol("unorderd_list_part", false));
	collapseSymbols.push_back(Symbol("if_comp_pred", false));
	collapseSymbols.push_back(Symbol("declaration_block", false));
	collapseSymbols.push_back(Symbol("type_list", false));
	collapseSymbols.push_back(Symbol("opt_type_list", false));
	collapseSymbols.push_back(Symbol("template_param_list", false));
	collapseSymbols.push_back(Symbol("trait_list", false));
	collapseSymbols.push_back(Symbol("dec_type", false));
	//collapseSymbols.push_back(Symbol("pre_reffed", false));
}
예제 #12
0
파일: player.cpp 프로젝트: alinealves/rogue
 Symbol Player::symbol () {
   return Symbol(Black,White,"@");
 }
예제 #13
0
//==========================================================================================================
// Create a DFA from an NFA using the Subset-Construction algorithm
//==========================================================================================================
void DFA::nfa_to_dfa(NFA& nfa) {
    vector<set<int>> epsilon_closures; // Epsilon closures per NFA state
    
    //------------------------------------------------------------------------------------------------------
    // Calculate epsilon-closures for each state in the NFA
    //------------------------------------------------------------------------------------------------------
    for(int i = 0; i < nfa.get_num_states(); ++i) {
        epsilon_closures.push_back(calc_epsilon_closure(i, nfa));     
    }
    
    // Map between DFA state, and a set of NFA states it was constructed from (the index in the vector is the DFA state)
    vector<set<int>> nfa_states;
    nfa_states.push_back(epsilon_closures[0]); // Initial, starting state
    table.push_back(vector<int>(NUM_SYMBOLS, -1)); // Adding the start state
    
    //------------------------------------------------------------------------------------------------------
    // As long as there are new states in the DFA, calcuate the transitions for them, while creating new
    // states if needed
    //------------------------------------------------------------------------------------------------------
    for(int i = 0; i < table.size(); ++i) {
        for(int sym = 0; sym < NUM_SYMBOLS; ++sym) { // For each possible symbol
            
            //----------------------------------------------------------------------------------------------
            // Get the set of reachable NFA states from the current DFA state for the current symbol
            //----------------------------------------------------------------------------------------------
            set<int> reachable_set = nfa.get_rechable_set(nfa_states[i], Symbol(sym));
            for(auto& s: reachable_set) { // Add the epsilon-closure
                reachable_set.insert(epsilon_closures[s].begin(), epsilon_closures[s].end());
            }
            
            if(reachable_set.empty())
                continue;
            
            //----------------------------------------------------------------------------------------------
            // Check if this set already exists as a DFA state
            //----------------------------------------------------------------------------------------------
            int state = table.size();
            for(int j = 0; j < nfa_states.size(); ++j) {
                if(reachable_set == nfa_states[j]) {
                    state = j;
                    break;
                }
            }
            
            table[i][sym] = state; // Add this transition
            if(state == table.size()) { // New state
                nfa_states.push_back(reachable_set);
                table.push_back(vector<int>(NUM_SYMBOLS, -1));
            }
            
        } // for each symbol
    } // for each new state
    
    //------------------------------------------------------------------------------------------------------
    // Mark a state as accepting if any of the NFA states corresponding to it are accepting
    //------------------------------------------------------------------------------------------------------
    accepting.resize(get_num_states(), -1);
    for(int i = 0; i < nfa_states.size(); ++i) {
        for(auto s: nfa_states[i]) {
            if(nfa.accepting[s] >= 0) { 
                if(accepting[i] >= 0)
                    throw string("DFA state contain accepting NFA states with different production rules");
                accepting[i] = nfa.accepting[s];
                break;
            }
        }
    }
} // nfa_to_dfa()
예제 #14
0
Enum::Enum(string s)
{
  symbols.push_back(Symbol(s));
}
예제 #15
0
/**
 * Captures the current stack and updates stack tracking information.
 * optionally stores a user data pointer that the tracker will take ownership of and delete upon reset
 * you must allocate the memory with FMemory::Malloc()
 */
void FStackTracker::CaptureStackTrace(int32 EntriesToIgnore, void* UserData, int32 StackLen, bool bLookupStringsForAliasRemoval)
{
	// Avoid re-rentrancy as the code uses TArray/TMap.
	if( !bAvoidCapturing && bIsEnabled )
	{
		// Scoped true/ false.
		bAvoidCapturing = true;

		// Capture callstack and create CRC.
		int32 Size = (MAX_BACKTRACE_DEPTH + EntriesToIgnore) * sizeof(uint64);
		uint64* FullBackTrace = static_cast<uint64*>(FMemory_Alloca(Size));

		FMemory::Memzero(FullBackTrace, Size);

		FPlatformStackWalk::CaptureStackBackTrace( FullBackTrace, MAX_BACKTRACE_DEPTH + EntriesToIgnore );
		CA_ASSUME(FullBackTrace);

		// Skip first NUM_ENTRIES_TO_SKIP entries as they are inside this code
		uint64* BackTrace = &FullBackTrace[EntriesToIgnore];
		if (StackLen < MAX_BACKTRACE_DEPTH)
		{
			FMemory::Memzero(BackTrace + StackLen, sizeof(uint64) * (MAX_BACKTRACE_DEPTH - StackLen));
		}
		if (bLookupStringsForAliasRemoval)
		{
			for (int32 Index = 0; Index < StackLen; Index++)
			{
				if (BackTrace[Index])
				{
					uint64* Existing = AliasMap.Find(BackTrace[Index]);
					if (Existing)
					{
						BackTrace[Index] = *Existing;
					}
					else
					{
						ANSICHAR AddressInformation[512];
						AddressInformation[0] = 0;
						FPlatformStackWalk::ProgramCounterToHumanReadableString( 1, BackTrace[Index], AddressInformation, ARRAY_COUNT(AddressInformation)-1 );
						FString Symbol(AddressInformation);
						int32 Spot = Symbol.Find(TEXT(" - "));
						if (Spot != INDEX_NONE)
						{
							Symbol = Symbol.RightChop(Spot + 3);
						}
						Existing = StringAliasMap.Find(Symbol);
						if (Existing)
						{
							AliasMap.Add(BackTrace[Index], *Existing);
							BackTrace[Index] = *Existing;
						}
						else
						{
							AliasMap.Add(BackTrace[Index], BackTrace[Index]);
							StringAliasMap.Add(Symbol, BackTrace[Index]);
						}
					}
				}
			}
		}
		uint32 CRC = FCrc::MemCrc_DEPRECATED( BackTrace, MAX_BACKTRACE_DEPTH * sizeof(uint64) );
        
		// Use index if found
		int32* IndexPtr = CRCToCallStackIndexMap.Find( CRC );
        
		if( IndexPtr )
		{
			// Increase stack count for existing callstack.
			CallStacks[*IndexPtr].StackCount++;
			if (UpdateFn)
			{
				UpdateFn(CallStacks[*IndexPtr], UserData);
			}

			//We can delete this since the user gives ownership at the beginning of this call
			//and had a chance to update their data inside the above callback
			if (UserData)
			{
				FMemory::Free(UserData);
			}
		}
		// Encountered new call stack, add to array and set index mapping.
		else
		{
			// Add to array and set mapping for future use.
			int32 Index = CallStacks.AddUninitialized();
			CRCToCallStackIndexMap.Add( CRC, Index );

			// Fill in callstack and count.
			FCallStack& CallStack = CallStacks[Index];
			FMemory::Memcpy( CallStack.Addresses, BackTrace, sizeof(uint64) * MAX_BACKTRACE_DEPTH );
			CallStack.StackCount = 1;
			CallStack.UserData = UserData;
		}

		// We're done capturing.
		bAvoidCapturing = false;
	}
}
예제 #16
0
inline Symbol Symbol::Copy() const {
  SymbolHandle handle;
  CHECK_EQ(MXSymbolCopy(GetHandle(), &handle), 0);
  return Symbol(handle);
}
예제 #17
0
static _finline void cyset(Type_ &function, const char *name, const mach_header_xx *mach) {
    function = reinterpret_cast<Type_>(Symbol(mach, name));
}
예제 #18
0
inline Symbol Symbol::Variable(const std::string &name) { return Symbol(name); }
예제 #19
0
파일: lexer.c 프로젝트: shenchi/mycc
symbol_t readSym(){
    char *s, tch;
    symtype_t i;

	while(isBlank())nextchar();
	if(isAlpha()){
		s = ccstring();
		s = ccstrcat(s,ch);

		nextchar();
		while(isAlpha() || isDigital()){
			s = ccstrcat(s,ch);
			nextchar();
		}
		for(i = CONST; i<=RETURN; i ++)
			if(ccstrcmp(s,keywords[i-1])==0){
				return Symbol(i, 0);
			}
		return Symbol(ID, (int)s);

	}else if(isDigital()){
        return readNumLit(0);
	}else if(ch=='\''){
		nextchar();
		if(isAlpha() || isDigital() || ch=='+' || ch=='-' || ch=='*' || ch=='/'){
			tch = ch;
			nextchar();
			if(ch=='\''){
				nextchar();
				return Symbol(CHARLIT, (int)tch);
			}
		}
		msg(ERR, "a wrong char literal",lineno+1);
	}else if(ch=='\"'){
		nextchar();
		s = ccstring();
		while(ch!='\"' && ch!=EOF){
			s = ccstrcat(s, ch);
			nextchar();
		}
		if(ch!=EOF){
			nextchar();
			return Symbol(STRLIT, (int)s);
		}
		msg(ERR, "a wrong string literal",lineno+1);

	}else if(ch=='+'){
		nextchar();
		//if(isDigital())
        //    return readNumLit(0);
        //else
            return Symbol(PLUS, 0);
	}else if(ch=='-'){
		nextchar();
		//if(isDigital())
        //    return readNumLit(1);
        //else
            return Symbol(MINUS, 0);
	}else if(ch=='*'){
		nextchar();
		return Symbol(MULTI, 0);
	}else if(ch=='/'){
		nextchar();
		return Symbol(DIVIDE, 0);
	}else if(ch=='<'){
		nextchar();
		if(ch=='='){
			nextchar();
			return Symbol(LEQU, 0);
		}else
			return Symbol(LESS, 0);
	}else if(ch=='>'){
		nextchar();
		if(ch=='='){
			nextchar();
			return Symbol(GEQU, 0);
		}else
			return Symbol(GREATER, 0);
	}else if(ch=='!'){
		nextchar();
		if(ch=='='){
			nextchar();
			return Symbol(UNEQU, 0);
		}
		msg(ERR, "unexpected char \'!\'",lineno+1);
	}else if(ch=='='){
		nextchar();
		if(ch=='='){
			nextchar();
			return Symbol(EQU, 0);
		}else
			return Symbol(ASN, 0);
	}else if(ch=='('){
		nextchar();
		return Symbol(LPAREN, 0);
	}else if(ch==')'){
		nextchar();
		return Symbol(RPAREN, 0);
	}else if(ch=='{'){
		nextchar();
		return Symbol(LBRACE, 0);
	}else if(ch=='}'){
		nextchar();
		return Symbol(RBRACE, 0);
	}else if(ch==';'){
		nextchar();
		return Symbol(SEMIC, 0);
	}else if(ch==':'){
		nextchar();
		return Symbol(COLON, 0);
	}else if(ch==','){
		nextchar();
		return Symbol(COMMA, 0);
	}else if(ch==EOF){
		return Symbol(SEOF, 0);
	}

	msg(ERR, "unknown lexer error",lineno+1);
	return 0;
}
예제 #20
0
inline Symbol Symbol::operator[](int index) {
  SymbolHandle out;
  MXSymbolGetOutput(GetHandle(), index, &out);
  return Symbol(out);
}
예제 #21
0
obj eval(obj exp){
ev:	assert(!! exp);
    obj rr,lt, rt;
	switch (exp->type) {
	case tInd:
		return doInd(eval(ult(exp)), ul(eval(urt(exp))));
	case LIST:
		return List2v(evalList(ul(exp)));
	case tArray:
		return map_obj(eval, exp);
	case tAnd:
		return prod_eval(ul(exp), mult);
	case MULT:
		return prod_eval(ul(exp), mult);
	case ARITH:
		return prod_eval(ul(exp), add);
	case POW:
		return prod_eval(ul(exp), power);
	case DIVIDE:
		return prod_eval(ul(exp), divide);
	case tRef:
		return retain(uref(exp));
	case tSymbol:
		if( macromode) {
			if(obj rr = search_assoc(car(macro_env), exp)){
				macromode = false;
				// macro lexical scope should be pushed to the stack here
				rr = exec(rr);
				macromode = true;
				return rr;
			}
		}
		return eval_symbol(exp);
	case tMinus:
		lt = eval(uref(exp));
		rr = uMinus(lt);	// releasing
		if(rr) {release(lt); return rr;}
		static obj symumn = Symbol("-");
		rr = udef_op0(symumn, lt);
		if(rr) {release(lt); return rr;}
		error("uMinus: not defined to that type");
	case tReturn:
		if(! uref(exp)) return encap(tSigRet, nil);
		return  encap(tSigRet, eval(uref(exp)));
	case tBreak:
		return retain(exp);
	case CONDITION:
		return evalCond(exp);
	case tOp:
		if(type(ult(exp)) ==tSymbol) {
			lt = search_assoc(curr_interp->types, ult(exp));
			if(lt) return encap((ValueType)vrInt(lt), eval(urt(exp)));}
		lt = eval(ult(exp));
		push(lt);
		switch(lt->type){
		case tCont:
			assert(0);
		case tSpecial:
			rr = ufn(lt)(urt(exp));
			break;
		case tSyntaxLam:
			rr = macro_exec(lt, urt(exp));
			break;
		case tInternalFn:
        case tClosure:
			rt = eval(urt(exp));
			rr = eval_function(lt, rt);
			break;
        default:
			rt = eval(urt(exp));
			rr = call_fn(mult, lt, rt);
			release(rt);
		}
		release(pop(&is));
		return rr;
	case tClosure:
		assert(0);
	case tCurry:
		return eval_curry(exp, em0(exp));
/*		obj vars = Assoc();
		bind_vars(&vars, em0(exp), em2(exp));
		rr = eval_curry(exp, vars);
		release(vars);
		return rr;
*/	case tArrow:
//		return enclose(exp);
/*		if(macromode){
			if(obj rr = search_assoc(car(macro_env), exp)){
			}
		}
*/ 		return render(tClosure, list3(retain(em0(exp)), retain(em1(exp)), retain(env)));
	case tDefine:
		return func_def(em0(exp), em1(exp), em2(exp));
	case tSyntaxDef:
		let(lfind_var(em0(exp)),  render(tSyntaxLam, list3(retain(em1(exp)), retain(em2(exp)), nil)));
		return nil;
	case tExec:
		return exec(exp);
	case tAssign:
		lt = car(exp);
		if(type(lt)==tOp){
			return func_def(ult(lt), urt(lt), cdr(exp));
		} else if(type(lt)==tMinus){
			static obj symumn = Symbol("-");
			return func_def(symumn, uref(lt), cdr(exp));
		} else return do_assign(lt, eval(cdr(exp)));
	case tIf:
		rr = eval(em0(exp));
		if (type(rr) != INT) error("if: Boolean Expected");
		if (vrInt(rr)) {
			rr = em1(exp);
		} else {
			rr = em2(exp);
		}
		return eval(rr);
	case tWhile:
		for(;;) {
			rr = eval(car(exp));
			if (type(rr) != INT) error("while: Boolean expected");
			if(!vrInt(rr)) break;
			rr = exec(cdr(exp));
			if(rr && type(rr)==tSigRet) return rr;
			if(rr && type(rr)==tBreak) {release(rr); break;}
			if(rr) release(rr);
		}
		return nil;
	default:
		return retain(exp);
	}
}
예제 #22
0
inline Symbol Symbol::Load(const std::string &file_name) {
  op_map();
  SymbolHandle handle;
  CHECK_EQ(MXSymbolCreateFromFile(file_name.c_str(), &(handle)), 0);
  return Symbol(handle);
}
예제 #23
0
ListExpr map_stream_result_type( ListExpr args, Tuple**, OP* )
{
    return list_ostream() << Symbol("tuple") << OP::type( args );
}
예제 #24
0
void Semantic::traverse(Stmt * cur) {
  if (cur->v == Stmt::LIST_T) {
    pushScope();
    traverse(cur->list);
    popScope();
  }
  else if (cur->v == Stmt::IF_T || cur->v == Stmt::WHILE_T) {
    if (cur->v == Stmt::WHILE_T) loops.push(cur);
    Type t = expType(cur->exp);
    traverse(cur->exp);
    if (t.v == Type::INT_T || t.v == Type::CHAR_T) {
      //warning
      pushScope();
      traverse(cur->left);
      popScope();
    }
    else if (t.v == Type::BOOL_T) {
      pushScope();
      traverse(cur->left);
      popScope();
    }
    else
      error("Condition must be of type bool");
    if (cur->v == Stmt::WHILE_T) loops.pop();
  }
  else if (cur->v == Stmt::FOR_T) {
    loops.push(cur);
    pushScope();
    traverse(cur->left);
    Type t = expType(cur->exp);
    traverse(cur->exp);
    if (t.v == Type::INT_T || t.v == Type::CHAR_T) {
      //warning
      pushScope();
      traverse(cur->stmt);
      popScope();
    }
    else if (t.v == Type::BOOL_T) {
      pushScope();
      traverse(cur->stmt);
      popScope();
    }
    else
      error("Condition must be of type bool");
    if (hasDecl(cur->right))
      error("For loop-end statement must not include declarations");
    traverse(cur->right);
    popScope();
    loops.pop();
  }
  else if (cur->v == Stmt::RETURN_T) {
    //check current function return type and compare it with this
    if (!sameType(expType(cur->exp), *getSym(curF).defn->type))
      error("return expression type differs from function " + curF + " signature");
    if (cur->exp != NULL)
      traverse(cur->exp);
  }
  else if (cur->v == Stmt::ASSERT_T) {
    //check argument type to be of bool
    if (!sameType(expType(cur->exp), Type(Type::BOOL_T)))
      error("assert expression type must be bool");
    traverse(cur->exp);
  }
  else if (cur->v == Stmt::ERROR_T) {
    //call error function with argment string
    if (!sameType(expType(cur->exp), Type(Type::STRING_T)))
      error("error argument must be of type string");
    traverse(cur->exp);
  }
  else if (cur->v == Stmt::ASSIGN_T) {
    //check if lhs and rhs same type, ensure rhs and lhs is not a struct
    Type l = lvalType(cur->lval), r = expType(cur->exp);
    traverse(cur->exp);
    
    if (cur->op == "=") {
      if (!sameType(l, r))
	error("lval and expression have different types");
    }
    else if (cur->op == ">>=") {
      if (!(sameType(l, Type(Type::INT_T)) || sameType(l, Type(Type::CHAR_T))))
	error("lval from right shift must be of type int or char");
      if (!sameType(r, Type(Type::INT_T)))
	error("shift ammount must be of type int");
    }
    else if (cur->op == "<<=") {
      if (!(sameType(l, Type(Type::INT_T)) || sameType(l, Type(Type::CHAR_T))))
	error("lval from left shift must be of type int or char");
      if (!sameType(r, Type(Type::INT_T)))
	error("shift ammount must be of type int");
    }
    else if (cur->op == "+=") {
      if (!(sameType(l, Type(Type::INT_T)) || sameType(l, Type(Type::CHAR_T))))
	error("lval from add assign must be of type int or char");
      if (!(sameType(r, Type(Type::INT_T)) || sameType(r, Type(Type::CHAR_T))))
	error("expression from add assign must be of type int or char");
    }
    else if (cur->op == "-=") {
      if (!(sameType(l, Type(Type::INT_T)) || sameType(l, Type(Type::CHAR_T))))
	error("lval from sub assign must be of type int or char");
      if (!(sameType(r, Type(Type::INT_T)) || sameType(r, Type(Type::CHAR_T))))
	error("expression from sub assign must be of type int or char");
    }
    else if (cur->op == "*=") {
      if (!(sameType(l, Type(Type::INT_T)) || sameType(l, Type(Type::CHAR_T))))
	error("lval from mul assign must be of type int or char");
      if (!(sameType(r, Type(Type::INT_T)) || sameType(r, Type(Type::CHAR_T))))
	error("expression from mul assign must be of type int or char");
    }
    else if (cur->op == "/=") {
      if (!(sameType(l, Type(Type::INT_T)) || sameType(l, Type(Type::CHAR_T))))
	error("lval from div assign must be of type int or char");
      if (!(sameType(r, Type(Type::INT_T)) || sameType(r, Type(Type::CHAR_T))))
	error("expression from div assign must be of type int or char");
    }
    else if (cur->op == "%=") {
      if (!(sameType(l, Type(Type::INT_T)) || sameType(l, Type(Type::CHAR_T))))
	error("lval from mod assign must be of type int or char");
      if (!(sameType(r, Type(Type::INT_T)) || sameType(r, Type(Type::CHAR_T))))
	error("expression from mod assign must be of type int or char");
    }
    else if (cur->op == "&=") {
      if (!(sameType(l, Type(Type::INT_T)) || sameType(l, Type(Type::CHAR_T)) || sameType(l, Type(Type::BOOL_T))))
	error("lval from and assign must be of type int or char or bool");
      if (!(sameType(r, Type(Type::INT_T)) || sameType(r, Type(Type::CHAR_T)) || sameType(r, Type(Type::BOOL_T))))
	error("expression from and assign must be of type int or char or bool");
    }
    else if (cur->op == "^=") {
      if (!(sameType(l, Type(Type::INT_T)) || sameType(l, Type(Type::CHAR_T)) || sameType(l, Type(Type::BOOL_T))))
	error("lval from xor assign must be of type int or char or bool");
      if (!(sameType(r, Type(Type::INT_T)) || sameType(r, Type(Type::CHAR_T)) || sameType(r, Type(Type::BOOL_T))))
	error("expression from xor assign must be of type int or char or bool");
    }
    else if (cur->op == "|=") {
      if (!(sameType(l, Type(Type::INT_T)) || sameType(l, Type(Type::CHAR_T)) || sameType(l, Type(Type::BOOL_T))))
	error("lval from or assign must be of type int or char or bool");
      if (!(sameType(r, Type(Type::INT_T)) || sameType(r, Type(Type::CHAR_T)) || sameType(r, Type(Type::BOOL_T))))
	error("expression from or assign must be of type int or char or bool");
    }
  }
  else if (cur->v == Stmt::INC_T) {
    //check if lhs is int or char
    Type l = lvalType(cur->lval);
    if (!(sameType(l, Type(Type::INT_T)) || sameType(l, Type(Type::CHAR_T))))
      error("lval from increment must be of type int or char");
    
  }
  else if (cur->v == Stmt::DEC_T) {
    //check if lhs is int or char
    Type l = lvalType(cur->lval);
    if (!(sameType(l, Type(Type::INT_T)) || sameType(l, Type(Type::CHAR_T))))
      error("lval from decrement must be of type int or char");
    
  }
  else if (cur->v == Stmt::EXP_T) {
    traverse(cur->exp);
  }
  else if (cur->v == Stmt::DECL_T) {
    //declaring a variable
    newSym(vid.back(), Symbol(cur->arg->ID, cur->arg->type));
  }
  else if (cur->v == Stmt::DECLI_T) {
    //declaring and assigning a variable
    newSym(vid.back(), Symbol(cur->arg->ID, cur->arg->type));
  }
  else if (cur->v == Stmt::BREAK_T) {
    //check most recent loop
    if (loops.empty())
      error("break statement does not have a loop");
  }
  else if (cur->v == Stmt::CONT_T) {
    if (loops.empty())
      error("continue statement does not have a loop");
  }
}