blob: 105c5144ca5dd0b7691da9f9ef4beaa85ec2e67c [file] [log] [blame]
// 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_fm2js.h"
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() {
CXFA_FMExpression* e = 0;
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 = ParseFunction();
if (e) {
expression->Add(e);
} else {
break;
}
} else {
e = ParseExpression();
if (e) {
expression->Add(e);
} else {
break;
}
}
}
return expression;
}
CXFA_FMExpression* CXFA_FMParse::ParseFunction() {
CXFA_FMExpression* e = 0;
CFX_WideStringC ident;
CFX_WideStringCArray* pArguments = 0;
CFX_PtrArray* pExpressions = 0;
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 = 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 = ParseTopExpression();
Check(TOKendfunc);
}
if (m_pErrorInfo->message.IsEmpty()) {
e = new CXFA_FMFunctionDefinition(line, 0, ident, pArguments, pExpressions);
} else {
int32_t size = 0;
int32_t index = 0;
if (pArguments) {
pArguments->RemoveAll();
delete pArguments;
pArguments = 0;
}
index = 0;
if (pExpressions) {
CXFA_FMExpression* e1 = 0;
size = pExpressions->GetSize();
while (index < size) {
e1 = (CXFA_FMExpression*)pExpressions->GetAt(index);
delete e1;
index++;
}
pExpressions->RemoveAll();
delete pExpressions;
pExpressions = 0;
}
}
return e;
}
CXFA_FMExpression* CXFA_FMParse::ParseExpression() {
CXFA_FMExpression* e = 0;
FX_DWORD line = m_pToken->m_uLinenum;
switch (m_pToken->m_type) {
case TOKvar:
e = ParseVarExpression();
break;
case TOKnull:
case TOKnumber:
case TOKstring:
case TOKplus:
case TOKminus:
case TOKksnot:
case TOKidentifier:
case TOKlparen:
e = ParseExpExpression();
break;
case TOKif:
e = ParseIfExpression();
break;
case TOKwhile:
e = ParseWhileExpression();
break;
case TOKfor:
e = ParseForExpression();
break;
case TOKforeach:
e = ParseForeachExpression();
break;
case TOKdo:
e = ParseDoExpression();
break;
case TOKbreak:
e = new CXFA_FMBreakExpression(line);
NextToken();
break;
case TOKcontinue:
e = 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;
}
CXFA_FMExpression* CXFA_FMParse::ParseVarExpression() {
CXFA_FMExpression* e = 0;
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 = ParseExpExpression();
}
if (m_pErrorInfo->message.IsEmpty()) {
e = new CXFA_FMVarExpression(line, ident, e);
} else {
delete e;
e = 0;
}
return e;
}
CXFA_FMSimpleExpression* CXFA_FMParse::ParseSimpleExpression() {
FX_DWORD line = m_pToken->m_uLinenum;
CXFA_FMSimpleExpression *pExp1 = 0, *pExp2 = 0;
pExp1 = ParseLogicalOrExpression();
while (m_pToken->m_type == TOKassign) {
NextToken();
pExp2 = ParseLogicalOrExpression();
if (m_pErrorInfo->message.IsEmpty()) {
pExp1 = new CXFA_FMAssignExpression(line, TOKassign, pExp1, pExp2);
} else {
delete pExp1;
pExp1 = 0;
}
}
return pExp1;
}
CXFA_FMExpression* CXFA_FMParse::ParseExpExpression() {
CXFA_FMExpression* e = 0;
FX_DWORD line = m_pToken->m_uLinenum;
CXFA_FMSimpleExpression* pExp1 = 0;
pExp1 = ParseSimpleExpression();
if (m_pErrorInfo->message.IsEmpty()) {
e = new CXFA_FMExpExpression(line, pExp1);
} else {
delete pExp1;
e = 0;
}
return e;
}
CXFA_FMSimpleExpression* CXFA_FMParse::ParseLogicalOrExpression() {
CXFA_FMSimpleExpression *e1 = 0, *e2 = 0;
FX_DWORD line = m_pToken->m_uLinenum;
e1 = ParseLogicalAndExpression();
for (;;) {
switch (m_pToken->m_type) {
case TOKor:
case TOKksor:
NextToken();
e2 = ParseLogicalAndExpression();
if (m_pErrorInfo->message.IsEmpty()) {
e1 = new CXFA_FMLogicalOrExpression(line, TOKor, e1, e2);
} else {
delete e1;
e1 = 0;
}
continue;
default:
break;
}
break;
}
return e1;
}
CXFA_FMSimpleExpression* CXFA_FMParse::ParseLogicalAndExpression() {
CXFA_FMSimpleExpression *e1 = 0, *e2 = 0;
FX_DWORD line = m_pToken->m_uLinenum;
e1 = ParseEqualityExpression();
for (;;) {
switch (m_pToken->m_type) {
case TOKand:
case TOKksand:
NextToken();
e2 = ParseEqualityExpression();
if (m_pErrorInfo->message.IsEmpty()) {
e1 = new CXFA_FMLogicalAndExpression(line, TOKand, e1, e2);
} else {
delete e1;
e1 = 0;
}
continue;
default:
break;
}
break;
}
return e1;
}
CXFA_FMSimpleExpression* CXFA_FMParse::ParseEqualityExpression() {
CXFA_FMSimpleExpression *e1 = 0, *e2 = 0;
FX_DWORD line = m_pToken->m_uLinenum;
e1 = ParseRelationalExpression();
for (;;) {
switch (m_pToken->m_type) {
case TOKeq:
case TOKkseq:
NextToken();
e2 = ParseRelationalExpression();
if (m_pErrorInfo->message.IsEmpty()) {
e1 = new CXFA_FMEqualityExpression(line, TOKeq, e1, e2);
} else {
delete e1;
e1 = 0;
}
continue;
case TOKne:
case TOKksne:
NextToken();
e2 = ParseRelationalExpression();
if (m_pErrorInfo->message.IsEmpty()) {
e1 = new CXFA_FMEqualityExpression(line, TOKne, e1, e2);
} else {
delete e1;
e1 = 0;
}
continue;
default:
break;
}
break;
}
return e1;
}
CXFA_FMSimpleExpression* CXFA_FMParse::ParseRelationalExpression() {
CXFA_FMSimpleExpression *e1 = 0, *e2 = 0;
FX_DWORD line = m_pToken->m_uLinenum;
e1 = ParseAddtiveExpression();
for (;;) {
switch (m_pToken->m_type) {
case TOKlt:
case TOKkslt:
NextToken();
e2 = ParseAddtiveExpression();
if (m_pErrorInfo->message.IsEmpty()) {
e1 = new CXFA_FMRelationalExpression(line, TOKlt, e1, e2);
} else {
delete e1;
e1 = 0;
}
continue;
case TOKgt:
case TOKksgt:
NextToken();
e2 = ParseAddtiveExpression();
if (m_pErrorInfo->message.IsEmpty()) {
e1 = new CXFA_FMRelationalExpression(line, TOKgt, e1, e2);
} else {
delete e1;
e1 = 0;
}
continue;
case TOKle:
case TOKksle:
NextToken();
e2 = ParseAddtiveExpression();
if (m_pErrorInfo->message.IsEmpty()) {
e1 = new CXFA_FMRelationalExpression(line, TOKle, e1, e2);
} else {
delete e1;
e1 = 0;
}
continue;
case TOKge:
case TOKksge:
NextToken();
e2 = ParseAddtiveExpression();
if (m_pErrorInfo->message.IsEmpty()) {
e1 = new CXFA_FMRelationalExpression(line, TOKge, e1, e2);
} else {
delete e1;
e1 = 0;
}
continue;
default:
break;
}
break;
}
return e1;
}
CXFA_FMSimpleExpression* CXFA_FMParse::ParseAddtiveExpression() {
CXFA_FMSimpleExpression *e1 = 0, *e2 = 0;
FX_DWORD line = m_pToken->m_uLinenum;
e1 = ParseMultiplicativeExpression();
for (;;) {
switch (m_pToken->m_type) {
case TOKplus:
NextToken();
e2 = ParseMultiplicativeExpression();
if (m_pErrorInfo->message.IsEmpty()) {
e1 = new CXFA_FMAdditiveExpression(line, TOKplus, e1, e2);
} else {
delete e1;
e1 = 0;
}
continue;
case TOKminus:
NextToken();
e2 = ParseMultiplicativeExpression();
if (m_pErrorInfo->message.IsEmpty()) {
e1 = new CXFA_FMAdditiveExpression(line, TOKminus, e1, e2);
} else {
delete e1;
e1 = 0;
}
continue;
default:
break;
}
break;
}
return e1;
}
CXFA_FMSimpleExpression* CXFA_FMParse::ParseMultiplicativeExpression() {
CXFA_FMSimpleExpression *e1 = 0, *e2 = 0;
FX_DWORD line = m_pToken->m_uLinenum;
e1 = ParseUnaryExpression();
for (;;) {
switch (m_pToken->m_type) {
case TOKmul:
NextToken();
e2 = ParseUnaryExpression();
if (m_pErrorInfo->message.IsEmpty()) {
e1 = new CXFA_FMMultiplicativeExpression(line, TOKmul, e1, e2);
} else {
delete e1;
e1 = 0;
}
continue;
case TOKdiv:
NextToken();
e2 = ParseUnaryExpression();
if (m_pErrorInfo->message.IsEmpty()) {
e1 = new CXFA_FMMultiplicativeExpression(line, TOKdiv, e1, e2);
} else {
delete e1;
e1 = 0;
}
continue;
default:
break;
}
break;
}
return e1;
}
CXFA_FMSimpleExpression* CXFA_FMParse::ParseUnaryExpression() {
CXFA_FMSimpleExpression* e = 0;
FX_DWORD line = m_pToken->m_uLinenum;
switch (m_pToken->m_type) {
case TOKplus:
NextToken();
e = ParseUnaryExpression();
if (m_pErrorInfo->message.IsEmpty()) {
e = new CXFA_FMPosExpression(line, e);
} else {
e = 0;
}
break;
case TOKminus:
NextToken();
e = ParseUnaryExpression();
if (m_pErrorInfo->message.IsEmpty()) {
e = new CXFA_FMNegExpression(line, e);
} else {
e = 0;
}
break;
case TOKksnot:
NextToken();
e = ParseUnaryExpression();
if (m_pErrorInfo->message.IsEmpty()) {
e = new CXFA_FMNotExpression(line, e);
} else {
e = 0;
}
break;
default:
e = ParsePrimaryExpression();
break;
}
return e;
}
CXFA_FMSimpleExpression* CXFA_FMParse::ParsePrimaryExpression() {
CXFA_FMSimpleExpression* e = 0;
FX_DWORD line = m_pToken->m_uLinenum;
switch (m_pToken->m_type) {
case TOKnumber:
e = new CXFA_FMNumberExpression(line, m_pToken->m_wstring);
NextToken();
break;
case TOKstring:
e = 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 = new CXFA_FMDotAccessorExpression(line, NULL, TOKdot, wsIdentifier,
s);
}
NextToken();
} else {
e = new CXFA_FMIdentifierExpressionn(line, wsIdentifier);
}
} break;
case TOKif:
e = new CXFA_FMIdentifierExpressionn(line, m_pToken->m_wstring);
NextToken();
break;
case TOKnull:
e = new CXFA_FMNullExpression(line);
NextToken();
break;
case TOKlparen:
e = 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 = ParsePostExpression(e);
if (!(m_pErrorInfo->message.IsEmpty())) {
delete e;
e = 0;
}
return e;
}
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();
CFX_PtrArray* pArray = 0;
if (m_pToken->m_type != TOKrparen) {
pArray = 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, 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 = 0;
}
} else {
int32_t iSize = pArray->GetSize();
for (int32_t i = 0; i < iSize; ++i) {
CXFA_FMSimpleExpression* pTemp =
(CXFA_FMSimpleExpression*)pArray->GetAt(i);
delete pTemp;
}
delete pArray;
delete e;
e = 0;
}
} 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();
CFX_PtrArray* pArray = 0;
if (m_pToken->m_type != TOKrparen) {
pArray = 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, 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 = 0;
}
} else {
int32_t iSize = pArray->GetSize();
for (int32_t i = 0; i < iSize; ++i) {
CXFA_FMSimpleExpression* pTemp =
(CXFA_FMSimpleExpression*)pArray->GetAt(i);
delete pTemp;
}
delete pArray;
delete e;
e = 0;
}
} else if (m_pToken->m_type == TOKlbracket) {
CXFA_FMSimpleExpression* s = ParseIndexExpression();
if (!(m_pErrorInfo->message.IsEmpty())) {
if (s) {
delete s;
s = 0;
}
if (e) {
delete e;
e = 0;
}
return e;
}
e = new CXFA_FMDotAccessorExpression(tempLine, e, TOKdot, tempStr,
s);
} 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) {
CXFA_FMSimpleExpression* s = ParseIndexExpression();
if (!(m_pErrorInfo->message.IsEmpty())) {
if (s) {
delete s;
s = 0;
}
if (e) {
delete e;
e = 0;
}
return e;
}
e = new CXFA_FMDotDotAccessorExpression(tempLine, e, TOKdotdot,
tempStr, s);
} 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) {
CXFA_FMSimpleExpression* s = ParseIndexExpression();
if (!(m_pErrorInfo->message.IsEmpty())) {
if (s) {
delete s;
s = 0;
}
if (e) {
delete e;
e = 0;
}
return e;
}
e = new CXFA_FMDotAccessorExpression(tempLine, e, TOKdotscream,
tempStr, s);
} 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() {
CXFA_FMSimpleExpression* pExp = 0;
FX_DWORD line = m_pToken->m_uLinenum;
NextToken();
CXFA_FMSimpleExpression* s = 0;
XFA_FM_AccessorIndex accessorIndex = ACCESSOR_NO_RELATIVEINDEX;
if (m_pToken->m_type == TOKmul) {
pExp = new CXFA_FMIndexExpression(line, accessorIndex, s, 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());
if (pExp) {
delete pExp;
pExp = 0;
}
}
return pExp;
}
if (m_pToken->m_type == TOKplus) {
accessorIndex = ACCESSOR_POSITIVE_INDEX;
NextToken();
} else if (m_pToken->m_type == TOKminus) {
accessorIndex = ACCESSOR_NEGATIVE_INDEX;
NextToken();
}
s = 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());
if (s) {
delete s;
}
} else {
pExp = new CXFA_FMIndexExpression(line, accessorIndex, s, FALSE);
}
return pExp;
}
CXFA_FMSimpleExpression* CXFA_FMParse::ParseParenExpression() {
CXFA_FMSimpleExpression *pExp1 = 0, *pExp2 = 0;
FX_DWORD line = m_pToken->m_uLinenum;
Check(TOKlparen);
if (m_pToken->m_type != TOKrparen) {
pExp1 = ParseLogicalOrExpression();
while (m_pToken->m_type == TOKassign) {
NextToken();
pExp2 = ParseLogicalOrExpression();
if (m_pErrorInfo->message.IsEmpty()) {
pExp1 = new CXFA_FMAssignExpression(line, TOKassign, pExp1, pExp2);
} else {
delete pExp1;
pExp1 = 0;
}
}
Check(TOKrparen);
} else {
NextToken();
}
return pExp1;
}
CXFA_FMExpression* CXFA_FMParse::ParseBlockExpression() {
FX_DWORD line = m_pToken->m_uLinenum;
CXFA_FMExpression* e = 0;
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;
}
CXFA_FMBlockExpression* pExp = 0;
if (m_pErrorInfo->message.IsEmpty()) {
pExp = new CXFA_FMBlockExpression(line, expression);
} else {
int32_t size = expression->GetSize();
int32_t index = 0;
while (index < size) {
e = (CXFA_FMExpression*)expression->GetAt(index);
delete e;
index++;
}
expression->RemoveAll();
delete expression;
expression = 0;
}
return pExp;
}
CXFA_FMExpression* CXFA_FMParse::ParseIfExpression() {
CXFA_FMSimpleExpression* pExpression = 0;
CXFA_FMExpression* pIfExpression = 0;
CXFA_FMExpression* pElseExpression = 0;
FX_DWORD line = m_pToken->m_uLinenum;
const FX_WCHAR* pStartPos = m_lexer->SavePos();
NextToken();
Check(TOKlparen);
while (m_pToken->m_type != TOKrparen) {
if (pExpression) {
delete pExpression;
}
pExpression = ParseSimpleExpression();
if (m_pToken->m_type == TOKcomma) {
NextToken();
} else {
break;
}
}
Check(TOKrparen);
if (m_pToken->m_type != TOKthen) {
if (pExpression) {
delete pExpression;
}
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);
pIfExpression = ParseBlockExpression();
switch (m_pToken->m_type) {
case TOKeof:
case TOKendif:
Check(TOKendif);
break;
case TOKif:
pElseExpression = ParseIfExpression();
Check(TOKendif);
break;
case TOKelseif:
pElseExpression = ParseIfExpression();
break;
case TOKelse:
NextToken();
pElseExpression = 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;
}
CXFA_FMIfExpression* pExp = 0;
if (m_pErrorInfo->message.IsEmpty()) {
pExp = new CXFA_FMIfExpression(line, pExpression, pIfExpression,
pElseExpression);
} else {
if (pExpression) {
delete pExpression;
}
if (pIfExpression) {
delete pIfExpression;
}
if (pElseExpression) {
delete pElseExpression;
}
}
return pExp;
}
CXFA_FMExpression* CXFA_FMParse::ParseWhileExpression() {
CXFA_FMExpression* e = 0;
CXFA_FMSimpleExpression* pCondition = 0;
CXFA_FMExpression* pExpression = 0;
FX_DWORD line = m_pToken->m_uLinenum;
NextToken();
pCondition = ParseParenExpression();
Check(TOKdo);
pExpression = ParseBlockExpression();
Check(TOKendwhile);
if (!m_pErrorInfo->message.IsEmpty()) {
if (pCondition) {
delete pCondition;
}
if (pExpression) {
delete pExpression;
}
delete e;
e = 0;
} else {
e = new CXFA_FMWhileExpression(line, pCondition, pExpression);
}
return e;
}
CXFA_FMSimpleExpression* CXFA_FMParse::ParseSubassignmentInForExpression() {
CXFA_FMSimpleExpression* e = 0;
switch (m_pToken->m_type) {
case TOKidentifier:
e = 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;
}
CXFA_FMExpression* CXFA_FMParse::ParseForExpression() {
CXFA_FMExpression* e = 0;
CFX_WideStringC wsVariant;
CXFA_FMSimpleExpression* pAssignment = 0;
CXFA_FMSimpleExpression* pAccessor = 0;
CXFA_FMSimpleExpression* pStep = 0;
CXFA_FMExpression* pList = 0;
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();
if (m_pToken->m_type == TOKassign) {
NextToken();
pAssignment = 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();
pAccessor = ParseSimpleExpression();
if (m_pToken->m_type == TOKstep) {
NextToken();
pStep = ParseSimpleExpression();
}
Check(TOKdo);
pList = ParseBlockExpression();
Check(TOKendfor);
if (m_pErrorInfo->message.IsEmpty()) {
e = new CXFA_FMForExpression(line, wsVariant, pAssignment, pAccessor,
iDirection, pStep, pList);
} else {
if (pAssignment) {
delete pAssignment;
}
if (pAccessor) {
delete pAccessor;
}
if (pStep) {
delete pStep;
}
if (pList) {
delete pList;
}
}
return e;
}
CXFA_FMExpression* CXFA_FMParse::ParseForeachExpression() {
CXFA_FMExpression* e = 0;
CFX_WideStringC wsIdentifier;
CFX_PtrArray* pAccessors = 0;
CXFA_FMExpression* pList = 0;
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 = 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 = ParseBlockExpression();
Check(TOKendfor);
if (m_pErrorInfo->message.IsEmpty()) {
e = new CXFA_FMForeachExpression(line, wsIdentifier, pAccessors, pList);
} else {
if (pAccessors) {
CXFA_FMSimpleExpression* s = 0;
int32_t size = pAccessors->GetSize();
int32_t index = 0;
while (index < size) {
s = (CXFA_FMSimpleExpression*)pAccessors->GetAt(index);
delete s;
index++;
}
pAccessors->RemoveAll();
delete pAccessors;
pAccessors = 0;
}
if (pList) {
delete pList;
}
}
return e;
}
CXFA_FMExpression* CXFA_FMParse::ParseDoExpression() {
CXFA_FMExpression* e = 0;
FX_DWORD line = m_pToken->m_uLinenum;
NextToken();
e = ParseBlockExpression();
Check(TOKend);
if (m_pErrorInfo->message.IsEmpty()) {
e = new CXFA_FMDoExpression(line, e);
} else {
delete e;
e = 0;
}
return e;
}