235 lines
6.4 KiB
Plaintext
235 lines
6.4 KiB
Plaintext
/*
|
|
This file is part of Warzone 2100.
|
|
Copyright (C) 2006-2008 Roman
|
|
Copyright (C) 2006-2011 Warzone 2100 Project
|
|
|
|
Warzone 2100 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 of the License, or
|
|
(at your option) any later version.
|
|
|
|
Warzone 2100 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 Warzone 2100; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
%{
|
|
/** @file
|
|
*
|
|
* Lexical analyser for multiplayer chat messages.
|
|
*/
|
|
|
|
#include "lib/framework/frame.h"
|
|
|
|
// FIXME: #include from src/
|
|
#include "src/scriptfuncs.h"
|
|
|
|
#include "lib/script/script.h"
|
|
#include "lib/script/chat_processing.h"
|
|
|
|
/* Get the Yacc definitions */
|
|
#include "chat_parser.tab.hpp"
|
|
|
|
// fwrite declared with warn_unused_result, resulting in mysterious errors in "%%" on some distros.
|
|
static inline bool no_warn_unused_result(int ignore) { if (ignore) {} return true; }
|
|
#define fwrite(a, b, c, d) no_warn_unused_result(fwrite(a, b, c, d))
|
|
|
|
/* Maximum length for any TEXT value */
|
|
#ifndef YYLMAX
|
|
#define YYLMAX 255
|
|
#endif
|
|
|
|
#if defined(YY_FLEX_SUBMINOR_VERSION) && YY_FLEX_SUBMINOR_VERSION == 33
|
|
extern int chat_get_lineno(void);
|
|
extern FILE *chat_get_in(void);
|
|
extern FILE *chat_get_out(void);
|
|
extern int chat_get_leng(void);
|
|
extern char *chat_get_text(void);
|
|
extern void chat_set_lineno(int line_number);
|
|
extern void chat_set_in(FILE* in_str);
|
|
extern void chat_set_out(FILE* out_str);
|
|
extern int chat_get_debug(void);
|
|
extern void chat_set_debug(int bdebug);
|
|
extern int chat_lex_destroy(void);
|
|
#endif
|
|
|
|
/* Pointer to the input buffer */
|
|
static const char *pInputBuffer = NULL;
|
|
static const char *pEndBuffer = NULL;
|
|
|
|
static SDWORD playerIndex;
|
|
|
|
#undef YY_INPUT
|
|
#define YY_INPUT(buf,result,max_size) \
|
|
if (pInputBuffer != pEndBuffer) { \
|
|
buf[0] = *(pInputBuffer++); result = 1; \
|
|
} else { \
|
|
buf[0] = EOF; result = YY_NULL; \
|
|
}
|
|
|
|
#undef chat_getc
|
|
#define chat_getc() (pInputBuffer != pEndBuffer ? *(pInputBuffer++) : EOF)
|
|
|
|
%}
|
|
|
|
%option yylineno
|
|
%option prefix="chat_"
|
|
%option nounput
|
|
%option case-insensitive
|
|
%option never-interactive
|
|
|
|
%%
|
|
|
|
/* Match integer numbers */
|
|
-?[0-9]+ { chat_lval.ival = atol(chat_text); return R_INTEGER; }
|
|
|
|
/* Keywords - Terminals */
|
|
"'s" { return R_POSSESSION; }
|
|
"?"+ { return _T_QM; }
|
|
"!"+ { return _T_EM; }
|
|
"."+ { return _T_FULLSTOP; }
|
|
":" { return _T_COLON; };
|
|
";" { return _T_SEMICOLON; };
|
|
"," { return _T_COMMA; };
|
|
"a" { return _T_A; }
|
|
"affirmative" { return _T_AFFIRMATIVE; }
|
|
"after" { return _T_AFTER; }
|
|
"ally" { return _T_ALLY; }
|
|
"am" { return _T_AM; }
|
|
"an" { return _T_AN; }
|
|
"and" { return _T_AND; }
|
|
"any" { return _T_ANY; }
|
|
"attack" { return _T_ATTACK; }
|
|
"attacking" { return _T_ATTACKING; }
|
|
"army" { return _T_ARMY; }
|
|
"beacon" { return _T_BEACON; }
|
|
"building" { return _T_BUILDING; }
|
|
"can't" { return _T_CANT; }
|
|
"center" { return _T_CENTER; }
|
|
"dead" { return _T_DEAD; }
|
|
"derrick" { return _T_DERRICK; }
|
|
"do" { return _T_DO; }
|
|
"drop" { return _T_DROP; }
|
|
"fine" { return _T_FINE; }
|
|
"for" { return _T_FOR; }
|
|
"force" { return _T_FORCE; }
|
|
"get" { return _T_GET; }
|
|
"getting" { return _T_GETTING; }
|
|
"go" { return _T_GO; }
|
|
"going" { return _T_GOING; }
|
|
"gonna" { return _T_GONNA; }
|
|
"got" { return _T_GOT; }
|
|
"great" { return _T_GREAT; }
|
|
"have" { return _T_HAVE; }
|
|
"has" { return _T_HAS; }
|
|
"help" { return _T_HELP; }
|
|
"hold" { return _T_HOLD; }
|
|
"i" { return _T_I; }
|
|
"i'm" { return _T_IM; }
|
|
"is" { return _T_IS; }
|
|
"lassat" { return _T_LASSAT; }
|
|
"let's" { return _T_LETS; }
|
|
"me" { return _T_ME; }
|
|
"more" { return _T_MORE; }
|
|
"need" { return _T_NEED; }
|
|
"no" { return _T_NO; }
|
|
"now" { return _T_NOW; }
|
|
"of course" { return _T_OFCOURSE; }
|
|
"ok"+ { return _T_OK; }
|
|
"on" { return _T_ON; }
|
|
"place" { return _T_PLACE; }
|
|
"possession" { return _T_POSSESSION; }
|
|
"power" { return _T_POWER; }
|
|
"pumping" { return _T_PUMPING; }
|
|
"put" { return _T_PUT; }
|
|
"ready" { return _T_READY; }
|
|
"require" { return _T_REQUIRE; }
|
|
"roger" { return _T_ROGER; }
|
|
"rush" { return _T_RUSH; }
|
|
"sec" { return _T_SEC; }
|
|
"see" { return _T_SEE; }
|
|
"some" { return _T_SOME; }
|
|
"status" { return _T_STATUS; }
|
|
"stop" { return _T_STOP; }
|
|
"sure" { return _T_SURE; }
|
|
"thank you" { return _T_THANK_YOU; }
|
|
"thanks" { return _T_THANKS; }
|
|
"the" { return _T_THE; }
|
|
"u" { return _T_U; }
|
|
"units" { return _T_UNITS; }
|
|
"vtols" { return _T_VTOLS; }
|
|
"wait" { return _T_WAIT; }
|
|
"where" { return _T_WHERE; }
|
|
"yea" { return _T_YES; }
|
|
"yeah" { return _T_YES; }
|
|
"yep" { return _T_YES; }
|
|
"yes" { return _T_YES; }
|
|
"you" { return _T_YOU; }
|
|
|
|
/* <<EOF>> { return _T_EOF; } */
|
|
|
|
[0-9_a-zA-Z_]* {
|
|
playerIndex = getPlayerFromString(chat_text);
|
|
|
|
if(playerIndex >= 0)
|
|
{
|
|
//console( "matched 'player'");
|
|
chat_lval.ival = playerIndex;
|
|
|
|
return R_PLAYER;
|
|
}
|
|
|
|
}
|
|
|
|
/* [^ \t\n\<\>\[\]\(\)]+ { return T_WORD; } */
|
|
/* [^ \t\n]+ { console( "matched 'T_WORD'"); return T_WORD; } */
|
|
|
|
|
|
/* Skip white space */
|
|
[ \t\n\x0d\x0a] ;
|
|
|
|
|
|
/* Match anything that's been missed and pass it as a char */
|
|
/* . {console( "matched 'anything else '%s'", chat_text[0]); return chat_text[0];} */
|
|
|
|
%%
|
|
|
|
/* Set the current input buffer for the lexer */
|
|
void chatSetInputBuffer(char *pBuffer, UDWORD size)
|
|
{
|
|
pInputBuffer = pBuffer;
|
|
pEndBuffer = pBuffer + size;
|
|
|
|
/* Reset the lexer in case it's been used before */
|
|
chat__flush_buffer(YY_CURRENT_BUFFER);
|
|
}
|
|
|
|
void chatGetErrorData(int *pLine, char **ppText)
|
|
{
|
|
*pLine = chat_lineno;
|
|
*ppText = chat_text;
|
|
}
|
|
|
|
int chat_wrap(void)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
|
|
/* Older GNU Flex versions don't define yylex_destroy()
|
|
* (and neither define a subminor version)
|
|
*/
|
|
#if !defined(YY_FLEX_SUBMINOR_VERSION) || (YY_FLEX_SUBMINOR_VERSION < 9)
|
|
int chat_lex_destroy(void)
|
|
{
|
|
/* For non-reentrant C scanner only. */
|
|
yy_delete_buffer(YY_CURRENT_BUFFER);
|
|
yy_init = 1;
|
|
return 0;
|
|
}
|
|
#endif
|