summaryrefslogtreecommitdiff
path: root/xfa/src/fxfa/fm2js/xfa_fmparse.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'xfa/src/fxfa/fm2js/xfa_fmparse.cpp')
-rw-r--r--xfa/src/fxfa/fm2js/xfa_fmparse.cpp1051
1 files changed, 1051 insertions, 0 deletions
diff --git a/xfa/src/fxfa/fm2js/xfa_fmparse.cpp b/xfa/src/fxfa/fm2js/xfa_fmparse.cpp
new file mode 100644
index 0000000000..7950abbd16
--- /dev/null
+++ b/xfa/src/fxfa/fm2js/xfa_fmparse.cpp
@@ -0,0 +1,1051 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/src/fxfa/fm2js/xfa_fmparse.h"
+
+#include <memory>
+
+CXFA_FMParse::CXFA_FMParse() : m_pToken(nullptr), m_pErrorInfo(0) {}
+
+int32_t CXFA_FMParse::Init(const CFX_WideStringC& wsFormcalc,
+ CXFA_FMErrorInfo* pErrorInfo) {
+ m_pErrorInfo = pErrorInfo;
+ m_lexer.reset(new CXFA_FMLexer(wsFormcalc, m_pErrorInfo));
+ return 0;
+}
+
+void CXFA_FMParse::NextToken() {
+ m_pToken = m_lexer->NextToken();
+ while (m_pToken->m_type == TOKreserver) {
+ if (m_lexer->HasError()) {
+ break;
+ }
+ m_pToken = m_lexer->NextToken();
+ }
+}
+
+void CXFA_FMParse::Check(XFA_FM_TOKEN op) {
+ if (m_pToken->m_type != op) {
+ CFX_WideString ws_TempString = m_pToken->m_wstring;
+ Error(m_pToken->m_uLinenum, FMERR_EXPECTED_TOKEN,
+ XFA_FM_KeywordToString(op), ws_TempString.c_str());
+ }
+ NextToken();
+}
+
+void CXFA_FMParse::Error(FX_DWORD lineNum, XFA_FM_ERRMSG msg, ...) {
+ m_pErrorInfo->linenum = lineNum;
+ const FX_WCHAR* lpMessageInfo = XFA_FM_ErrorMsg(msg);
+ va_list ap;
+ va_start(ap, msg);
+ m_pErrorInfo->message.FormatV(lpMessageInfo, ap);
+ va_end(ap);
+}
+
+CFX_PtrArray* CXFA_FMParse::ParseTopExpression() {
+ std::unique_ptr<CXFA_FMExpression> e;
+ CFX_PtrArray* expression = new CFX_PtrArray();
+ while (1) {
+ if (m_pToken->m_type == TOKeof || m_pToken->m_type == TOKendfunc ||
+ m_pToken->m_type == TOKendif || m_pToken->m_type == TOKelseif ||
+ m_pToken->m_type == TOKelse || m_pToken->m_type == TOKreserver) {
+ return expression;
+ }
+
+ if (m_pToken->m_type == TOKfunc) {
+ e.reset(ParseFunction());
+ if (e) {
+ expression->Add(e.release());
+ } else {
+ break;
+ }
+ } else {
+ e.reset(ParseExpression());
+ if (e) {
+ expression->Add(e.release());
+ } else {
+ break;
+ }
+ }
+ }
+ return expression;
+}
+
+CXFA_FMExpression* CXFA_FMParse::ParseFunction() {
+ std::unique_ptr<CXFA_FMExpression> e;
+ CFX_WideStringC ident;
+ std::unique_ptr<CFX_WideStringCArray> pArguments;
+ std::unique_ptr<CFX_PtrArray> pExpressions;
+ FX_DWORD line = m_pToken->m_uLinenum;
+ NextToken();
+ if (m_pToken->m_type != TOKidentifier) {
+ CFX_WideString ws_TempString = m_pToken->m_wstring;
+ Error(m_pToken->m_uLinenum, FMERR_EXPECTED_IDENTIFIER,
+ ws_TempString.c_str());
+ } else {
+ ident = m_pToken->m_wstring;
+ NextToken();
+ }
+ Check(TOKlparen);
+ if (m_pToken->m_type == TOKrparen) {
+ NextToken();
+ } else {
+ pArguments.reset(new CFX_WideStringCArray());
+ CFX_WideStringC p;
+ while (1) {
+ if (m_pToken->m_type == TOKidentifier) {
+ p = m_pToken->m_wstring;
+ pArguments->Add(p);
+ NextToken();
+ if (m_pToken->m_type == TOKcomma) {
+ NextToken();
+ continue;
+ } else if (m_pToken->m_type == TOKrparen) {
+ NextToken();
+ break;
+ } else {
+ Check(TOKrparen);
+ break;
+ }
+ } else {
+ CFX_WideString ws_TempString = m_pToken->m_wstring;
+ Error(m_pToken->m_uLinenum, FMERR_EXPECTED_IDENTIFIER,
+ ws_TempString.c_str());
+ NextToken();
+ break;
+ }
+ }
+ }
+ Check(TOKdo);
+ if (m_pToken->m_type == TOKendfunc) {
+ NextToken();
+ } else {
+ pExpressions.reset(ParseTopExpression());
+ Check(TOKendfunc);
+ }
+ if (m_pErrorInfo->message.IsEmpty()) {
+ e.reset(new CXFA_FMFunctionDefinition(line, 0, ident, pArguments.release(),
+ pExpressions.release()));
+ } else {
+ if (pArguments)
+ pArguments->RemoveAll();
+ if (pExpressions) {
+ for (int i = 0; i < pExpressions->GetSize(); ++i)
+ delete static_cast<CXFA_FMExpression*>(pExpressions->GetAt(i));
+ }
+ }
+ return e.release();
+}
+
+CXFA_FMExpression* CXFA_FMParse::ParseExpression() {
+ std::unique_ptr<CXFA_FMExpression> e;
+ FX_DWORD line = m_pToken->m_uLinenum;
+ switch (m_pToken->m_type) {
+ case TOKvar:
+ e.reset(ParseVarExpression());
+ break;
+ case TOKnull:
+ case TOKnumber:
+ case TOKstring:
+ case TOKplus:
+ case TOKminus:
+ case TOKksnot:
+ case TOKidentifier:
+ case TOKlparen:
+ e.reset(ParseExpExpression());
+ break;
+ case TOKif:
+ e.reset(ParseIfExpression());
+ break;
+ case TOKwhile:
+ e.reset(ParseWhileExpression());
+ break;
+ case TOKfor:
+ e.reset(ParseForExpression());
+ break;
+ case TOKforeach:
+ e.reset(ParseForeachExpression());
+ break;
+ case TOKdo:
+ e.reset(ParseDoExpression());
+ break;
+ case TOKbreak:
+ e.reset(new CXFA_FMBreakExpression(line));
+ NextToken();
+ break;
+ case TOKcontinue:
+ e.reset(new CXFA_FMContinueExpression(line));
+ NextToken();
+ break;
+ default:
+ CFX_WideString ws_TempString = m_pToken->m_wstring;
+ Error(m_pToken->m_uLinenum, FMERR_UNEXPECTED_EXPRESSION,
+ ws_TempString.c_str());
+ NextToken();
+ break;
+ }
+ return e.release();
+}
+
+CXFA_FMExpression* CXFA_FMParse::ParseVarExpression() {
+ std::unique_ptr<CXFA_FMExpression> e;
+ CFX_WideStringC ident;
+ FX_DWORD line = m_pToken->m_uLinenum;
+ NextToken();
+ if (m_pToken->m_type != TOKidentifier) {
+ CFX_WideString ws_TempString = m_pToken->m_wstring;
+ Error(m_pToken->m_uLinenum, FMERR_EXPECTED_IDENTIFIER,
+ ws_TempString.c_str());
+ } else {
+ ident = m_pToken->m_wstring;
+ NextToken();
+ }
+ if (m_pToken->m_type == TOKassign) {
+ NextToken();
+ e.reset(ParseExpExpression());
+ }
+ if (m_pErrorInfo->message.IsEmpty()) {
+ e.reset(new CXFA_FMVarExpression(line, ident, e.release()));
+ } else {
+ e.reset();
+ }
+ return e.release();
+}
+
+CXFA_FMSimpleExpression* CXFA_FMParse::ParseSimpleExpression() {
+ FX_DWORD line = m_pToken->m_uLinenum;
+ std::unique_ptr<CXFA_FMSimpleExpression> pExp1(ParseLogicalOrExpression());
+ while (m_pToken->m_type == TOKassign) {
+ NextToken();
+ std::unique_ptr<CXFA_FMSimpleExpression> pExp2(ParseLogicalOrExpression());
+ if (m_pErrorInfo->message.IsEmpty()) {
+ pExp1.reset(new CXFA_FMAssignExpression(line, TOKassign, pExp1.release(),
+ pExp2.release()));
+ } else {
+ pExp1.reset();
+ }
+ }
+ return pExp1.release();
+}
+
+CXFA_FMExpression* CXFA_FMParse::ParseExpExpression() {
+ FX_DWORD line = m_pToken->m_uLinenum;
+ std::unique_ptr<CXFA_FMSimpleExpression> pExp1(ParseSimpleExpression());
+ std::unique_ptr<CXFA_FMExpression> e;
+ if (m_pErrorInfo->message.IsEmpty()) {
+ e.reset(new CXFA_FMExpExpression(line, pExp1.release()));
+ } else {
+ e.reset();
+ }
+ return e.release();
+}
+
+CXFA_FMSimpleExpression* CXFA_FMParse::ParseLogicalOrExpression() {
+ FX_DWORD line = m_pToken->m_uLinenum;
+ std::unique_ptr<CXFA_FMSimpleExpression> e1(ParseLogicalAndExpression());
+ for (;;) {
+ switch (m_pToken->m_type) {
+ case TOKor:
+ case TOKksor: {
+ NextToken();
+ std::unique_ptr<CXFA_FMSimpleExpression> e2(
+ ParseLogicalAndExpression());
+ if (m_pErrorInfo->message.IsEmpty()) {
+ e1.reset(new CXFA_FMLogicalOrExpression(line, TOKor, e1.release(),
+ e2.release()));
+ } else {
+ e1.reset();
+ }
+ continue;
+ }
+ default:
+ break;
+ }
+ break;
+ }
+ return e1.release();
+}
+
+CXFA_FMSimpleExpression* CXFA_FMParse::ParseLogicalAndExpression() {
+ FX_DWORD line = m_pToken->m_uLinenum;
+ std::unique_ptr<CXFA_FMSimpleExpression> e1(ParseEqualityExpression());
+ for (;;) {
+ switch (m_pToken->m_type) {
+ case TOKand:
+ case TOKksand: {
+ NextToken();
+ std::unique_ptr<CXFA_FMSimpleExpression> e2(ParseEqualityExpression());
+ if (m_pErrorInfo->message.IsEmpty()) {
+ e1.reset(new CXFA_FMLogicalAndExpression(line, TOKand, e1.release(),
+ e2.release()));
+ } else {
+ e1.reset();
+ }
+ continue;
+ }
+ default:
+ break;
+ }
+ break;
+ }
+ return e1.release();
+}
+
+CXFA_FMSimpleExpression* CXFA_FMParse::ParseEqualityExpression() {
+ FX_DWORD line = m_pToken->m_uLinenum;
+ std::unique_ptr<CXFA_FMSimpleExpression> e1(ParseRelationalExpression());
+ for (;;) {
+ std::unique_ptr<CXFA_FMSimpleExpression> e2;
+ switch (m_pToken->m_type) {
+ case TOKeq:
+ case TOKkseq:
+ NextToken();
+ e2.reset(ParseRelationalExpression());
+ if (m_pErrorInfo->message.IsEmpty()) {
+ e1.reset(new CXFA_FMEqualityExpression(line, TOKeq, e1.release(),
+ e2.release()));
+ } else {
+ e1.reset();
+ }
+ continue;
+ case TOKne:
+ case TOKksne:
+ NextToken();
+ e2.reset(ParseRelationalExpression());
+ if (m_pErrorInfo->message.IsEmpty()) {
+ e1.reset(new CXFA_FMEqualityExpression(line, TOKne, e1.release(),
+ e2.release()));
+ } else {
+ e1.reset();
+ }
+ continue;
+ default:
+ break;
+ }
+ break;
+ }
+ return e1.release();
+}
+
+CXFA_FMSimpleExpression* CXFA_FMParse::ParseRelationalExpression() {
+ FX_DWORD line = m_pToken->m_uLinenum;
+ std::unique_ptr<CXFA_FMSimpleExpression> e1(ParseAddtiveExpression());
+ for (;;) {
+ std::unique_ptr<CXFA_FMSimpleExpression> e2;
+ switch (m_pToken->m_type) {
+ case TOKlt:
+ case TOKkslt:
+ NextToken();
+ e2.reset(ParseAddtiveExpression());
+ if (m_pErrorInfo->message.IsEmpty()) {
+ e1.reset(new CXFA_FMRelationalExpression(line, TOKlt, e1.release(),
+ e2.release()));
+ } else {
+ e1.reset();
+ }
+ continue;
+ case TOKgt:
+ case TOKksgt:
+ NextToken();
+ e2.reset(ParseAddtiveExpression());
+ if (m_pErrorInfo->message.IsEmpty()) {
+ e1.reset(new CXFA_FMRelationalExpression(line, TOKgt, e1.release(),
+ e2.release()));
+ } else {
+ e1.reset();
+ }
+ continue;
+ case TOKle:
+ case TOKksle:
+ NextToken();
+ e2.reset(ParseAddtiveExpression());
+ if (m_pErrorInfo->message.IsEmpty()) {
+ e1.reset(new CXFA_FMRelationalExpression(line, TOKle, e1.release(),
+ e2.release()));
+ } else {
+ e1.reset();
+ }
+ continue;
+ case TOKge:
+ case TOKksge:
+ NextToken();
+ e2.reset(ParseAddtiveExpression());
+ if (m_pErrorInfo->message.IsEmpty()) {
+ e1.reset(new CXFA_FMRelationalExpression(line, TOKge, e1.release(),
+ e2.release()));
+ } else {
+ e1.reset();
+ }
+ continue;
+ default:
+ break;
+ }
+ break;
+ }
+ return e1.release();
+}
+
+CXFA_FMSimpleExpression* CXFA_FMParse::ParseAddtiveExpression() {
+ FX_DWORD line = m_pToken->m_uLinenum;
+ std::unique_ptr<CXFA_FMSimpleExpression> e1(ParseMultiplicativeExpression());
+ for (;;) {
+ std::unique_ptr<CXFA_FMSimpleExpression> e2;
+ switch (m_pToken->m_type) {
+ case TOKplus:
+ NextToken();
+ e2.reset(ParseMultiplicativeExpression());
+ if (m_pErrorInfo->message.IsEmpty()) {
+ e1.reset(new CXFA_FMAdditiveExpression(line, TOKplus, e1.release(),
+ e2.release()));
+ } else {
+ e1.reset();
+ }
+ continue;
+ case TOKminus:
+ NextToken();
+ e2.reset(ParseMultiplicativeExpression());
+ if (m_pErrorInfo->message.IsEmpty()) {
+ e1.reset(new CXFA_FMAdditiveExpression(line, TOKminus, e1.release(),
+ e2.release()));
+ } else {
+ e1.reset();
+ }
+ continue;
+ default:
+ break;
+ }
+ break;
+ }
+ return e1.release();
+}
+
+CXFA_FMSimpleExpression* CXFA_FMParse::ParseMultiplicativeExpression() {
+ FX_DWORD line = m_pToken->m_uLinenum;
+ std::unique_ptr<CXFA_FMSimpleExpression> e1(ParseUnaryExpression());
+ for (;;) {
+ std::unique_ptr<CXFA_FMSimpleExpression> e2;
+ switch (m_pToken->m_type) {
+ case TOKmul:
+ NextToken();
+ e2.reset(ParseUnaryExpression());
+ if (m_pErrorInfo->message.IsEmpty()) {
+ e1.reset(new CXFA_FMMultiplicativeExpression(
+ line, TOKmul, e1.release(), e2.release()));
+ } else {
+ e1.reset();
+ }
+ continue;
+ case TOKdiv:
+ NextToken();
+ e2.reset(ParseUnaryExpression());
+ if (m_pErrorInfo->message.IsEmpty()) {
+ e1.reset(new CXFA_FMMultiplicativeExpression(
+ line, TOKdiv, e1.release(), e2.release()));
+ } else {
+ e1.reset();
+ }
+ continue;
+ default:
+ break;
+ }
+ break;
+ }
+ return e1.release();
+}
+
+CXFA_FMSimpleExpression* CXFA_FMParse::ParseUnaryExpression() {
+ std::unique_ptr<CXFA_FMSimpleExpression> e;
+ FX_DWORD line = m_pToken->m_uLinenum;
+ switch (m_pToken->m_type) {
+ case TOKplus:
+ NextToken();
+ e.reset(ParseUnaryExpression());
+ if (m_pErrorInfo->message.IsEmpty()) {
+ e.reset(new CXFA_FMPosExpression(line, e.release()));
+ } else {
+ e.reset();
+ }
+ break;
+ case TOKminus:
+ NextToken();
+ e.reset(ParseUnaryExpression());
+ if (m_pErrorInfo->message.IsEmpty()) {
+ e.reset(new CXFA_FMNegExpression(line, e.release()));
+ } else {
+ e.reset();
+ }
+ break;
+ case TOKksnot:
+ NextToken();
+ e.reset(ParseUnaryExpression());
+ if (m_pErrorInfo->message.IsEmpty()) {
+ e.reset(new CXFA_FMNotExpression(line, e.release()));
+ } else {
+ e.reset();
+ }
+ break;
+ default:
+ e.reset(ParsePrimaryExpression());
+ break;
+ }
+ return e.release();
+}
+
+CXFA_FMSimpleExpression* CXFA_FMParse::ParsePrimaryExpression() {
+ std::unique_ptr<CXFA_FMSimpleExpression> e;
+ FX_DWORD line = m_pToken->m_uLinenum;
+ switch (m_pToken->m_type) {
+ case TOKnumber:
+ e.reset(new CXFA_FMNumberExpression(line, m_pToken->m_wstring));
+ NextToken();
+ break;
+ case TOKstring:
+ e.reset(new CXFA_FMStringExpression(line, m_pToken->m_wstring));
+ NextToken();
+ break;
+ case TOKidentifier: {
+ CFX_WideStringC wsIdentifier(m_pToken->m_wstring);
+ NextToken();
+ if (m_pToken->m_type == TOKlbracket) {
+ CXFA_FMSimpleExpression* s = ParseIndexExpression();
+ if (s) {
+ e.reset(new CXFA_FMDotAccessorExpression(line, NULL, TOKdot,
+ wsIdentifier, s));
+ }
+ NextToken();
+ } else {
+ e.reset(new CXFA_FMIdentifierExpressionn(line, wsIdentifier));
+ }
+ } break;
+ case TOKif:
+ e.reset(new CXFA_FMIdentifierExpressionn(line, m_pToken->m_wstring));
+ NextToken();
+ break;
+ case TOKnull:
+ e.reset(new CXFA_FMNullExpression(line));
+ NextToken();
+ break;
+ case TOKlparen:
+ e.reset(ParseParenExpression());
+ break;
+ default:
+ CFX_WideString ws_TempString = m_pToken->m_wstring;
+ Error(m_pToken->m_uLinenum, FMERR_UNEXPECTED_EXPRESSION,
+ ws_TempString.c_str());
+ NextToken();
+ break;
+ }
+ e.reset(ParsePostExpression(e.release()));
+ if (!(m_pErrorInfo->message.IsEmpty()))
+ e.reset();
+ return e.release();
+}
+
+CXFA_FMSimpleExpression* CXFA_FMParse::ParsePostExpression(
+ CXFA_FMSimpleExpression* e) {
+ FX_DWORD line = m_pToken->m_uLinenum;
+ while (1) {
+ switch (m_pToken->m_type) {
+ case TOKlparen: {
+ NextToken();
+ std::unique_ptr<CFX_PtrArray> pArray;
+ if (m_pToken->m_type != TOKrparen) {
+ pArray.reset(new CFX_PtrArray());
+ while (m_pToken->m_type != TOKrparen) {
+ CXFA_FMSimpleExpression* e = ParseSimpleExpression();
+ if (e) {
+ pArray->Add(e);
+ }
+ if (m_pToken->m_type == TOKcomma) {
+ NextToken();
+ } else if (m_pToken->m_type == TOKeof ||
+ m_pToken->m_type == TOKreserver) {
+ break;
+ }
+ }
+ if (m_pToken->m_type != TOKrparen) {
+ CFX_WideString ws_TempString = m_pToken->m_wstring;
+ Error(m_pToken->m_uLinenum, FMERR_EXPECTED_TOKEN,
+ XFA_FM_KeywordToString(TOKrparen), ws_TempString.c_str());
+ }
+ }
+ if (m_pErrorInfo->message.IsEmpty()) {
+ e = new CXFA_FMCallExpression(line, e, pArray.release(), FALSE);
+ NextToken();
+ if (m_pToken->m_type != TOKlbracket) {
+ continue;
+ }
+ CXFA_FMSimpleExpression* s = ParseIndexExpression();
+ if (s) {
+ e = new CXFA_FMDotAccessorExpression(line, e, TOKcall,
+ FX_WSTRC(L""), s);
+ } else {
+ delete e;
+ e = nullptr;
+ }
+ } else {
+ if (pArray) {
+ for (int32_t i = 0; i < pArray->GetSize(); ++i)
+ delete static_cast<CXFA_FMSimpleExpression*>(pArray->GetAt(i));
+ }
+ delete e;
+ e = nullptr;
+ }
+ } break;
+ case TOKdot:
+ NextToken();
+ if (m_pToken->m_type == TOKidentifier) {
+ CFX_WideStringC tempStr = m_pToken->m_wstring;
+ FX_DWORD tempLine = m_pToken->m_uLinenum;
+ NextToken();
+ if (m_pToken->m_type == TOKlparen) {
+ CXFA_FMSimpleExpression* pExpAccessor;
+ CXFA_FMSimpleExpression* pExpCall;
+ pExpAccessor = e;
+ NextToken();
+ std::unique_ptr<CFX_PtrArray> pArray;
+ if (m_pToken->m_type != TOKrparen) {
+ pArray.reset(new CFX_PtrArray());
+ while (m_pToken->m_type != TOKrparen) {
+ CXFA_FMSimpleExpression* exp = ParseSimpleExpression();
+ pArray->Add(exp);
+ if (m_pToken->m_type == TOKcomma) {
+ NextToken();
+ } else if (m_pToken->m_type == TOKeof ||
+ m_pToken->m_type == TOKreserver) {
+ break;
+ }
+ }
+ if (m_pToken->m_type != TOKrparen) {
+ CFX_WideString ws_TempString = m_pToken->m_wstring;
+ Error(m_pToken->m_uLinenum, FMERR_EXPECTED_TOKEN,
+ XFA_FM_KeywordToString(TOKrparen), ws_TempString.c_str());
+ }
+ }
+ if (m_pErrorInfo->message.IsEmpty()) {
+ CXFA_FMSimpleExpression* pIdentifier =
+ new CXFA_FMIdentifierExpressionn(tempLine, tempStr);
+ pExpCall = new CXFA_FMCallExpression(line, pIdentifier,
+ pArray.release(), TRUE);
+ e = new CXFA_FMMethodCallExpression(line, pExpAccessor, pExpCall);
+ NextToken();
+ if (m_pToken->m_type != TOKlbracket) {
+ continue;
+ }
+ CXFA_FMSimpleExpression* s = ParseIndexExpression();
+ if (s) {
+ e = new CXFA_FMDotAccessorExpression(line, e, TOKcall,
+ FX_WSTRC(L""), s);
+ } else {
+ delete e;
+ e = nullptr;
+ }
+ } else {
+ if (pArray) {
+ for (int32_t i = 0; i < pArray->GetSize(); ++i) {
+ delete static_cast<CXFA_FMSimpleExpression*>(
+ pArray->GetAt(i));
+ }
+ }
+ delete e;
+ e = nullptr;
+ }
+ } else if (m_pToken->m_type == TOKlbracket) {
+ std::unique_ptr<CXFA_FMSimpleExpression> s(ParseIndexExpression());
+ if (!(m_pErrorInfo->message.IsEmpty())) {
+ delete e;
+ return nullptr;
+ }
+ e = new CXFA_FMDotAccessorExpression(tempLine, e, TOKdot, tempStr,
+ s.release());
+ } else {
+ CXFA_FMSimpleExpression* s = new CXFA_FMIndexExpression(
+ tempLine, ACCESSOR_NO_INDEX, NULL, FALSE);
+ e = new CXFA_FMDotAccessorExpression(line, e, TOKdot, tempStr, s);
+ continue;
+ }
+ } else {
+ CFX_WideString ws_TempString = m_pToken->m_wstring;
+ Error(m_pToken->m_uLinenum, FMERR_EXPECTED_IDENTIFIER,
+ ws_TempString.c_str());
+ return e;
+ }
+ break;
+ case TOKdotdot:
+ NextToken();
+ if (m_pToken->m_type == TOKidentifier) {
+ CFX_WideStringC tempStr = m_pToken->m_wstring;
+ FX_DWORD tempLine = m_pToken->m_uLinenum;
+ NextToken();
+ if (m_pToken->m_type == TOKlbracket) {
+ std::unique_ptr<CXFA_FMSimpleExpression> s(ParseIndexExpression());
+ if (!(m_pErrorInfo->message.IsEmpty())) {
+ delete e;
+ return nullptr;
+ }
+ e = new CXFA_FMDotDotAccessorExpression(tempLine, e, TOKdotdot,
+ tempStr, s.release());
+ } else {
+ CXFA_FMSimpleExpression* s = new CXFA_FMIndexExpression(
+ tempLine, ACCESSOR_NO_INDEX, NULL, FALSE);
+ e = new CXFA_FMDotDotAccessorExpression(line, e, TOKdotdot, tempStr,
+ s);
+ continue;
+ }
+ } else {
+ CFX_WideString ws_TempString = m_pToken->m_wstring;
+ Error(m_pToken->m_uLinenum, FMERR_EXPECTED_IDENTIFIER,
+ ws_TempString.c_str());
+ return e;
+ }
+ break;
+ case TOKdotscream:
+ NextToken();
+ if (m_pToken->m_type == TOKidentifier) {
+ CFX_WideStringC tempStr = m_pToken->m_wstring;
+ FX_DWORD tempLine = m_pToken->m_uLinenum;
+ NextToken();
+ if (m_pToken->m_type == TOKlbracket) {
+ std::unique_ptr<CXFA_FMSimpleExpression> s(ParseIndexExpression());
+ if (!(m_pErrorInfo->message.IsEmpty())) {
+ delete e;
+ return nullptr;
+ }
+ e = new CXFA_FMDotAccessorExpression(tempLine, e, TOKdotscream,
+ tempStr, s.release());
+ } else {
+ CXFA_FMSimpleExpression* s = new CXFA_FMIndexExpression(
+ tempLine, ACCESSOR_NO_INDEX, NULL, FALSE);
+ e = new CXFA_FMDotAccessorExpression(line, e, TOKdotscream, tempStr,
+ s);
+ continue;
+ }
+ } else {
+ CFX_WideString ws_TempString = m_pToken->m_wstring;
+ Error(m_pToken->m_uLinenum, FMERR_EXPECTED_IDENTIFIER,
+ ws_TempString.c_str());
+ return e;
+ }
+ break;
+ case TOKdotstar: {
+ CXFA_FMSimpleExpression* s =
+ new CXFA_FMIndexExpression(line, ACCESSOR_NO_INDEX, NULL, FALSE);
+ e = new CXFA_FMDotAccessorExpression(line, e, TOKdotstar,
+ FX_WSTRC(L"*"), s);
+ } break;
+ default:
+ return e;
+ }
+ NextToken();
+ }
+ return e;
+}
+
+CXFA_FMSimpleExpression* CXFA_FMParse::ParseIndexExpression() {
+ std::unique_ptr<CXFA_FMSimpleExpression> pExp;
+ FX_DWORD line = m_pToken->m_uLinenum;
+ NextToken();
+ std::unique_ptr<CXFA_FMSimpleExpression> s;
+ XFA_FM_AccessorIndex accessorIndex = ACCESSOR_NO_RELATIVEINDEX;
+ if (m_pToken->m_type == TOKmul) {
+ pExp.reset(
+ new CXFA_FMIndexExpression(line, accessorIndex, s.release(), TRUE));
+ NextToken();
+ if (m_pToken->m_type != TOKrbracket) {
+ CFX_WideString ws_TempString = m_pToken->m_wstring;
+ Error(m_pToken->m_uLinenum, FMERR_EXPECTED_TOKEN,
+ XFA_FM_KeywordToString(TOKrparen), ws_TempString.c_str());
+ pExp.reset();
+ }
+ return pExp.release();
+ }
+ if (m_pToken->m_type == TOKplus) {
+ accessorIndex = ACCESSOR_POSITIVE_INDEX;
+ NextToken();
+ } else if (m_pToken->m_type == TOKminus) {
+ accessorIndex = ACCESSOR_NEGATIVE_INDEX;
+ NextToken();
+ }
+ s.reset(ParseSimpleExpression());
+ if (m_pToken->m_type != TOKrbracket) {
+ CFX_WideString ws_TempString = m_pToken->m_wstring;
+ Error(m_pToken->m_uLinenum, FMERR_EXPECTED_TOKEN,
+ XFA_FM_KeywordToString(TOKrparen), ws_TempString.c_str());
+ } else {
+ pExp.reset(
+ new CXFA_FMIndexExpression(line, accessorIndex, s.release(), FALSE));
+ }
+ return pExp.release();
+}
+
+CXFA_FMSimpleExpression* CXFA_FMParse::ParseParenExpression() {
+ Check(TOKlparen);
+
+ if (m_pToken->m_type == TOKrparen) {
+ Error(m_pToken->m_uLinenum, FMERR_EXPECTED_NON_EMPTY_EXPRESSION);
+ NextToken();
+ return nullptr;
+ }
+
+ FX_DWORD line = m_pToken->m_uLinenum;
+ std::unique_ptr<CXFA_FMSimpleExpression> pExp1(ParseLogicalOrExpression());
+
+ while (m_pToken->m_type == TOKassign) {
+ NextToken();
+ std::unique_ptr<CXFA_FMSimpleExpression> pExp2(ParseLogicalOrExpression());
+ if (m_pErrorInfo->message.IsEmpty()) {
+ pExp1.reset(new CXFA_FMAssignExpression(line, TOKassign, pExp1.release(),
+ pExp2.release()));
+ } else {
+ pExp1.reset();
+ }
+ }
+ Check(TOKrparen);
+ return pExp1.release();
+}
+
+CXFA_FMExpression* CXFA_FMParse::ParseBlockExpression() {
+ FX_DWORD line = m_pToken->m_uLinenum;
+ CXFA_FMExpression* e = nullptr;
+ std::unique_ptr<CFX_PtrArray> expression(new CFX_PtrArray());
+ while (1) {
+ switch (m_pToken->m_type) {
+ case TOKeof:
+ case TOKendif:
+ case TOKelseif:
+ case TOKelse:
+ case TOKendwhile:
+ case TOKendfor:
+ case TOKend:
+ case TOKendfunc:
+ case TOKreserver:
+ break;
+ case TOKfunc:
+ e = ParseFunction();
+ if (e) {
+ expression->Add(e);
+ }
+ continue;
+ default:
+ e = ParseExpression();
+ if (e) {
+ expression->Add(e);
+ }
+ continue;
+ }
+ break;
+ }
+ std::unique_ptr<CXFA_FMBlockExpression> pExp;
+ if (m_pErrorInfo->message.IsEmpty()) {
+ pExp.reset(new CXFA_FMBlockExpression(line, expression.release()));
+ } else {
+ for (int i = 0; i < expression->GetSize(); ++i)
+ delete static_cast<CXFA_FMExpression*>(expression->GetAt(i));
+ }
+ return pExp.release();
+}
+
+CXFA_FMExpression* CXFA_FMParse::ParseIfExpression() {
+ FX_DWORD line = m_pToken->m_uLinenum;
+ const FX_WCHAR* pStartPos = m_lexer->SavePos();
+ NextToken();
+ Check(TOKlparen);
+ std::unique_ptr<CXFA_FMSimpleExpression> pExpression;
+ while (m_pToken->m_type != TOKrparen) {
+ pExpression.reset(ParseSimpleExpression());
+ if (m_pToken->m_type != TOKcomma)
+ break;
+ NextToken();
+ }
+ Check(TOKrparen);
+ if (m_pToken->m_type != TOKthen) {
+ m_lexer->SetCurrentLine(line);
+ m_pToken = new CXFA_FMToken(line);
+ m_pToken->m_type = TOKidentifier;
+ m_pToken->m_wstring = FX_WSTRC(L"if");
+ m_lexer->SetToken(m_pToken);
+ m_lexer->RestorePos(pStartPos);
+ return ParseExpExpression();
+ }
+ Check(TOKthen);
+ std::unique_ptr<CXFA_FMExpression> pIfExpression(ParseBlockExpression());
+ std::unique_ptr<CXFA_FMExpression> pElseExpression;
+ switch (m_pToken->m_type) {
+ case TOKeof:
+ case TOKendif:
+ Check(TOKendif);
+ break;
+ case TOKif:
+ pElseExpression.reset(ParseIfExpression());
+ Check(TOKendif);
+ break;
+ case TOKelseif:
+ pElseExpression.reset(ParseIfExpression());
+ break;
+ case TOKelse:
+ NextToken();
+ pElseExpression.reset(ParseBlockExpression());
+ Check(TOKendif);
+ break;
+ default:
+ CFX_WideString ws_TempString = m_pToken->m_wstring;
+ Error(m_pToken->m_uLinenum, FMERR_EXPECTED_IFEND, ws_TempString.c_str());
+ NextToken();
+ break;
+ }
+ std::unique_ptr<CXFA_FMIfExpression> pExp;
+ if (m_pErrorInfo->message.IsEmpty()) {
+ pExp.reset(new CXFA_FMIfExpression(line, pExpression.release(),
+ pIfExpression.release(),
+ pElseExpression.release()));
+ }
+ return pExp.release();
+}
+
+CXFA_FMExpression* CXFA_FMParse::ParseWhileExpression() {
+ FX_DWORD line = m_pToken->m_uLinenum;
+ NextToken();
+ std::unique_ptr<CXFA_FMSimpleExpression> pCondition(ParseParenExpression());
+ Check(TOKdo);
+ std::unique_ptr<CXFA_FMExpression> pExpression(ParseBlockExpression());
+ Check(TOKendwhile);
+ std::unique_ptr<CXFA_FMExpression> e;
+ if (m_pErrorInfo->message.IsEmpty()) {
+ e.reset(new CXFA_FMWhileExpression(line, pCondition.release(),
+ pExpression.release()));
+ }
+ return e.release();
+}
+
+CXFA_FMSimpleExpression* CXFA_FMParse::ParseSubassignmentInForExpression() {
+ std::unique_ptr<CXFA_FMSimpleExpression> e;
+ switch (m_pToken->m_type) {
+ case TOKidentifier:
+ e.reset(ParseSimpleExpression());
+ break;
+ default:
+ CFX_WideString ws_TempString = m_pToken->m_wstring;
+ Error(m_pToken->m_uLinenum, FMERR_UNEXPECTED_EXPRESSION,
+ ws_TempString.c_str());
+ NextToken();
+ break;
+ }
+ return e.release();
+}
+
+CXFA_FMExpression* CXFA_FMParse::ParseForExpression() {
+ CFX_WideStringC wsVariant;
+ FX_DWORD line = m_pToken->m_uLinenum;
+ NextToken();
+ if (m_pToken->m_type != TOKidentifier) {
+ CFX_WideString ws_TempString = m_pToken->m_wstring;
+ Error(m_pToken->m_uLinenum, FMERR_EXPECTED_TOKEN,
+ XFA_FM_KeywordToString(m_pToken->m_type), ws_TempString.c_str());
+ }
+ wsVariant = m_pToken->m_wstring;
+ NextToken();
+ std::unique_ptr<CXFA_FMSimpleExpression> pAssignment;
+ if (m_pToken->m_type == TOKassign) {
+ NextToken();
+ pAssignment.reset(ParseSimpleExpression());
+ } else {
+ CFX_WideString ws_TempString = m_pToken->m_wstring;
+ Error(m_pToken->m_uLinenum, FMERR_EXPECTED_TOKEN,
+ XFA_FM_KeywordToString(m_pToken->m_type), ws_TempString.c_str());
+ }
+ int32_t iDirection = 0;
+ if (m_pToken->m_type == TOKupto) {
+ iDirection = 1;
+ } else if (m_pToken->m_type == TOKdownto) {
+ iDirection = -1;
+ } else {
+ CFX_WideString ws_TempString = m_pToken->m_wstring;
+ Error(m_pToken->m_uLinenum, FMERR_EXPECTED_TOKEN, L"upto or downto",
+ (const FX_WCHAR*)ws_TempString);
+ }
+ NextToken();
+ std::unique_ptr<CXFA_FMSimpleExpression> pAccessor(ParseSimpleExpression());
+ std::unique_ptr<CXFA_FMSimpleExpression> pStep;
+ if (m_pToken->m_type == TOKstep) {
+ NextToken();
+ pStep.reset(ParseSimpleExpression());
+ }
+ Check(TOKdo);
+ std::unique_ptr<CXFA_FMExpression> pList(ParseBlockExpression());
+ Check(TOKendfor);
+ std::unique_ptr<CXFA_FMExpression> e;
+ if (m_pErrorInfo->message.IsEmpty()) {
+ e.reset(new CXFA_FMForExpression(line, wsVariant, pAssignment.release(),
+ pAccessor.release(), iDirection,
+ pStep.release(), pList.release()));
+ }
+ return e.release();
+}
+
+CXFA_FMExpression* CXFA_FMParse::ParseForeachExpression() {
+ std::unique_ptr<CXFA_FMExpression> e;
+ CFX_WideStringC wsIdentifier;
+ std::unique_ptr<CFX_PtrArray> pAccessors;
+ std::unique_ptr<CXFA_FMExpression> pList;
+ FX_DWORD line = m_pToken->m_uLinenum;
+ NextToken();
+ if (m_pToken->m_type != TOKidentifier) {
+ CFX_WideString ws_TempString = m_pToken->m_wstring;
+ Error(m_pToken->m_uLinenum, FMERR_EXPECTED_TOKEN,
+ XFA_FM_KeywordToString(m_pToken->m_type), ws_TempString.c_str());
+ }
+ wsIdentifier = m_pToken->m_wstring;
+ NextToken();
+ Check(TOKin);
+ Check(TOKlparen);
+ if (m_pToken->m_type == TOKrparen) {
+ CFX_WideString ws_TempString = m_pToken->m_wstring;
+ Error(m_pToken->m_uLinenum, FMERR_UNEXPECTED_EXPRESSION,
+ ws_TempString.c_str());
+ NextToken();
+ } else {
+ pAccessors.reset(new CFX_PtrArray());
+ while (m_pToken->m_type != TOKrparen) {
+ CXFA_FMSimpleExpression* s = ParseSimpleExpression();
+ if (s) {
+ pAccessors->Add(s);
+ }
+ if (m_pToken->m_type == TOKcomma) {
+ NextToken();
+ } else {
+ break;
+ }
+ }
+ Check(TOKrparen);
+ }
+ Check(TOKdo);
+ pList.reset(ParseBlockExpression());
+ Check(TOKendfor);
+ if (m_pErrorInfo->message.IsEmpty()) {
+ e.reset(new CXFA_FMForeachExpression(
+ line, wsIdentifier, pAccessors.release(), pList.release()));
+ } else {
+ if (pAccessors) {
+ for (int i = 0; i < pAccessors->GetSize(); ++i)
+ delete static_cast<CXFA_FMSimpleExpression*>(pAccessors->GetAt(i));
+ }
+ }
+ return e.release();
+}
+
+CXFA_FMExpression* CXFA_FMParse::ParseDoExpression() {
+ std::unique_ptr<CXFA_FMExpression> e;
+ FX_DWORD line = m_pToken->m_uLinenum;
+ NextToken();
+ e.reset(ParseBlockExpression());
+ Check(TOKend);
+ if (m_pErrorInfo->message.IsEmpty()) {
+ e.reset(new CXFA_FMDoExpression(line, e.release()));
+ } else {
+ e.reset();
+ }
+ return e.release();
+}