openmohaa/code/parser/lex_source.txt

298 lines
8.2 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>
void fprintf2( FILE *f, const char *format, ... )
{
va_list va;
static char buffer[ 4200 ];
va_start( va, format );
vsprintf( buffer, format, va );
va_end( va );
gi.Printf( buffer );
2016-03-27 11:49:47 +02:00
}
#define fprintf fprintf2
int prev_yylex = 0;
extern yyparsedata parsedata;
#define YYLLOCSET { yylval.s.sourcePos = parsedata.pos - yyleng; }
#define YYLEX(n) { prev_yylex = n; return n; }
#define YY_USER_ACTION parsedata.pos; parsedata.pos += yyleng;
#define YY_FATAL_ERROR( n ) yylexerror( n )
void yylexerror( const char *msg )
{
gi.Printf( "%s\n%s", msg, yytext );
2016-03-27 11:49:47 +02:00
assert( 0 );
}
static void TextEscapeValue( char *str, size_t len )
2016-03-27 11:49:47 +02:00
{
char *to = parsetree_malloc( len + 1 );
yylval.s.val.stringValue = to;
while( len )
{
if( *str == '\\' )
{
len--;
if( !len )
break;
str++;
if( *str == 'n' )
{
*to = '\n';
}
else if( *str == 't' )
{
*to = '\t';
}
else if( *str == '"' )
{
*to = '\"';
}
else
{
*to = *str;
}
}
else
{
*to = *str;
}
len--;
str++;
to++;
}
*to = 0;
}
static void TextValue( char *str, size_t len )
2016-03-27 11:49:47 +02:00
{
yylval.s.val.stringValue = parsetree_malloc( len + 1 );
strncpy( yylval.s.val.stringValue, str, len );
yylval.s.val.stringValue[ len ] = 0;
}
static bool UseField( void )
{
//return prev_yylex == TOKEN_PERIOD || prev_yylex == TOKEN_DOLLAR;
return ( !strncmp( yytext, "game.", 5 ) ||
!strncmp( yytext, "group.", 6 ) ||
!strncmp( yytext, "level.", 6 ) ||
!strncmp( yytext, "local.", 6 ) ||
!strncmp( yytext, "parm.", 5 ) ||
!strncmp( yytext, "owner.", 6 ) ||
!strncmp( yytext, "self.", 5 ) ||
*yytext == '$' || *yytext == '-' || *yytext == '/' );
}
%}
/*%option debug*/
2016-03-27 11:49:47 +02:00
%option warn nodefault
%option noyywrap never-interactive
%option yylineno
%x C_COMMENT
%x C_LINE_COMMENT
%x VARIABLES
%x IDENTIFIER
2023-06-17 17:00:17 +02:00
string ([^\\\"]|\\.)*
identifier [^\{\}\(\)\[\]\r\n\,:; \t]
alphanum [a-zA-Z0-9_]+
varname [a-zA-Z0-9_\"]+
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 ); }
<VARIABLES>[\r\n]* { BEGIN( INITIAL ); YYLEX( TOKEN_EOL ); }
<VARIABLES>"size" { YYLEX( TOKEN_SIZE ); }
<VARIABLES>"." { YYLEX( TOKEN_PERIOD ); }
<VARIABLES>\"([^\\\"]|\\.)*\" { YYLLOCSET; TextEscapeValue( yytext + 1, strlen( yytext ) - 2 ); YYLEX( TOKEN_STRING ); }
<VARIABLES>[a-zA-Z0-9_\"]+ { YYLLOCSET; TextValue( yytext, strlen( yytext ) ); YYLEX( TOKEN_IDENTIFIER ); }
<VARIABLES>. {
for ( int i = yyleng - 1; i >= 0; --i )
unput( yytext[ i ] );
parsedata.pos -= yyleng;
BEGIN( INITIAL );
}
[\r\n]* { if( prev_yylex != TOKEN_EOL ) YYLEX( TOKEN_EOL ); }
[ \t]* { ; }
2023-06-17 17:00:17 +02:00
\"{string}\" { YYLLOCSET; TextEscapeValue( yytext + 1, strlen( yytext ) - 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 ); }
"game"? { BEGIN( VARIABLES ); yylval.s.val = node1_( method_game ); YYLEX( TOKEN_LISTENER ); }
"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 ); }
"{" { parsedata.braces_count++; YYLEX( TOKEN_LBRACKET ); }
"}" { parsedata.braces_count--; YYLEX( TOKEN_RBRACKET ); }
"(" { YYLLOCSET; YYLEX( TOKEN_LPAREN ); }
")" { BEGIN( VARIABLES ); YYLLOCSET; YYLEX( TOKEN_RPAREN ); }
"[" { YYLEX( TOKEN_LSQUARE ); }
"]" { BEGIN( VARIABLES ); YYLEX( TOKEN_RSQUARE ); }
"=" { YYLEX( TOKEN_ASSIGNMENT ); }
":" { YYLEX( TOKEN_COLON ); }
"::" { YYLEX( TOKEN_DOUBLE_COLON ); }
";" { YYLEX( TOKEN_SEMICOLON ); }
"==" { YYLEX( TOKEN_EQUALITY ); }
"||" { YYLEX( TOKEN_LOGICAL_OR ); }
"&&" { YYLEX( TOKEN_LOGICAL_AND ); }
"|" { YYLEX( TOKEN_BITWISE_OR ); }
"^" { YYLEX( TOKEN_BITWISE_EXCL_OR ); }
"&" { YYLEX( TOKEN_BITWISE_AND ); }
"!=" { YYLEX( TOKEN_INEQUALITY ); }
"<" { YYLEX( TOKEN_LESS_THAN ); }
">" { YYLEX( TOKEN_GREATER_THAN ); }
"<=" { YYLEX( TOKEN_LESS_THAN_OR_EQUAL ); }
">=" { YYLEX( TOKEN_GREATER_THAN_OR_EQUAL ); }
[ ]"-" { YYLEX( TOKEN_NEG ); }
"+" { YYLEX( TOKEN_PLUS ); }
"+=" { YYLEX( TOKEN_PLUS_EQUALS ); }
"++"|[ ]"++" { YYLEX( TOKEN_INCREMENT ); }
"-"|"-"[ ]|[ ]"-"[ ] { YYLEX( TOKEN_MINUS ); }
"-=" { YYLEX( TOKEN_MINUS_EQUALS ); }
[ ]"-=" { YYLEX( TOKEN_MINUS_EQUALS ); }
"--"|[ ]"--" { YYLEX( TOKEN_DECREMENT ); }
"*" { 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 ); }
"!" { YYLEX( TOKEN_NOT ); }
"~" { YYLEX( TOKEN_COMPLEMENT ); }
"." { YYLEX( TOKEN_PERIOD ); }
"," { YYLEX( TOKEN_COMMA ); }
"#" { YYLEX( TOKEN_NUMBER ); }
"NULL" { YYLEX( TOKEN_NULL ); }
"NIL" { YYLEX( TOKEN_NIL ); }
2023-06-17 17:00:17 +02:00
[0-9]+ {
char* p = nullptr;
yylval.s.val.intValue = std::strtoll(yytext, &p, 10);
YYLEX(TOKEN_INTEGER);
}
[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
"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 ); }
[a-zA-Z0-9_\./\\-]+ {
if( UseField() )
{
parsedata.pos -= yyleng;
REJECT;
}
else
{
YYLLOCSET;
TextEscapeValue( yytext, yyleng );
YYLEX( TOKEN_IDENTIFIER );
}
}
. { yylexerror( "bad token:\n" ); }
%{
#undef fprintf
%}
%%