示例#1
0
bool CalcExpr(const string & expr, int a1, int a2, Token & result)
{
    map<string,TokenVector>::iterator its=cache.find(expr);
    
    if(its==cache.end())
    {
        TokenVector a;
        bool r = ParseExpr(expr, a);
        if (!r) return false;
        
        TokenVector b;
        r = ConvertExpr(a, b);
        if (!r) return false;
        
        cache.insert(std::map<string,TokenVector> :: value_type(expr,b));
    }
    
	

    map<string,TokenVector>::iterator it=cache.find(expr);
    
	TokenVector input;
	Token x;
	x.type = INT;
	x.value.i = a1;
	input.push_back(x);
	x.value.i = a2;
	input.push_back(x);

	return CalcExpr(input, it->second, result);
}
    void VerifyEscapedOctalDigits(unsigned int expectedToken, wstring octalDigitStringPrefix, wstring octalDigitStringSuffix)
    {
        vector<wstring> escapedOctalItems;

        //Test we recognize the basic set of Octal digits (0-7) (we use '8' below in make_pair as the range is the standard STL style range where it is
        //up to, but not including, the 'end' position).
        PopulateASCIICharacterCodes(escapedOctalItems, make_pair(static_cast<int>(L'0'), static_cast<int>(L'8')), wstring(L"\\"));

        //Test we recognize 1, 2 and 3 digit octal strings (obvioulsy exhustive tests for all possible octal numbers from 0-777 would take forever to run
        escapedOctalItems.push_back(wstring(L"\\1"));
        escapedOctalItems.push_back(wstring(L"\\11"));
        escapedOctalItems.push_back(wstring(L"\\111"));

        for_each(escapedOctalItems.begin(), escapedOctalItems.end(),
                 [expectedToken, &octalDigitStringPrefix, &octalDigitStringSuffix]
                 (const wstring& refStringLit) -> void
                 {
                     wstring toLex = octalDigitStringPrefix + refStringLit + octalDigitStringSuffix;

                     TokenVector expectedTokens;
                     expectedTokens.push_back(make_pair(expectedToken, toLex));

                     VerifyLex(toLex, expectedTokens);
                 });
    }
示例#3
0
void PrintTokenVector(const TokenVector & tokens)
{
	TokenVector::const_iterator it = tokens.begin();
	for (; it != tokens.end(); ++it)
	{
		PrintToken(*it);
	}
}
float similarity(const TokenVector& lv, const TokenVector& rv)
{
    if (lv.size() != rv.size())
    {
        return -1;
    }
    float sim = 0.0;
    float lsum = 0.0;
    float rsum = 0.0;
    for (std::size_t i = 0; i < lv.size(); ++i)
    {
        sim += lv[i] * rv[i];
        lsum += lv[i];
        rsum += rv[i];
    }
    return sim / lsum/ rsum;
}
    void VerifyEscapedControlCodes(unsigned int expectedToken, wstring codeStringPrefix, wstring codeStringSuffix)
    {
        vector<wstring> controlEscapeStringLiteralItems;
        PopulateASCIICharacterCodes(controlEscapeStringLiteralItems, make_pair(64, 96), wstring(L"\\^"));

        for_each(controlEscapeStringLiteralItems.begin(), controlEscapeStringLiteralItems.end(),
                 [expectedToken, &codeStringPrefix, &codeStringSuffix]
                 (const wstring& refStringLit) -> void
                 {
                     wstring toLex = codeStringPrefix + refStringLit + codeStringSuffix;
                 
                     TokenVector expectedTokens;
                     expectedTokens.push_back(make_pair(expectedToken, toLex));
                 
                     VerifyLex(toLex, expectedTokens);
                 });
    }
    void VerifyLex(const wstring& refToLex, const TokenVector& expectedTokens, bool shouldSucceed /*= true*/)
    {
        wchar_t const* first = refToLex.c_str();
        wchar_t const* last = first + refToLex.size();

        TokenVector actualTokens;
        auto cur = g_lexer.begin(first, last);
        auto end = g_lexer.end();

        for(; cur != end && cur->is_valid() ; ++cur)
        {
            try
            {
                actualTokens.push_back(make_pair(cur->id(), wstring(cur->value().begin(), cur->value().end())));
            }
            catch(const std::bad_alloc&)
            {
                break;
            }
        }

        const bool lexingSucceeded = (cur == end);

        const bool lexResultAsExpected = lexingSucceeded == shouldSucceed;

        //Kind of goofy to have to do it this way but the unit test stuff is not set up to output wstrings :(
        if(!lexResultAsExpected)
        {
            wcout << endl << L"Lexing was expected to " << (shouldSucceed ? L"pass" : L"fail") << L"but it " << (shouldSucceed ? L"failed" : L"passed") << L" with input '" << refToLex << L"'" << endl;
        }
        BOOST_CHECK( lexResultAsExpected );

        if(shouldSucceed)
        {            
            const bool sizeMatches = actualTokens.size() == expectedTokens.size();
            if(!sizeMatches)
            {
                wcout << endl << L"Expected lexing to result in " << expectedTokens.size() << L" but it actually resulted in " << actualTokens.size() << L" tokens." << endl;
            }
            BOOST_CHECK( sizeMatches );

            //avoid annoying signed/unsigned mismatch or relying on the fact that ::size_type is == size_t
            typedef decltype(actualTokens.size()) IndexType;

            for(IndexType i = 0 ; i < actualTokens.size() ; ++i)
            {
                auto actual = actualTokens[i];
                auto expected = expectedTokens[i];

                const bool areEqual = (actual == expected);
                if(!areEqual)
                {
                    wcout << endl << L"Expected token '" << expected.second + L"' (" << expected.first << "), but got '" << actual.second << L"' (" << actual.first << L") at token index " << i << endl;
                }

                BOOST_CHECK( areEqual );
            }
        }
    }
