aknlayoutcompiler/src/CoreParser.cpp
changeset 0 f58d6ec98e88
child 1 b700e12870ca
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/aknlayoutcompiler/src/CoreParser.cpp	Thu Dec 17 09:14:18 2009 +0200
@@ -0,0 +1,517 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+#include "CoreParser.h"
+#include <sstream>
+#include <iostream>
+using namespace std;
+
+
+ParseResult::ParseResult()
+: iRuleId(0), iStart(0), iEnd(0)
+	{
+	}
+
+bool ParseResult::Matched() const
+	{
+	return iRuleId != 0;
+	}
+
+ParseResult ParseResult::Fail()
+	{
+	ParseResult p;
+	return p;
+	}
+
+
+Parser::Parser()
+: iOp(ENul), iMatch(0), iSub1(0), iSub2(0), iId(-1)
+	{
+	}
+
+Parser::Parser(const char* aMatch)
+: iOp(EExact), iMatch(aMatch), iSub1(0), iSub2(0), iId(-1)
+	{
+	}
+
+Parser::Parser(T0Op aOp)
+: iOp(aOp), iMatch(0), iSub1(0), iSub2(0), iId(-1)
+	{
+	}
+
+Parser::Parser(T1Op aOp, const Parser& aSub)
+: iOp(aOp), iMatch(0), iSub1(&aSub), iSub2(0), iId(-1)
+	{
+	}
+
+Parser::Parser(T2Op aOp, const Parser& aFirst, const Parser& aRest)
+: iOp(aOp), iMatch(0), iSub1(&aFirst), iSub2(&aRest), iId(-1)
+	{
+	}
+
+Parser::Parser(const Parser& aOther)
+	{
+	*this = aOther;
+	}
+
+const Parser& Parser::operator=(const Parser& aOther)
+	{
+	if (this == &aOther)
+		return *this;
+
+	iOp = aOther.iOp;
+	iMatch = aOther.iMatch;
+	iSub1 = 0;
+	iSub2 = 0;
+	iSub1 = aOther.iSub1;
+	iSub2 = aOther.iSub2;
+	iId = aOther.iId;
+//	if (aOther.iSub1)
+//		iSub1 = new Parser(*aOther.iSub1);
+//	if (aOther.iSub2)
+//		iSub2 = new Parser(*aOther.iSub2);
+
+	return *this;
+	}
+
+Parser::~Parser()
+	{
+//	delete iSub1;
+//	delete iSub2;
+	}
+
+Parser Parser::EOS()
+	{
+	return Parser(EEos);
+	}
+
+Parser Parser::Int()
+	{
+	return Parser(EInt);
+	}
+
+Parser Parser::Real()
+	{
+	return Parser(EReal);
+	}
+
+const Parser& Parser::Nul()
+	{
+	static Parser nul(ENul);
+	nul.SetId(0);
+	return nul;
+	}
+
+
+ParseResult Parser::Parse(const std::string& aString) const
+	{
+	vector<Step> stack;
+	stack.push_back(Step(this, 0, -1));
+	TMatchRes res = EContinue;
+	bool done = false;
+
+	while (!stack.empty() && !done)
+		{
+		Step& top = stack.back();
+		int topId = stack.size()-1;
+		switch (res)
+			{
+			case EFail:
+				if (top.iRule->iOp == EAlt && top.iStep < 2)
+					{
+					res = top.iRule->ParseStep(topId, aString, top.iPos, stack);
+					}
+				else if (top.iRule->iOp == EMult && top.iStep < 2)
+					{
+					top.iStep = 2;
+					res = top.iRule->ParseStep(topId, aString, top.iPos, stack);
+					}
+				else
+					{
+					if (top.iParent >= 0 && stack[top.iParent].iRule->iOp == ESeq)
+						stack[top.iParent].iStep--;
+					stack.pop_back();
+					}
+				break;
+
+			case EPass:
+				{
+				int nextSeq = -1;
+				for (int i=stack.size()-1; nextSeq==-1 && i>=0; i--)
+					{
+					if ((stack[i].iRule->iOp == ESeq && stack[i].iStep < 2) || 
+						(stack[i].iRule->iOp == EMult && stack[i].iStep < 3))
+						nextSeq = i;
+					}
+				if (nextSeq >= 0)
+					res = stack[nextSeq].iRule->ParseStep(nextSeq, aString, top.iResult.iEnd, stack);
+				else
+					done = true;
+				break;
+				}
+
+			case EContinue:
+				res = top.iRule->ParseStep(topId, aString, top.iPos, stack);
+				break;
+			}
+		}
+
+	if (done)
+		{
+		for (int i=stack.size()-1; i>=1; i--)
+			{
+			Step& step = stack[i];
+			Step& parent = stack[step.iParent];
+			parent.iResult.iChildren.push_front(step.iResult);
+			if (parent.iResult.iEnd < step.iResult.iEnd)
+				parent.iResult.iEnd = step.iResult.iEnd;
+			}
+
+		return stack[0].iResult;
+		}
+	else
+		return ParseResult::Fail();
+	}
+
+Parser::TMatchRes Parser::ParseStep(int aStepId, const std::string& aString, int aPos, vector<Step>& aStack) const
+	{
+	Step& step = aStack[aStepId];
+	step.iResult.iRuleId = Id();
+	
+	switch (iOp)
+		{
+		case EExact:
+			{
+			string match(iMatch);
+			int mLen = match.size();
+			if (mLen + aPos > aString.size())
+				return EFail;
+			else if (aString.substr(aPos, mLen) != match)
+				return EFail;
+			else
+				step.iResult.iEnd = aPos + mLen;
+			return EPass;
+			}
+
+		case EEos:
+			{
+			if (aPos != aString.size())
+				return EFail;
+			else
+				step.iResult.iEnd = aPos;
+			return EPass;
+			}
+
+		case EInt:
+			{
+			istringstream strm(aString.substr(aPos));
+			int temp;
+			strm >> temp;
+			int len = strm.tellg();
+			if (len >= 0)
+				step.iResult.iEnd = aPos + len;
+			else
+				return EFail;
+			return EPass;
+			}
+
+		case EReal:
+			{
+			istringstream strm(aString.substr(aPos));
+			double temp;
+			strm >> temp;
+			int len = strm.tellg();
+			if (len >= 0)
+				step.iResult.iEnd = aPos + len;
+			else
+				return EFail;
+			return EPass;
+			}
+
+		case ENul:
+			{
+			step.iResult.iChildren.clear();
+			step.iResult.iEnd = aPos;
+			return EPass;
+			}
+
+		case EMult:
+			{
+/*			Step next(iSub1, aPos, aStepId);
+			if (step.iStep == 1)
+				next.iRule = this;
+			else if (step.iStep == 2)
+				next.iRule = &Parser::Nul();
+			step.iStep++;
+			aStack.push_back(next);
+			return EContinue;
+*/
+			return EFail;
+			}
+
+		case ESeq:
+			{
+			Step next(iSub1, aPos, aStepId);
+			if (step.iStep == 1)
+				next.iRule = iSub2;
+			step.iStep++;
+			aStack.push_back(next);
+			return EContinue;
+			}
+
+		case EAlt:
+			{
+			Step next(iSub1, aPos, aStepId);
+			if (step.iStep == 1)
+				next.iRule = iSub2;
+			step.iStep++;
+			aStack.push_back(next);
+			return EContinue;
+			}
+		}
+
+	return EFail;
+	}
+
+int Parser::Id() const
+	{
+	return iId;
+	}
+
+void Parser::SetId(int aId)
+	{
+	iId = aId;
+	}
+
+
+Parser operator|(const Parser& aFirst, const Parser& aRest)
+	{
+	return Parser(Parser::EAlt, aFirst, aRest);
+	}
+
+Parser operator>>(const Parser& aFirst, const Parser& aRest)
+	{
+	return Parser(Parser::ESeq, aFirst, aRest);
+	}
+
+/*Parser operator*(const Parser& aSub)
+	{
+	return Parser(Parser::EMult, aSub);
+	}
+*/
+
+void DoPrint(const ParseResult& res)
+	{
+	cout << res.iRuleId << " " << res.iStart << "..." << res.iEnd << " ";
+	if (res.iChildren.size())
+		{
+		cout << "{ ";
+		for (int i=0; i<res.iChildren.size(); i++)
+			DoPrint(res.iChildren[i]);
+		cout << "} ";
+		}
+	}
+
+void Print(const ParseResult& res)
+	{
+	DoPrint(res);
+	cout << endl;
+	}
+
+int TestParser()
+	{
+	Parser p = Parser("A");
+	ParseResult res;
+	res = p.Parse("A");	Print(res);
+	res = p.Parse("B");	Print(res);
+
+	p = Parser("A") | Parser("B");
+	res = p.Parse("A");	Print(res);
+	res = p.Parse("B");	Print(res);
+	res = p.Parse("AB"); Print(res);
+	res = p.Parse("C");	Print(res);
+
+	p = Parser("A") | Parser("B") | Parser("C");
+	res = p.Parse("A");	Print(res);
+	res = p.Parse("B");	Print(res);
+	res = p.Parse("AB"); Print(res);
+	res = p.Parse("C");	Print(res);
+	res = p.Parse("D");	Print(res);
+
+	p = Parser("A") >> Parser("B");
+	res = p.Parse("A");	Print(res);
+	res = p.Parse("B"); Print(res);
+	res = p.Parse("AB"); Print(res);
+	res = p.Parse("BA"); Print(res);
+	res = p.Parse("C"); Print(res);
+
+	p = Parser("A") >> Parser("B") >> Parser("C");
+	res = p.Parse("A");	Print(res);
+	res = p.Parse("B"); Print(res);
+	res = p.Parse("AB"); Print(res);
+	res = p.Parse("ABC"); Print(res);
+	res = p.Parse("ABCD"); Print(res);
+	res = p.Parse("BAC"); Print(res);
+	res = p.Parse("D"); Print(res);
+
+	p = Parser("A") >> Parser("B") >> Parser("A") >> Parser::EOS();
+	res = p.Parse("A"); Print(res);
+	res = p.Parse("B"); Print(res);
+	res = p.Parse("AB"); Print(res);
+	res = p.Parse("BA"); Print(res);
+	res = p.Parse("ABA"); Print(res);
+	res = p.Parse("ABAB"); Print(res);
+	res = p.Parse("C"); Print(res);
+
+	p = (Parser("A") | Parser("B")) >> Parser("C");
+	res = p.Parse("A");	Print(res);
+	res = p.Parse("B"); Print(res);
+	res = p.Parse("AC"); Print(res);
+	res = p.Parse("BC"); Print(res);
+	res = p.Parse("BA"); Print(res);
+	res = p.Parse("C"); Print(res);
+	res = p.Parse("CC"); Print(res);
+
+	p = Parser("A") >> (Parser("B") | Parser("BB")) >> Parser::EOS();
+	res = p.Parse("A"); Print(res);
+	res = p.Parse("AB"); Print(res);
+	res = p.Parse("ABB"); Print(res);
+	res = p.Parse("ABBB"); Print(res);
+
+	p = Parser("A") >> (Parser("B") | Parser("C")) >> (Parser("D") | Parser("E")) >> Parser::EOS();
+	res = p.Parse("A"); Print(res);
+	res = p.Parse("AB"); Print(res);
+	res = p.Parse("AC"); Print(res);
+	res = p.Parse("AD"); Print(res);
+	res = p.Parse("AE"); Print(res);
+	res = p.Parse("ABD"); Print(res);
+	res = p.Parse("ABE"); Print(res);
+	res = p.Parse("ACD"); Print(res);
+	res = p.Parse("ACE"); Print(res);
+	res = p.Parse("ADB"); Print(res);
+	res = p.Parse("AEB"); Print(res);
+	res = p.Parse("ADC"); Print(res);
+	res = p.Parse("AEC"); Print(res);
+	res = p.Parse("ABDB"); Print(res);
+	res = p.Parse("ABEC"); Print(res);
+	res = p.Parse("ACDE"); Print(res);
+	res = p.Parse("ACEE"); Print(res);
+
+	p = Parser("A") | Parser("B");
+	Parser q = p >> p;
+	cout << p.Id() << endl;
+	cout << q.Id() << endl;
+	res = q.Parse("A"); Print(res);
+	res = q.Parse("B"); Print(res);
+	res = q.Parse("AA"); Print(res);
+	res = q.Parse("AB"); Print(res);
+	res = q.Parse("BA"); Print(res);
+	res = q.Parse("BB"); Print(res);
+	res = q.Parse("AC"); Print(res);
+	res = q.Parse("CA"); Print(res);
+
+	q = Parser("A") >> p;
+	p = q | Parser::Nul();
+	res = p.Parse("A"); Print(res);
+	res = p.Parse("B"); Print(res);
+	res = p.Parse("AA"); Print(res);
+	res = p.Parse(""); Print(res);
+
+	Parser r = Parser::Nul();
+	q = Parser("A") >> r;
+	r = q | Parser::Nul();
+	p = r >> Parser::EOS();
+	res = p.Parse("A"); Print(res);
+	res = p.Parse("B"); Print(res);
+	res = p.Parse("AA"); Print(res);
+	res = p.Parse("AAB"); Print(res);
+	res = p.Parse(""); Print(res);
+
+	p = Parser("B") >> r >> Parser("B");
+	res = p.Parse("B"); Print(res);
+	res = p.Parse("BB"); Print(res);
+	res = p.Parse("BAB"); Print(res);
+	res = p.Parse("BAAB"); Print(res);
+	res = p.Parse("BAAAB"); Print(res);
+
+	p = r >> Parser("AAB");
+	res = p.Parse("B"); Print(res);
+	res = p.Parse("AB"); Print(res);
+	res = p.Parse("AAB"); Print(res);
+	res = p.Parse("AAAB"); Print(res);
+	res = p.Parse("AAAAB"); Print(res);
+
+	p = Parser::Int();
+	res = p.Parse("1"); Print(res);
+	res = p.Parse("a"); Print(res);
+	res = p.Parse("123"); Print(res);
+	res = p.Parse("123ab"); Print(res);
+	res = p.Parse(""); Print(res);
+	
+	p = Parser::Real();
+	res = p.Parse("1"); Print(res);
+	res = p.Parse("1.0"); Print(res);
+	res = p.Parse(".01"); Print(res);
+	res = p.Parse("1e9"); Print(res);
+	res = p.Parse("a"); Print(res);
+	res = p.Parse("123"); Print(res);
+	res = p.Parse("123ab"); Print(res);
+	res = p.Parse(""); Print(res);
+	
+
+	// unsupported *
+/*	p = *Parser("A");
+	res = p.Parse("A"); Print(res);
+	res = p.Parse("B"); Print(res);
+	res = p.Parse("AA"); Print(res);
+	res = p.Parse(""); Print(res);
+
+	p = *Parser("A") >> Parser::EOS();
+	res = p.Parse("A"); Print(res);
+	res = p.Parse("B"); Print(res);
+	res = p.Parse("AA"); Print(res);
+	res = p.Parse("AAB"); Print(res);
+	res = p.Parse(""); Print(res);
+
+	p = Parser("B") >> *Parser("A") >> Parser("B");
+	res = p.Parse("B"); Print(res);
+	res = p.Parse("BB"); Print(res);
+	res = p.Parse("BAB"); Print(res);
+	res = p.Parse("BAAB"); Print(res);
+	res = p.Parse("BAAAB"); Print(res);
+
+	p = *Parser("A") >> Parser("AB");
+	res = p.Parse("B"); Print(res);
+	res = p.Parse("AB"); Print(res);
+	res = p.Parse("AAB"); Print(res);
+	res = p.Parse("AAAB"); Print(res);
+	res = p.Parse("AAAAB"); Print(res);
+*/
+	return 0;
+	}
+/*
+Parser p = Parser("A") >> (Parser("B") | Parser("C")) >> (Parser("D") | Parser("E")) >> Parser("F");
+Parser q = p | (p >> q);
+int TestFormulaTreeNode()
+	{
+
+	ParseResult res;
+	res = q.Parse("ACEFACEF");	Print(res);
+	return 0;
+	}
+*/
+// note, uncomment this line to execute test code
+//int x = TestParser();