openmohaa/code/parser/lex_source.txt

419 lines
11 KiB
Text
Raw Normal View History

2016-03-27 11:49:47 +02:00
%{
/*
* ===========================================================================
* Copyright (C) 2015 the OpenMoHAA team
*
* This file is part of OpenMoHAA source code.
*
* OpenMoHAA source code 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.
*
* OpenMoHAA source code 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 OpenMoHAA source code; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* ===========================================================================
*
*
* yyLexer.*: FLEX Lexical grammar for MoHScript.
*/
#include "scriptcompiler.h"
#include "./yyParser.hpp"
2016-03-27 11:49:47 +02:00
#include <stdio.h>
2025-02-14 23:54:15 +01:00
void fprintf2(FILE * f, const char *format, ...)
2016-03-27 11:49:47 +02:00
{
2025-02-14 23:54:15 +01:00
va_list va;
static char buffer[4200];
2016-03-27 11:49:47 +02:00
2025-02-14 23:54:15 +01:00
va_start(va, format);
vsprintf(buffer, format, va);
va_end(va);
2016-03-27 11:49:47 +02:00
2025-02-14 23:54:15 +01:00
gi.Printf(buffer);
2016-03-27 11:49:47 +02:00
}
#define fprintf fprintf2
2025-02-14 23:54:15 +01:00
const char *start_ptr;
const char *in_ptr;
extern int prev_yylex;
extern int out_pos;
extern int success_pos;
2023-08-12 19:59:40 +02:00
parseStage_e parseStage;
2016-03-27 11:49:47 +02:00
extern yyparsedata parsedata;
2025-02-14 23:54:15 +01:00
void yyllocset(YYLTYPE * loc, uint32_t off)
2023-08-12 19:59:40 +02:00
{
2025-02-14 23:54:15 +01:00
success_pos = out_pos - yyleng + off;
loc->sourcePos = success_pos;
parsedata.pos = success_pos;
2023-08-12 19:59:40 +02:00
}
void yyreducepos(uint32_t off)
{
2025-02-14 23:54:15 +01:00
out_pos -= off;
2023-08-12 19:59:40 +02:00
}
2025-02-14 23:54:15 +01:00
#define YYLEX(n) \
{ \
yyllocset(&yylloc, 0); \
prev_yylex = n; \
return n; \
}
#define YYLEXOFF(n, off) \
{ \
yyllocset(&yylloc, off); \
prev_yylex = n; \
return n; \
}
#define YY_USER_ACTION \
{ \
out_pos += yyleng - yy_more_len; \
yylloc.sourcePos = out_pos; \
parsedata.pos = out_pos; \
}
#define YY_FATAL_ERROR(n) yylexerror(n)
void yylexerror(const char *msg)
2016-03-27 11:49:47 +02:00
{
2025-02-14 23:54:15 +01:00
gi.DPrintf("%s\n%s", msg, yytext);
assert(0);
2016-03-27 11:49:47 +02:00
}
2025-02-14 23:54:15 +01:00
static void TextEscapeValue(char *str, size_t len)
2016-03-27 11:49:47 +02:00
{
2025-02-14 23:54:15 +01:00
char *to = parsetree_malloc(len + 1);
yylval.s.val.stringValue = to;
while (len) {
if (*str == '\\') {
if (len == 1) {
break;
}
if (str[1] == 'n') {
*to = '\n';
to++;
} else if (str[1] == 't') {
*to = '\t';
to++;
} else if (str[1] == '"') {
*to = '\"';
to++;
} else {
*to = str[1];
to++;
}
len -= 2;
str += 2;
} else {
*to = *str;
to++;
len--;
str++;
}
}
*to = 0;
2016-03-27 11:49:47 +02:00
}
2025-02-14 23:54:15 +01:00
static void TextValue(char *str, size_t len)
2016-03-27 11:49:47 +02:00
{
2025-02-14 23:54:15 +01:00
char *s = parsetree_malloc(len + 1);
strncpy(s, str, len);
s[len] = 0;
yylval.s.val.stringValue = s;
2016-03-27 11:49:47 +02:00
}
2025-02-14 23:54:15 +01:00
static bool UseField(void)
2016-03-27 11:49:47 +02:00
{
2025-02-14 23:54:15 +01:00
return prev_yylex == TOKEN_PERIOD || prev_yylex == TOKEN_DOLLAR;
2016-03-27 11:49:47 +02:00
}
2023-08-13 03:33:50 +02:00
#define YY_INPUT(buf,result,max_size) \
{ \
char c; \
int n; \
\
c = '*'; \
for(n = 0; n < max_size; n++) \
{ \
c = *in_ptr++; \
if (!c || c == '\n') { \
break; \
} \
\
buf[n] = c; \
} \
\
if (c == '\n') \
{ \
buf[n++] = c; \
} \
else if (!c) \
{ \
in_ptr--; \
} \
\
result = n; \
}
2016-03-27 11:49:47 +02:00
%}
/*%option debug*/
2016-03-27 11:49:47 +02:00
%option warn nodefault
2023-08-12 19:59:40 +02:00
%option never-interactive
2016-03-27 11:49:47 +02:00
%option yylineno
2023-08-13 03:33:50 +02:00
%x SCRIPT
2016-03-27 11:49:47 +02:00
%x C_COMMENT
%x C_LINE_COMMENT
%x VARIABLES
%x IDENTIFIER
string ([^\\\"\r\n]|\\.)*
2023-06-17 17:00:17 +02:00
identifier [^\{\}\(\)\[\]\r\n\,:; \t]
nonexpr [0-9a-zA-Z_\"'?@#`\.\x80-\xff]
nonnumeric [a-zA-Z_\"'?@#`\x80-\xff]
2023-06-17 17:00:17 +02:00
alphanum [a-zA-Z0-9_]+
2025-02-14 23:54:15 +01:00
varname [a-zA-Z0-9_\"$\\]+
2023-06-17 17:00:17 +02:00
2016-03-27 11:49:47 +02:00
%%
"/*" { BEGIN( C_COMMENT ); }
<C_COMMENT>"*/" { BEGIN( INITIAL ); }
<C_COMMENT>\n { ; }
<C_COMMENT>. { ; }
"*/" { Compiler.CompileError( parsedata.pos - yyleng, "'*/' found outside of comment" ); }
2017-07-07 19:19:46 +02:00
\\[\r\n]+ { ; }
2016-03-27 11:49:47 +02:00
"//"[^\r\n]* { if( prev_yylex != TOKEN_EOL ) YYLEX( TOKEN_EOL ); }
2024-10-30 23:21:05 +01:00
<VARIABLES>"size" { BEGIN(INITIAL); YYLEX(TOKEN_SIZE); }
<VARIABLES>[ \t]*\./([0-9]*[^0-9[:space:]]) { YYLEX(TOKEN_PERIOD); }
2024-10-30 23:21:05 +01:00
<VARIABLES>\"{string}\" { BEGIN(INITIAL); TextEscapeValue(yytext + 1, strlen( yytext ) - 2 ); YYLEX(TOKEN_STRING); }
<VARIABLES>{varname} {
2025-02-14 23:54:15 +01:00
TextEscapeValue(yytext, strlen(yytext));
2024-10-30 23:21:05 +01:00
YYLEX(TOKEN_IDENTIFIER);
}
<VARIABLES>[ \t\r\n] {
BEGIN(INITIAL);
unput(yytext[yyleng - 1]);
yyreducepos(1);
}
<VARIABLES>. {
BEGIN(INITIAL);
unput(yytext[yyleng - 1]);
yyreducepos(1);
}
2016-03-27 11:49:47 +02:00
\"{string}\"{nonexpr} {
BEGIN(IDENTIFIER);
yymore();
}
\"{string}\" { TextEscapeValue( yytext + 1, yyleng - 2 ); YYLEX( TOKEN_STRING ); }
2016-03-27 11:49:47 +02:00
"?" { YYLEX( TOKEN_TERNARY ); }
"if" { YYLEX( TOKEN_IF ); }
"else" { YYLEX( TOKEN_ELSE ); }
"while" { YYLEX( TOKEN_WHILE ); }
"for" { YYLEX( TOKEN_FOR ); }
"do" { YYLEX( TOKEN_DO ); }
2023-08-13 03:33:50 +02:00
"game" { BEGIN( VARIABLES ); yylval.s.val = node1_( method_game ); YYLEX( TOKEN_LISTENER ); }
2016-03-27 11:49:47 +02:00
"group" { BEGIN( VARIABLES ); yylval.s.val = node1_( method_group ); YYLEX( TOKEN_LISTENER ); }
"level" { BEGIN( VARIABLES ); yylval.s.val = node1_( method_level ); YYLEX( TOKEN_LISTENER ); }
"local" { BEGIN( VARIABLES ); yylval.s.val = node1_( method_local ); YYLEX( TOKEN_LISTENER ); }
"parm" { BEGIN( VARIABLES ); yylval.s.val = node1_( method_parm ); YYLEX( TOKEN_LISTENER ); }
"owner" { BEGIN( VARIABLES ); yylval.s.val = node1_( method_owner ); YYLEX( TOKEN_LISTENER ); }
"self" { BEGIN( VARIABLES ); yylval.s.val = node1_( method_self ); YYLEX( TOKEN_LISTENER ); }
2023-08-12 19:59:40 +02:00
"{" { parsedata.braces_count++; YYLEX( TOKEN_LEFT_BRACES ); }
"}" { parsedata.braces_count--; YYLEX( TOKEN_RIGHT_BRACES ); }
"(" { YYLEX(TOKEN_LEFT_BRACKET); }
")" { BEGIN(VARIABLES); YYLEX(TOKEN_RIGHT_BRACKET); }
"[" { YYLEX(TOKEN_LEFT_SQUARE_BRACKET); }
"]" { BEGIN(VARIABLES); YYLEX(TOKEN_RIGHT_SQUARE_BRACKET); }
2016-03-27 11:49:47 +02:00
"=" { YYLEX( TOKEN_ASSIGNMENT ); }
":" { YYLEX( TOKEN_COLON ); }
"::" { YYLEX( TOKEN_DOUBLE_COLON ); }
";" { YYLEX( TOKEN_SEMICOLON ); }
"==" { YYLEX( TOKEN_EQUALITY ); }
"ifequal" { YYLEX( TOKEN_EQUALITY ); }
"ifstrequal" { YYLEX( TOKEN_EQUALITY ); }
2016-03-27 11:49:47 +02:00
"||" { YYLEX( TOKEN_LOGICAL_OR ); }
"&&" { YYLEX( TOKEN_LOGICAL_AND ); }
"|" { YYLEX( TOKEN_BITWISE_OR ); }
"^" { YYLEX( TOKEN_BITWISE_EXCL_OR ); }
"&" { YYLEX( TOKEN_BITWISE_AND ); }
"!=" { YYLEX( TOKEN_INEQUALITY ); }
"ifnotequal" { YYLEX( TOKEN_INEQUALITY ); }
"ifstrnotequal" { YYLEX( TOKEN_INEQUALITY ); }
2016-03-27 11:49:47 +02:00
"<" { YYLEX( TOKEN_LESS_THAN ); }
"ifless" { YYLEX( TOKEN_LESS_THAN ); }
2016-03-27 11:49:47 +02:00
">" { YYLEX( TOKEN_GREATER_THAN ); }
"ifgreater" { YYLEX( TOKEN_GREATER_THAN ); }
2016-03-27 11:49:47 +02:00
"<=" { YYLEX( TOKEN_LESS_THAN_OR_EQUAL ); }
"iflessequal" { YYLEX( TOKEN_LESS_THAN_OR_EQUAL ); }
2016-03-27 11:49:47 +02:00
">=" { YYLEX( TOKEN_GREATER_THAN_OR_EQUAL ); }
"ifgreaterequal" { YYLEX( TOKEN_GREATER_THAN_OR_EQUAL ); }
[ \t]"-" { YYLEX( TOKEN_NEG ); }
2016-03-27 11:49:47 +02:00
"+" { YYLEX( TOKEN_PLUS ); }
"+=" { YYLEX( TOKEN_PLUS_EQUALS ); }
"++"|[ \t]"++" { YYLEX( TOKEN_INCREMENT ); }
"-"|"-"[ \t]|[ \t]"-"[ \t] { YYLEX( TOKEN_MINUS ); }
2016-03-27 11:49:47 +02:00
"-=" { YYLEX( TOKEN_MINUS_EQUALS ); }
[ \t]"-=" { YYLEX( TOKEN_MINUS_EQUALS ); }
"--"|[ \t]"--" { YYLEX( TOKEN_DECREMENT ); }
2016-03-27 11:49:47 +02:00
"*" { YYLEX( TOKEN_MULTIPLY ); }
"*=" { YYLEX( TOKEN_MULTIPLY_EQUALS ); }
"/" { YYLEX( TOKEN_DIVIDE ); }
"/=" { YYLEX( TOKEN_DIVIDE_EQUALS ); }
"%" { YYLEX( TOKEN_MODULUS ); }
"%=" { YYLEX( TOKEN_MODULUS_EQUALS ); }
"<<" { YYLEX( TOKEN_SHIFT_LEFT ); }
"<<=" { YYLEX( TOKEN_SHIFT_LEFT_EQUALS ); }
">>" { YYLEX( TOKEN_SHIFT_RIGHT ); }
">>=" { YYLEX( TOKEN_SHIFT_RIGHT_EQUALS ); }
"&=" { YYLEX( TOKEN_AND_EQUALS ); }
"^=" { YYLEX( TOKEN_EXCL_OR_EQUALS ); }
"|=" { YYLEX( TOKEN_OR_EQUALS ); }
[$]+ { BEGIN( VARIABLES ); YYLEX( TOKEN_DOLLAR ); }
2016-03-27 11:49:47 +02:00
"!" { YYLEX( TOKEN_NOT ); }
"~" { YYLEX( TOKEN_COMPLEMENT ); }
"." { YYLEX( TOKEN_PERIOD ); }
"," { YYLEX( TOKEN_COMMA ); }
"NULL" { YYLEX( TOKEN_NULL ); }
"NIL" { YYLEX( TOKEN_NIL ); }
2023-08-12 19:59:40 +02:00
"try" { YYLEX( TOKEN_TRY ); }
"catch" { YYLEX( TOKEN_CATCH ); }
"switch" { YYLEX( TOKEN_SWITCH ); }
"case" { YYLEX( TOKEN_CASE ); }
"break" { YYLEX( TOKEN_BREAK ); }
"continue" { YYLEX( TOKEN_CONTINUE ); }
"makearray"|"makeArray" { YYLEX( TOKEN_MAKEARRAY ); }
"endarray"|"endArray" { YYLEX( TOKEN_ENDARRAY ); }
2023-08-13 03:33:50 +02:00
[\r\n]+ { if (prev_yylex != TOKEN_EOL) YYLEX(TOKEN_EOL); }
2023-08-12 19:59:40 +02:00
[ \t] { ; }
[0-9]+ {
2023-06-17 17:00:17 +02:00
char* p = nullptr;
2023-08-12 19:59:40 +02:00
yylval.s.val.intValue = std::strtol(yytext, &p, 10);
2023-06-17 17:00:17 +02:00
YYLEX(TOKEN_INTEGER);
}
[0-9\.]+{nonnumeric} {
BEGIN(IDENTIFIER);
yymore();
}
2023-06-17 17:00:17 +02:00
[0-9\.]+|[0-9\.]+("e+"|"e-")+[0-9\.] {
char* p = nullptr;
yylval.s.val.floatValue = std::strtof(yytext, &p);
YYLEX(TOKEN_FLOAT);
}
2016-03-27 11:49:47 +02:00
2023-08-12 19:59:40 +02:00
<IDENTIFIER>{identifier}* {
BEGIN(INITIAL);
TextEscapeValue(yytext, yyleng);
YYLEX(TOKEN_IDENTIFIER);
}
<IDENTIFIER>[ \t\r\n] {
BEGIN(INITIAL);
unput(yytext[yyleng - 1]);
yyreducepos(1);
TextEscapeValue(yytext, yyleng - 1);
YYLEXOFF(TOKEN_IDENTIFIER, 1);
}
<IDENTIFIER>. {
BEGIN(INITIAL);
unput(yytext[yyleng - 1]);
yyreducepos(1);
TextEscapeValue(yytext, yyleng - 1);
YYLEXOFF(TOKEN_IDENTIFIER, 1);
}
2016-03-27 11:49:47 +02:00
2023-08-12 19:59:40 +02:00
{identifier} {
BEGIN(IDENTIFIER);
yymore();
}
2016-03-27 11:49:47 +02:00
[a-zA-Z0-9_]+ {
2023-08-12 19:59:40 +02:00
BEGIN(IDENTIFIER);
yymore();
2016-03-27 11:49:47 +02:00
}
2023-08-13 03:33:50 +02:00
<SCRIPT>[a-zA-Z0-9]+ { BEGIN(INITIAL); }
2023-08-12 19:59:40 +02:00
. { YY_FATAL_ERROR("bad token:\n"); }
2016-03-27 11:49:47 +02:00
%{
#undef fprintf
%}
%%
2023-08-13 03:33:50 +02:00
//
// Implements yywrap to always append a newline to the source
//
int yywrap(void) {
if (parseStage == PS_TYPE) {
parseStage = PS_BODY;
in_ptr = start_ptr;
out_pos = 0;
success_pos = 0;
return 0;
}
if (parseStage == PS_BODY)
{
if (YY_START == C_COMMENT)
{
Compiler.CompileError(success_pos, "unexpected end of file found in comment");
return 1;
}
parseStage = PS_BODY_END;
in_ptr = "\n";
return 0;
}
return 1;
}
void yy_init_script() {
BEGIN(SCRIPT);
}