示例#7
0
   void PSU1Rules::Detect(const TokenVector& tv)
   {
      for(unsigned int i=0; i<tv.size(); ++i)
      {
         gKey.Process(tv[i]);
         t1Key.Process(tv[i]);
         t2Key.Process(tv[i]);
      }

      const double bauda = any_cast<double>(param::FindParameter(t1Key.GetTupleRef(), "bauda").value);

      for(unsigned int i=0; i<tv.size(); ++i)
      {
         trKey.Process(tv[i],bauda);
         txaKey.Process(tv[i],bauda);
         codeKey.Process(tv[i]);
         saKey.Process(tv[i]);
      }
   }
示例#8
0
AssemblerResult Assembler::tokenize(const char* infile)
{
    std::ifstream asmfile(infile);

    if (asmfile.is_open())
    {
        int lineNo = 1;
        std::string line;
        while (std::getline(asmfile, line))
        {
      
            // check if the line contains an include statement
            
            char* writeable = strdup(line.c_str()); 

            char* token = strtok(writeable, " \t");

            std::string tok;

            if (token != NULL)
            {
        
                for (int i = 0; i < strlen(token) ; i ++)
                    tok.push_back(std::toupper(token[i]));

                if (tok == std::string("#INCLUDE"))
                {  

                    char *fname = strtok(NULL, "\"\'");

                    //std::cout << fname << std::endl;                 

                    // Recurse
                    AssemblerResult res = tokenize(fname);

                    free(writeable);

                    if (res != ASSEMBLER_OK)
                        return res;

                    continue;

                }

            }

            free(writeable);

            // Else, tokenise the line
 
            TokenVector*    tv = new TokenVector();

            AssemblerResult res = tv->tokenize(std::string(infile), lineNo, line);

            if (res != ASSEMBLER_OK)
            {
                return ASSEMBLER_ERROR;
            }
    
            m_lineTokens.push_back(tv); 
            lineNo ++;
        }

    } 
    else
    {
        std::cout << "Error opening file: " << infile << std::endl;
        return ASSEMBLER_ERROR_FILENOTFOUND;
    }    

    return ASSEMBLER_OK; 
}
示例#9
0
// 逆波兰式计算求值
bool CalcExpr(const TokenVector & input, const TokenVector & expr, Token & result)
{
	TokenStack stack;

    
	TokenVector::const_iterator it = expr.begin();
	for (; it != expr.end(); ++it)
	{
		if (it->type == INT || it->type == FLOAT || it->type == BOOL)
		{
			stack.push(*it);
		}
		else if (it->type == ARG)
		{
			if (it->value.index >= input.size()) return false;
			const Token & a = input[it->value.index];
			if (a.type == INT || a.type == FLOAT || a.type == BOOL)
			{
				stack.push(a);
			}
			else
			{
				return false;
			}
		}
		else if (it->type == RAND)
		{
			Token a;
			a.type = INT;
			a.value.i = rand();
			stack.push(a);
		}
		else if (it->type == OP)
		{
			if (stack.size() < 2) return false;
			Token a = stack.top();
			stack.pop();
			Token b = stack.top();
			stack.pop();
			Token c;
			if (GetValue(it->value.op, b, a, c))
			{
				stack.push(c);
			}
			else
			{
				return false;
			}
		}
	}

	if (!stack.empty())
	{
		result = stack.top();
		return true;
	}
	else
	{
		return false;
	}
}
示例#10
0
// 词法分析,解析表达式
bool ParseExpr(const string & expr, TokenVector & tokens)
{
	// 表达式的解析较简单,就不用状态机了,直接一个一个解析。。。
	int i = 0;
	Token token;
	string buffer;
	tokens.clear();
	while (i < expr.length())
	{
		// 空白跳过
		if (isblank(expr[i]))
		{
			++i;
			continue;
		}

		// 单个字符的操作符和括号
		if (expr[i] == '+' ||
			expr[i] == '-' ||
			expr[i] == '*' ||
			expr[i] == '/' ||
			expr[i] == '%' ||
			expr[i] == '^' ||
			expr[i] == '(' ||
			expr[i] == ')')
		{
			token.type = OP;
			if (expr[i] == '+') token.value.op = ADD;
			else if (expr[i] == '-') token.value.op = SUB;
			else if (expr[i] == '*') token.value.op = MUL;
			else if (expr[i] == '/') token.value.op = DIV;
			else if (expr[i] == '%') token.value.op = MOD;
			else if (expr[i] == '^') token.value.op = POW;
			else if (expr[i] == '(') token.value.op = LEFT;
			else if (expr[i] == ')') token.value.op = RIGHT;

			tokens.push_back(token);

			++i;
			continue;
		}
		// 整数或浮点数
		else if (isdigit(expr[i]))
		{
			buffer.clear();
			buffer += expr[i++];
			bool point = false;

			while (i < expr.length())
			{
				if (isdigit(expr[i]))
				{
					buffer += expr[i++];
				}
				else if (expr[i] == '.' && !point)
				{
					buffer += expr[i++];
					point = true;
				}
				else
				{
					break;
				}
			}
			if (point)
			{
				token.type = FLOAT;
				token.value.f = strtof(buffer.c_str(), NULL);
			}
			else
			{
				token.type = INT;
				token.value.i = strtoul(buffer.c_str(), NULL, 0);

			}
			tokens.push_back(token);
		}
		// 随机数
		else if (expr[i] == 'r')
		{
			token.type = RAND;
			token.value.i = 0;
			tokens.push_back(token);
			++i;
		}
		// 参数
		else if (expr[i] == 'x')
		{
			++i;
			buffer.clear();

			while (i < expr.length() && isdigit(expr[i]))
			{
				buffer += expr[i];
				++i;
			}
			if (buffer.empty())
			{
				return false;
			}

			token.type = ARG;
			token.value.index = strtoul(buffer.c_str(), NULL, 0);
			tokens.push_back(token);
			continue;
		}
		// > 或 >=
		else if (expr[i] == '>')
		{
			token.type = OP;
			++i;
			if (i < expr.length() && expr[i] == '=')
			{
				token.value.op = GE;
				++i;
			}
			else
			{
				token.value.op = GT;
			}
			tokens.push_back(token);
		}
		// < 或 <=
		else if (expr[i] == '<')
		{
			token.type = OP;
			++i;
			if (i < expr.length() && expr[i] == '=')
			{
				token.value.op = LE;
				++i;
			}
			else
			{
				token.value.op = LT;
			}
			tokens.push_back(token);
		}
		// ==
		else if (i + 1 < expr.length() && expr[i] == '=' && expr[i + 1] == '=')
		{
			token.type = OP;
			token.value.op = EQ;
			tokens.push_back(token);
			i += 2;
		}
		// !=
		else if (i + 1 < expr.length() && expr[i] == '!' && expr[i + 1] == '=')
		{
			token.type = OP;
			token.value.op = NE;
			tokens.push_back(token);
			i += 2;
		}
		// &&
		else if (i + 1 < expr.length() && expr[i] == '&' && expr[i + 1] == '&')
		{
			token.type = OP;
			token.value.op = AND;
			tokens.push_back(token);
			i += 2;
		}
		// ||
		else if (i + 1 < expr.length() && expr[i] == '|' && expr[i + 1] == '|')
		{
			token.type = OP;
			token.value.op = OR;
			tokens.push_back(token);
			i += 2;
		}
		else
		{
			return false;
		}
	}

	return true;
}
示例#11
0
// 把解析好的表达式转换成逆波兰式
bool ConvertExpr(const TokenVector & input, TokenVector & output)
{
	TokenStack stack;
	output.clear();

	TokenVector::const_iterator it = input.begin();
	for (; it != input.end(); ++it)
	{
		if (it->type == OP)
		{
			// 左括号,直接压进操作符栈
			if (it->value.op == LEFT)
			{
				stack.push(*it);
			}
			// 右括号,从栈里弹出操作符,直到碰到右括号
			else if (it->value.op == RIGHT)
			{
				bool find_left = false;
				while (!stack.empty())
				{
					if (stack.top().value.op == LEFT)
					{
						find_left = true;
						stack.pop();
						break;
					}
					else
					{
						output.push_back(stack.top());
						stack.pop();
					}
				}
				if (!find_left) return false;
			}
			// 其它操作符,和栈顶操作符比较优先级
			else
			{
				while (!stack.empty() && stack.top().value.op != LEFT &&
					OPPriority(stack.top().value.op) >= OPPriority(it->value.op))
				{
					output.push_back(stack.top());
					stack.pop();
				}

				stack.push(*it);
			}
		}
		// 非操作符直接输出
		else
		{
			output.push_back(*it);
		}
	}

	while (!stack.empty())
	{
		output.push_back(stack.top());
		stack.pop();
	}

	return true;
}
示例#12
0
/**
  * Nastavi svuj stav podle vstupniho XML, ktere parsuje.
  *
  * @param xml vstupni XML se stavem simulace
  *
  * @return true pokud se podarilo nastavit stav, jinak false
  */
