// Ryzom - MMORPG Framework
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
/* A Bison parser, made by GNU Bison 1.875. */
/* Skeleton parser for Yacc-like parsing with Bison,
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* As a special exception, when this file is copied by Bison into a
Bison output file, you may use that output file without restriction.
This special exception was added by the Free Software Foundation
in version 1.24 of Bison. */
/* Written by Richard Stallman by simplifying the original so called
``semantic'' parser. */
/* All symbols defined below should begin with yy or YY, to avoid
infringing on user name space. This should be done even for local
variables, as they might otherwise be expanded by user macros.
There are some unavoidable exceptions within include files to
define necessary library symbols; they are noted "INFRINGES ON
USER NAME SPACE" below. */
/* Identify Bison output. */
#define YYBISON 1
/* Skeleton name. */
#define YYSKELETON_NAME "yacc.c"
/* Pure parsers. */
#define YYPURE 0
/* Using locations. */
#define YYLSP_NEEDED 0
/* If NAME_PREFIX is specified substitute the variables and functions
names. */
#define yyparse aiparse
#define yylex ailex
#define yyerror aierror
#define yylval ailval
#define yychar aichar
#define yydebug aidebug
#define yynerrs ainerrs
/* Tokens. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
/* Put the tokens into the symbol table, so that GDB and other debuggers
know about them. */
enum yytokentype {
TOKEN_IF = 258,
TOKEN_ELSE = 259,
TOKEN_WHILE = 260,
TOKEN_PRINT = 261,
TOKEN_LOG = 262,
TOKEN_CASE = 263,
TOKEN_POINT = 264,
TOKEN_SEPARATOR = 265,
TOKEN_PV = 266,
TOKEN_PP = 267,
TOKEN_LP = 268,
TOKEN_LA = 269,
TOKEN_RP = 270,
TOKEN_RA = 271,
TOKEN_ASSIGNATOR = 272,
TOKEN_SWITCH = 273,
TOKEN_RAND = 274,
TOKEN_NUMBER = 275,
TOKEN_ONCHILDREN = 276,
TOKEN_CHAIN = 277,
TOKEN_NAME = 278,
TOKEN_STRNAME = 279,
TOKEN_CTXNAME = 280,
TOKEN_LOGIC = 281,
TOKEN_INCRDECR = 282,
TOKEN_ADD = 283,
TOKEN_SUB = 284,
TOKEN_COMP = 285,
TOKEN_ASSIGN = 286,
TOKEN_FACTOR = 287
};
#endif
#define TOKEN_IF 258
#define TOKEN_ELSE 259
#define TOKEN_WHILE 260
#define TOKEN_PRINT 261
#define TOKEN_LOG 262
#define TOKEN_CASE 263
#define TOKEN_POINT 264
#define TOKEN_SEPARATOR 265
#define TOKEN_PV 266
#define TOKEN_PP 267
#define TOKEN_LP 268
#define TOKEN_LA 269
#define TOKEN_RP 270
#define TOKEN_RA 271
#define TOKEN_ASSIGNATOR 272
#define TOKEN_SWITCH 273
#define TOKEN_RAND 274
#define TOKEN_NUMBER 275
#define TOKEN_ONCHILDREN 276
#define TOKEN_CHAIN 277
#define TOKEN_NAME 278
#define TOKEN_STRNAME 279
#define TOKEN_CTXNAME 280
#define TOKEN_LOGIC 281
#define TOKEN_INCRDECR 282
#define TOKEN_ADD 283
#define TOKEN_SUB 284
#define TOKEN_COMP 285
#define TOKEN_ASSIGN 286
#define TOKEN_FACTOR 287
/* Copy the first part of user declarations. */
#line 1 "ai_service/script_parser.yacc"
#include "stdpch.h"
#include "script_compiler.h"
#include
using namespace std;
using namespace NLMISC;
using namespace AIVM;
using namespace AICOMP;
// Define this to output verbose debug parsing info
//#define AI_COMP_DEBUG
extern int aierrorline (const char *s, int);
extern int aierror (const char *s);
extern int ailex ();
extern int aiparse ();
extern void addSignature (char *dest, char *src);
extern int aiErrorCount;
extern int aiLine;
extern char aiFile[512];
extern const char *aiInputScript;
extern uint aiInputScriptLength;
extern void aiClean ();
extern int aidebug; /* nonzero means print parse trace */
#define fprintf myfprintf
int myfprintf (FILE *file, const char *format, ...)
{
int result;
va_list args;
va_start( args, format );
if (file == stderr)
{
char buffer[1024];
result = vsnprintf(buffer, 1024, format, args);
nldebug (buffer);
}
else
{
result = vfprintf (file, format, args);
}
va_end( args );
return result;
}
std::vector *aiRoot;
string aiErrorMessage;
// Main method
bool aiCompile (std::vector &dest, const char *script, const char *scriptName, bool win32Report = false)
{
#ifdef AI_COMP_DEBUG
aidebug = 1;
#else // AI_COMP_DEBUG
aidebug = 0;
#endif // AI_COMP_DEBUG
aiLine = 1;
aiErrorCount = 0;
aiInputScript = script;
aiInputScriptLength = strlen (script);
strcpy (aiFile, scriptName);
aiRoot = NULL;
nldebug("script compilation of %s", scriptName);
aiErrorMessage = toString ("script compilation of %s\n", scriptName);
int err = aiparse();
bool error = err || aiErrorCount;
if (error)
{
nlwarning ("compilation failed for %s - %d error(s)", scriptName, aiErrorCount);
aiErrorMessage += toString ("compilation failed for %s - %d error(s)\n", scriptName, aiErrorCount);
}
else
{
nlassert (aiRoot);
nldebug ("compilation success. (code size %d)", aiRoot->size()*4);
aiErrorMessage += toString ("compilation success. (code size %d)\n", aiRoot->size()*4);
dest = *aiRoot;
}
#ifdef NL_OS_WINDOWS
if (win32Report)
MessageBoxA (NULL, aiErrorMessage.c_str (), "AI Script Compiler", MB_OK|(error?MB_ICONEXCLAMATION:MB_ICONINFORMATION));
#endif // NL_OS_WINDOWS
// Clean all
aiClean ();
return !error;
}
/* The parsing tree is composed of different types of node:
- Opcode for terminal opcode node
- ByteCode for a bunch of code node
- ByteCodeList for bunch of code when maintening substructure is important (for rand)
- Case for storing case index and code
- Cases for storing list of case
Opcode, ByteCode and ByteCodeList can be appended to a ByteCode node.
*/
// Memory to delete
vector *> NodeToClear;
vector *> *> ListToClear;
vector CaseToClear;
vector