/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
struct SbiStatement {
SbiToken eTok; void( SbiParser::*Func )(); bool bMain; // true: OK outside the SUB bool bSubr; // true: OK inside the SUB
};
}
#define Y true #define N false
const SbiStatement StmntTable [] = {
{ ATTRIBUTE, &SbiParser::Attribute, Y, Y, }, // ATTRIBUTE
{ CALL, &SbiParser::Call, N, Y, }, // CALL
{ CLOSE, &SbiParser::Close, N, Y, }, // CLOSE
{ CONST_, &SbiParser::Dim, Y, Y, }, // CONST
{ DECLARE, &SbiParser::Declare, Y, N, }, // DECLARE
{ DEFBOOL, &SbiParser::DefXXX, Y, N, }, // DEFBOOL
{ DEFCUR, &SbiParser::DefXXX, Y, N, }, // DEFCUR
{ DEFDATE, &SbiParser::DefXXX, Y, N, }, // DEFDATE
{ DEFDBL, &SbiParser::DefXXX, Y, N, }, // DEFDBL
{ DEFERR, &SbiParser::DefXXX, Y, N, }, // DEFERR
{ DEFINT, &SbiParser::DefXXX, Y, N, }, // DEFINT
{ DEFLNG, &SbiParser::DefXXX, Y, N, }, // DEFLNG
{ DEFOBJ, &SbiParser::DefXXX, Y, N, }, // DEFOBJ
{ DEFSNG, &SbiParser::DefXXX, Y, N, }, // DEFSNG
{ DEFSTR, &SbiParser::DefXXX, Y, N, }, // DEFSTR
{ DEFVAR, &SbiParser::DefXXX, Y, N, }, // DEFVAR
{ DIM, &SbiParser::Dim, Y, Y, }, // DIM
{ DO, &SbiParser::DoLoop, N, Y, }, // DO
{ ELSE, &SbiParser::NoIf, N, Y, }, // ELSE
{ ELSEIF, &SbiParser::NoIf, N, Y, }, // ELSEIF
{ ENDIF, &SbiParser::NoIf, N, Y, }, // ENDIF
{ END, &SbiParser::Stop, N, Y, }, // END
{ ENUM, &SbiParser::Enum, Y, N, }, // TYPE
{ ERASE, &SbiParser::Erase, N, Y, }, // ERASE
{ ERROR_, &SbiParser::ErrorStmnt, N, Y, }, // ERROR
{ EXIT, &SbiParser::Exit, N, Y, }, // EXIT
{ FOR, &SbiParser::For, N, Y, }, // FOR
{ FUNCTION, &SbiParser::SubFunc, Y, N, }, // FUNCTION
{ GOSUB, &SbiParser::Goto, N, Y, }, // GOSUB
{ GLOBAL, &SbiParser::Dim, Y, N, }, // GLOBAL
{ GOTO, &SbiParser::Goto, N, Y, }, // GOTO
{ IF, &SbiParser::If, N, Y, }, // IF
{ IMPLEMENTS, &SbiParser::Implements, Y, N, }, // IMPLEMENTS
{ INPUT, &SbiParser::Input, N, Y, }, // INPUT
{ LET, &SbiParser::Assign, N, Y, }, // LET
{ LINE, &SbiParser::Line, N, Y, }, // LINE, -> LINE INPUT (#i92642)
{ LINEINPUT,&SbiParser::LineInput, N, Y, }, // LINE INPUT
{ LSET, &SbiParser::LSet, N, Y, }, // LSET
{ NAME, &SbiParser::Name, N, Y, }, // NAME
{ ON, &SbiParser::On, N, Y, }, // ON
{ OPEN, &SbiParser::Open, N, Y, }, // OPEN
{ OPTION, &SbiParser::Option, Y, N, }, // OPTION
{ PRINT, &SbiParser::Print, N, Y, }, // PRINT
{ PRIVATE, &SbiParser::Dim, Y, N, }, // PRIVATE
{ PROPERTY, &SbiParser::SubFunc, Y, N, }, // FUNCTION
{ PUBLIC, &SbiParser::Dim, Y, N, }, // PUBLIC
{ REDIM, &SbiParser::ReDim, N, Y, }, // DIM
{ RESUME, &SbiParser::Resume, N, Y, }, // RESUME
{ RETURN, &SbiParser::Return, N, Y, }, // RETURN
{ RSET, &SbiParser::RSet, N, Y, }, // RSET
{ SELECT, &SbiParser::Select, N, Y, }, // SELECT
{ SET, &SbiParser::Set, N, Y, }, // SET
{ STATIC, &SbiParser::Static, Y, Y, }, // STATIC
{ STOP, &SbiParser::Stop, N, Y, }, // STOP
{ SUB, &SbiParser::SubFunc, Y, N, }, // SUB
{ TYPE, &SbiParser::Type, Y, N, }, // TYPE
{ WHILE, &SbiParser::While, N, Y, }, // WHILE
{ WITH, &SbiParser::With, N, Y, }, // WITH
{ WRITE, &SbiParser::Write, N, Y, }, // WRITE
};
rTypeArray = new SbxArray; // array for user defined types
rEnumArray = new SbxArray; // array for Enum types
bVBASupportOn = pm->IsVBASupport(); if ( bVBASupportOn )
EnableCompatibility();
}
SbiParser::~SbiParser() { }
// part of the runtime-library?
SbiSymDef* SbiParser::CheckRTLForSym(const OUString& rSym, SbxDataType eType)
{
SbxVariable* pVar = GetBasic()->GetRtl()->Find(rSym, SbxClassType::DontCare); if (!pVar) return nullptr;
if( IsEof() )
{ // AB #33133: If no sub has been created before, // the global chain must be closed here! // AB #40689: Due to the new static-handling there // can be another nGblChain, so ask for it before. if( bNewGblDefs && nGblChain == 0 )
nGblChain = aGen.Gen( SbiOpcode::JUMP_, 0 ); returnfalse;
}
// In vba it's possible to do Error.foobar ( even if it results in // a runtime error if ( eCurTok == ERROR_ && IsVBASupportOn() ) // we probably need to define a subset of keywords where this madness applies e.g. if ( IsVBASupportOn() && SymbolCanBeRedined( eCurTok ) )
{
SbiTokenizer tokens( *this );
tokens.Next(); if ( tokens.Peek() == DOT )
{
eCurTok = SYMBOL;
ePush = eCurTok;
}
} // if there's a symbol, it's either a variable (LET) // or a SUB-procedure (CALL without brackets) // DOT for assignments in the WITH-block: .A=5 if( eCurTok == SYMBOL || eCurTok == DOT )
{ if( !pProc )
Error( ERRCODE_BASIC_EXPECTED, SUB ); else
{ // for correct line and column...
Next();
Push( eCurTok );
aGen.Statement();
Symbol(nullptr);
}
} else
{
Next();
// statement parsers
constauto p = std::find_if(std::begin(StmntTable), std::end(StmntTable),
[this](auto element) { return element.eTok == eCurTok; }); if (p != std::end(StmntTable))
{ if( !pProc && !p->bMain )
Error( ERRCODE_BASIC_NOT_IN_MAIN, eCurTok ); elseif( pProc && !p->bSubr )
Error( ERRCODE_BASIC_NOT_IN_SUBR, eCurTok ); else
{ // AB #41606/#40689: Due to the new static-handling there // can be another nGblChain, so ask for it before. if( bNewGblDefs && nGblChain == 0 &&
( eCurTok == SUB || eCurTok == FUNCTION || eCurTok == PROPERTY ) )
{
nGblChain = aGen.Gen( SbiOpcode::JUMP_, 0 );
bNewGblDefs = false;
} // statement-opcode at the beginning of a sub, too, please if( ( p->bSubr && (eCurTok != STATIC || Peek() == SUB || Peek() == FUNCTION ) ) ||
eCurTok == SUB || eCurTok == FUNCTION )
aGen.Statement();
(this->*( p->Func ) )();
ErrCode nSbxErr = SbxBase::GetError(); if( nSbxErr )
{
SbxBase::ResetError();
Error( nSbxErr );
}
}
} else
Error( ERRCODE_BASIC_UNEXPECTED, eCurTok );
}
// test for the statement's end - // might also be an ELSE, as there must not necessary be a : before the ELSE!
if( !IsEos() )
{
Peek(); if( !IsEos() && eCurTok != ELSE )
{ // if the parsing has been aborted, jump over to the ":"
Error( ERRCODE_BASIC_UNEXPECTED, eCurTok ); while( !IsEos() ) Next();
}
} // The parser aborts at the end, the // next token has not been fetched yet! returntrue;
}
SbiParseStack* p = pStack; while( p )
{ // LoopVar can at the moment only be for with if( p->pWithVar ) return p->pWithVar;
p = p->pNext;
} return nullptr;
}
case CLASSMODULE:
bClassModule = true;
aGen.GetModule().SetModuleType( css::script::ModuleType::CLASS ); break; case VBASUPPORT: // Option VBASupport used to override the module mode ( in fact this must reset the mode if( Next() == NUMBER )
{ if ( nVal == 1 || nVal == 0 )
{
bVBASupportOn = ( nVal == 1 ); if ( bVBASupportOn )
{
EnableCompatibility();
} // if the module setting is different // reset it to what the Option tells us if ( bVBASupportOn != aGen.GetModule().IsVBASupport() )
{
aGen.GetModule().SetVBASupport( bVBASupportOn );
} break;
}
}
Error( ERRCODE_BASIC_EXPECTED, u"0/1"_ustr ); break; default:
Error( ERRCODE_BASIC_BAD_OPTION, eCurTok );
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.