bool SimState::setState(QString xml)
{
    //inicializuji hodnoty
    places.clear();
    transits.clear();
    places_id.clear();
    transits_id.clear();

    QString errorStr;
    int errorLine;
    int errorColumn;

    QDomDocument document;
    if (!document.setContent(xml,&errorStr,&errorLine,&errorColumn)) { //proparsuju XML
        qCritical() << "Error during parsing xml on line: " << errorLine << ", column: " << errorColumn;
        return false;
    }

    QDomElement root = document.documentElement();

    if (root.tagName() != "petrinet") { //nejedna se petriho sit
        qCritical() << "Error during parsing xml, not valid";
        return false;
    }

    //nactu informace o siti
    author = root.attribute("author");
    name = root.attribute("name");
    version = root.attribute("version").toInt();
    info = root.attribute("info");

    //iteruji nad misty
    QDomElement xml_places = root.firstChildElement("places");
    QDomElement one_place = xml_places.firstChildElement("place");

    while (!one_place.isNull()) {
        TokenVector tokens;
        //projdu vsechny tokeny
        QDomElement one_token = one_place.firstChildElement("token");
        while (!one_token.isNull()) {
            pntype token = one_token.text().toInt();
            tokens.push_back(token);
            one_token = one_token.nextSiblingElement("token");
        }
        //vytvorim nove misto, naplnim ho
        PNPlace *place = new PNPlace(one_place.attribute("posx"),one_place.attribute("posy")
                                     ,one_place.attribute("id"),tokens);
        places.push_back(place); //a zapisu do vektoru mist
        places_id[one_place.attribute("id")] = place; //zapisu jeho ID
        one_place = one_place.nextSiblingElement("place");
    }

    //iteruji nad prechody
    QDomElement xml_trans = root.firstChildElement("transitions");
    QDomElement one_trans = xml_trans.firstChildElement("transition");

    while (!one_trans.isNull()) {
        StringToPnplaceMap in_names;
        StringToPnplaceMap out_names;
        ConstraintVector constraints;

        //nejdriv inicializuji vstupni mista
        QDomElement one_element = one_trans.firstChildElement("inplace");
        while (!one_element.isNull()) {
            bool isNum = false;
            one_element.attribute("name").toInt(&isNum); //vstupni misto je konstanta
            if (isNum) {
                //pridam omezeni prechod == konstanta
                in_names[one_element.attribute("name")] = places_id[one_element.text()];
                constraints.push_back(new Constraint(one_element.attribute("name"),OP_EQ,one_element.attribute("name").toInt()));
            } else {
                in_names[one_element.attribute("name")] = places_id[one_element.text()]; //uchovam ukazatel na vstupni misto
            }
            one_element = one_element.nextSiblingElement("inplace");
        }

        //pote udelam to stejne s vystupnimi misty
        one_element = one_trans.firstChildElement("outplace");
        while (!one_element.isNull()) {
            out_names[one_element.attribute("name")] = places_id[one_element.text()];
            one_element = one_element.nextSiblingElement("outplace");
        }

        //pak iteruji nad omezenimi
        QDomElement one_cond = one_trans.firstChildElement("constraint");
        while (!one_cond.isNull()) {
            Constraint *cond;
            if (one_cond.attribute("type") == "const") { //druha hodnota je konstanta
                cond = new Constraint(one_cond.attribute("var1"),one_cond.attribute("op").toInt(),one_cond.attribute("const").toInt());
            } else { //druha hodnota je promenna
                cond = new Constraint(one_cond.attribute("var1"),one_cond.attribute("op").toInt(),one_cond.attribute("var2"));
            }
            constraints.push_back(cond); //ulozim omezeni
            one_cond = one_cond.nextSiblingElement("constraint");
        }

        //nakonec iteruji nad operacemi
        OutputOperations operations;
        QDomElement one_op = one_trans.firstChildElement("operation");
        while (!one_op.isNull()){
            OneOut oneout;
            oneout.output = one_op.attribute("output");
            QDomElement one_operation = one_op.firstChildElement();
            //iteruji nad jednou vstupni operaci
            while(!one_operation.isNull()) {
                Operation op;
                if (one_operation.tagName() == "plus") {
                    op.op = ADD;
                } else {
                    op.op = SUB;
                }
                op.var = one_operation.attribute("id");
                oneout.operations.push_back(op);
                one_operation = one_operation.nextSiblingElement();
            }
            operations.push_back(oneout);
            one_op = one_op.nextSiblingElement("operation");
        }

        //vytvorim novy prechod a naplnim hodnotami
        PNTrans *trans = new PNTrans(one_trans.attribute("posx"), one_trans.attribute("posy"),
                                     one_trans.attribute("id"), constraints, in_names, out_names, operations);
        transits_id[one_trans.attribute("id")] = trans;
        transits.push_back(trans); //ulozim do vektoru mist
        one_trans = one_trans.nextSiblingElement("transition");
    }

    return true;
}
示例#13
0
/**
  * Vrati XML se stavem simulace.
  *
  * @return XML se stavem simulace
  */
