summaryrefslogtreecommitdiff
path: root/starmath/source/parse.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'starmath/source/parse.cxx')
-rw-r--r--starmath/source/parse.cxx122
1 files changed, 95 insertions, 27 deletions
diff --git a/starmath/source/parse.cxx b/starmath/source/parse.cxx
index 598ec121611b..803f97425a6d 100644
--- a/starmath/source/parse.cxx
+++ b/starmath/source/parse.cxx
@@ -38,32 +38,6 @@
using namespace ::com::sun::star::i18n;
-
-SmToken::SmToken()
- : eType(TUNKNOWN)
- , cMathChar('\0')
- , nGroup(TG::NONE)
- , nLevel(0)
- , nRow(0)
- , nCol(0)
-{
-}
-
-SmToken::SmToken(SmTokenType eTokenType,
- sal_Unicode cMath,
- const char* pText,
- TG nTokenGroup,
- sal_uInt16 nTokenLevel)
- : aText(OUString::createFromAscii(pText))
- , eType(eTokenType)
- , cMathChar(cMath)
- , nGroup(nTokenGroup)
- , nLevel(nTokenLevel)
- , nRow(0)
- , nCol(0)
-{
-}
-
//Definition of math keywords
const SmTokenTableEntry aTokenTable[] =
{
@@ -123,6 +97,7 @@ const SmTokenTableEntry aTokenTable[] =
{ "drarrow" , TDRARROW, MS_DRARROW, TG::Standalone, 5},
{ "emptyset" , TEMPTYSET, MS_EMPTYSET, TG::Standalone, 5},
{ "equiv", TEQUIV, MS_EQUIV, TG::Relation, 0},
+ { "evaluate", TEVALUATE, '\0', TG::NONE, 0},
{ "exists", TEXISTS, MS_EXISTS, TG::Standalone, 5},
{ "exp", TEXP, '\0', TG::Function, 5},
{ "fact", TFACT, MS_FACT, TG::UnOper, 5},
@@ -130,7 +105,7 @@ const SmTokenTableEntry aTokenTable[] =
{ "font", TFONT, '\0', TG::FontAttr, 5},
{ "forall", TFORALL, MS_FORALL, TG::Standalone, 5},
{ "fourier", TFOURIER, MS_FOURIER, TG::Standalone, 5},
- { "frac", TFRAC, '\0', TG::NONE, 0},
+ { "frac", TFRAC, '\0', TG::NONE, 5},
{ "from", TFROM, '\0', TG::Limit, 0},
{ "func", TFUNC, '\0', TG::Function, 5},
{ "ge", TGE, MS_GE, TG::Relation, 0},
@@ -150,6 +125,7 @@ const SmTokenTableEntry aTokenTable[] =
{ "int", TINT, MS_INT, TG::Oper, 5},
{ "intd", TINTD, MS_INT, TG::Oper, 5},
{ "intersection", TINTERSECT, MS_INTERSECT, TG::Product, 0},
+ { "it", TIT, '\0', TG::Product, 0},
{ "ital", TITALIC, '\0', TG::FontAttr, 5},
{ "italic", TITALIC, '\0', TG::FontAttr, 5},
{ "lambdabar" , TLAMBDABAR, MS_LAMBDABAR, TG::Standalone, 5},
@@ -174,6 +150,8 @@ const SmTokenTableEntry aTokenTable[] =
{ "lllint", TLLLINT, MS_LLLINT, TG::Oper, 5},
{ "ln", TLN, '\0', TG::Function, 5},
{ "log", TLOG, '\0', TG::Function, 5},
+ { "lrline", TLRLINE, MS_VERTLINE, TG::LBrace | TG::RBrace, 5},
+ { "lrdline", TLRDLINE, MS_VERTLINE, TG::LBrace | TG::RBrace, 5},
{ "lsub", TLSUB, '\0', TG::Power, 0},
{ "lsup", TLSUP, '\0', TG::Power, 0},
{ "lt", TLT, MS_LT, TG::Relation, 0},
@@ -1513,6 +1491,55 @@ std::unique_ptr<SmNode> SmParser::DoSubSup(TG nActiveGroup, SmNode *pGivenNode)
return pNode;
}
+std::unique_ptr<SmNode> SmParser::DoSubSupEvaluate(SmNode *pGivenNode)
+{
+ std::unique_ptr<SmNode> xGivenNode(pGivenNode);
+ DepthProtect aDepthGuard(m_nParseDepth);
+ if (aDepthGuard.TooDeep()) throw std::range_error("parser depth limit");
+
+ std::unique_ptr<SmSubSupNode> pNode(new SmSubSupNode(m_aCurToken));
+ pNode->SetUseLimits(true);
+
+ // initialize subnodes array
+ std::vector<std::unique_ptr<SmNode>> aSubNodes(1 + SUBSUP_NUM_ENTRIES);
+ aSubNodes[0] = std::move(xGivenNode);
+
+ // process all sub-/supscripts
+ int nIndex = 0;
+ while (TokenInGroup(TG::Limit))
+ {
+ SmTokenType eType (m_aCurToken.eType);
+
+ switch (eType)
+ {
+ case TFROM : nIndex = static_cast<int>(RSUB); break;
+ case TTO : nIndex = static_cast<int>(RSUP); break;
+ default :
+ SAL_WARN( "starmath", "unknown case");
+ }
+ nIndex++;
+ assert(1 <= nIndex && nIndex <= SUBSUP_NUM_ENTRIES);
+
+ std::unique_ptr<SmNode> xENode;
+ if (aSubNodes[nIndex]) // if already occupied at earlier iteration
+ {
+ // forget the earlier one, remember an error instead
+ aSubNodes[nIndex].reset();
+ xENode = DoError(SmParseError::DoubleSubsupscript); // this also skips current token.
+ }
+ else NextToken(); // skip sub-/supscript token
+
+ // get sub-/supscript node
+ std::unique_ptr<SmNode> xSNode;
+ xSNode = DoTerm(true);
+
+ aSubNodes[nIndex] = std::move(xENode ? xENode : xSNode);
+ }
+
+ pNode->SetSubNodes(buildNodeArray(aSubNodes));
+ return pNode;
+}
+
std::unique_ptr<SmNode> SmParser::DoOpSubSup()
{
DepthProtect aDepthGuard(m_nParseDepth);
@@ -1613,6 +1640,8 @@ std::unique_ptr<SmNode> SmParser::DoTerm(bool bGroupNumberIdent)
case TLEFT :
return DoBrace();
+ case TEVALUATE:
+ return DoEvaluate();
case TBLANK :
case TSBLANK :
@@ -2302,6 +2331,8 @@ std::unique_ptr<SmStructureNode> SmParser::DoBrace()
case TLANGLE : eExpectedType = TRANGLE; break;
case TLFLOOR : eExpectedType = TRFLOOR; break;
case TLCEIL : eExpectedType = TRCEIL; break;
+ case TLRLINE : eExpectedType = TLRLINE; break;
+ case TLRDLINE : eExpectedType = TLRDLINE; break;
default :
SAL_WARN("starmath", "unknown case");
}
@@ -2376,6 +2407,43 @@ std::unique_ptr<SmBracebodyNode> SmParser::DoBracebody(bool bIsLeftRight)
return pBody;
}
+std::unique_ptr<SmNode> SmParser::DoEvaluate()
+{
+
+ // Checkout depth and create node
+ DepthProtect aDepthGuard(m_nParseDepth);
+ if (aDepthGuard.TooDeep()) throw std::range_error("parser depth limit");
+ std::unique_ptr<SmStructureNode> xSNode(new SmBraceNode(m_aCurToken));
+ SmToken aToken( TRLINE, MS_VERTLINE, "evaluate", TG::RBrace, 5);
+ aToken.nRow = m_aCurToken.nRow;
+ aToken.nCol = m_aCurToken.nCol;
+
+ // Parse body && left none
+ NextToken();
+ std::unique_ptr<SmNode> pBody = DoPower();
+ SmToken bToken( TNONE, '\0', "", TG::LBrace, 5);
+ std::unique_ptr<SmNode> pLeft;
+ pLeft.reset(new SmMathSymbolNode(bToken));
+
+ // Mount nodes
+ std::unique_ptr<SmNode> pRight;
+ pRight.reset(new SmMathSymbolNode(aToken));
+ xSNode->SetSubNodes(std::move(pLeft), std::move(pBody), std::move(pRight));
+ xSNode->SetScaleMode(SmScaleMode::Height); // scalable line
+
+ // Parse from to
+ if ( m_aCurToken.nGroup == TG::Limit )
+ {
+ std::unique_ptr<SmNode> rSNode;
+ rSNode = DoSubSupEvaluate(xSNode.release());
+ rSNode->GetToken().eType = TEVALUATE;
+ return rSNode;
+ }
+
+ return xSNode;
+
+}
+
std::unique_ptr<SmTextNode> SmParser::DoFunction()
{
DepthProtect aDepthGuard(m_nParseDepth);