QString SimState::getState()
{
    QString result; //vysledne XML
    QXmlStreamWriter doc(&result);
    doc.setAutoFormatting(true);
    doc.writeStartDocument();

    doc.writeStartElement("petrinet");

    //zapisi informace o siti
    doc.writeAttribute("author",author);
    doc.writeAttribute("name",name);
    doc.writeAttribute("version",QString::number(version));
    doc.writeAttribute("info",info);

    //nejprve zapisi mista
    doc.writeStartElement("places");

    PlaceVector::iterator pit;

    for (pit = places.begin(); pit != places.end(); pit++) {
        //zapisi misto a informace o nem
        doc.writeStartElement("place");

        PNPlace *place = (*pit);
        doc.writeAttribute("id",place->id);
        doc.writeAttribute("posx",place->x);
        doc.writeAttribute("posy",place->y);

        TokenVector::iterator tit;
        TokenVector tokens = place->getTokens();

        //zapisi tokeny
        for (tit = tokens.begin(); tit < tokens.end(); tit++) {
            doc.writeTextElement("token",QString::number(*tit));
        }

        doc.writeEndElement();
    }

    doc.writeEndElement();

    //pote zapisi prechody
    doc.writeStartElement("transitions");

    TransVector::iterator trit;

    for (trit = transits.begin(); trit != transits.end(); trit++) {
        doc.writeStartElement("transition");

        //zapisi informace o prechodu
        PNTrans *transit = (*trit);
        doc.writeAttribute("id",transit->id);
        doc.writeAttribute("posx",transit->x);
        doc.writeAttribute("posy",transit->y);

        ConstraintVector::iterator cvit;
        for (cvit = transit->constraints.begin(); cvit != transit->constraints.end(); cvit++) {
            //zapisi podminku
            Constraint *constraint = (*cvit);

            bool isNum = false;
            constraint->first.toInt(&isNum);

            if (isNum) continue;

            doc.writeEmptyElement("constraint");

            if (constraint -> type == TYPENONE) {
                doc.writeAttribute("type","none");
            } else if (constraint -> type == TYPEANYTHING) {
                doc.writeAttribute("type","anything");
            } else {
                doc.writeAttribute("var1",constraint->first);
                doc.writeAttribute("op",QString::number(int(constraint->op)));
                if (constraint -> type == TYPEVAR) {
                    doc.writeAttribute("type","var");
                    doc.writeAttribute("var2",constraint->second_var);
                } else if (constraint -> type == TYPECONST) {
                    doc.writeAttribute("type","const");
                    doc.writeAttribute("const",QString::number(constraint->second_const));
                }
            }

        }

        //zapisi vstupni a vystupni mista prechodu
        StringToPnplaceMap::iterator placeit;

        for (placeit = transit->in_names.begin(); placeit != transit->in_names.end(); placeit++) {
            doc.writeStartElement("inplace");
            PNPlace *place = (*placeit).second;
            doc.writeAttribute("name",(*placeit).first);
            doc.writeCharacters(place->id);
            doc.writeEndElement();
        }

        for (placeit = transit->out_names.begin(); placeit != transit->out_names.end(); placeit++) {
            doc.writeStartElement("outplace");
            doc.writeAttribute("name",(*placeit).first);
            PNPlace *place = (*placeit).second;
            doc.writeCharacters(place->id);
            doc.writeEndElement();
        }

        OutputOperations::iterator oit;

        //nakonec zapisi operace
        for (oit = transit->operations.begin(); oit != transit->operations.end(); oit++) {
            doc.writeStartElement("operation");
            doc.writeAttribute("output",(*oit).output);
            OperationVector::iterator opit;

            //a jednotlive kroky dane operace
            for (opit = (*oit).operations.begin(); opit != (*oit).operations.end(); opit++) {
                Operation operation = (*opit);
                if (operation.op == ADD) doc.writeEmptyElement("plus");
                else if (operation.op == SUB) doc.writeEmptyElement("minus");
                else {
                    qCritical() << "Error: unknown operation during saving XML";
                }
                doc.writeAttribute("id",operation.var);
            }

            doc.writeEndElement();
        }

        doc.writeEndElement();
    }

    doc.writeEndElement();

    doc.writeEndElement();

    doc.writeEndDocument();

    return result;
}