/*
* This file is part of ZigBrains.
*
* Copyright (C) 2023-2025 FalsePattern
* All Rights Reserved
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* ZigBrains is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, only version 3 of the License.
*
* ZigBrains 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with ZigBrains. If not, see .
*/
package com.falsepattern.zigbrains.zon.lexer;
import com.intellij.lexer.FlexLexer;
import com.intellij.psi.tree.IElementType;
import static com.intellij.psi.TokenType.WHITE_SPACE;
import static com.intellij.psi.TokenType.BAD_CHARACTER;
import static com.falsepattern.zigbrains.zon.psi.ZonTypes.*;
%%
%class ZonFlexLexer
%implements FlexLexer
%function advance
%type IElementType
%unicode
WHITE_SPACE=\s+
// visual studio parity
LF=\r\n?|[\n\u0085\u2028\u2029]
bin=[01]
bin_="_"? {bin}
oct=[0-7]
oct_="_"? {oct}
hex=[0-9a-fA-F]
hex_="_"? {hex}
dec=[0-9]
dec_="_"? {dec}
bin_int={bin} {bin_}*
oct_int={oct} {oct_}*
dec_int={dec} {dec_}*
hex_int={hex} {hex_}*
char_char= \\ .
| [^\'\r\n\u0085\u2028\u2029]
string_char= \\ .
| [^\"\r\n\u0085\u2028\u2029]
nl_wrap={LF} (\s|{LF})*
all_no_nl=[^\r\n\u0085\u2028\u2029]+
FLOAT= "0x" {hex_int} "." {hex_int} ([pP] [-+]? {dec_int})?
| {dec_int} "." {dec_int} ([eE] [-+]? {dec_int})?
| "0x" {hex_int} [pP] [-+]? {dec_int}
| {dec_int} [eE] [-+]? {dec_int}
INTEGER= "0b" {bin_int}
| "0o" {oct_int}
| "0x" {hex_int}
| {dec_int}
IDENTIFIER_PLAIN=[A-Za-z_][A-Za-z0-9_]*
%state STR_LIT
%state STR_MULT_LINE
%state CHAR_LIT
%state ID_QUOT
%state UNT_SQUOT
%state UNT_DQUOT
%state CMT_LINE
%%
//Comments
"//" { yybegin(CMT_LINE); }
{all_no_nl} { }
{nl_wrap} "//" { }
\R { yybegin(YYINITIAL); return LINE_COMMENT; }
<> { yybegin(YYINITIAL); return LINE_COMMENT; }
//Symbols
"." { return DOT; }
"=" { return EQUAL; }
"{" { return LBRACE; }
"}" { return RBRACE; }
"," { return COMMA; }
//Keywords
"false" { return KEYWORD_FALSE; }
"true" { return KEYWORD_TRUE; }
"null" { return KEYWORD_NULL; }
"nan" { return NUM_NAN; }
"inf" { return NUM_INF; }
//Strings
"'" { yybegin(CHAR_LIT); }
{char_char}*"'" { yybegin(YYINITIAL); return CHAR_LITERAL; }
<> { yybegin(YYINITIAL); return BAD_SQUOT; }
[^] { yypushback(1); yybegin(UNT_SQUOT); }
"\"" { yybegin(STR_LIT); }
{string_char}*"\"" { yybegin(YYINITIAL); return STRING_LITERAL_SINGLE; }
<> { yybegin(YYINITIAL); return BAD_DQUOT; }
[^] { yypushback(1); yybegin(UNT_DQUOT); }
"\\\\" { yybegin(STR_MULT_LINE); }
{all_no_nl} { }
{nl_wrap} "\\\\" { }
{LF} { yybegin(YYINITIAL); return STRING_LITERAL_MULTI; }
<> { yybegin(YYINITIAL); return STRING_LITERAL_MULTI; }
//Numbers
{FLOAT} { return FLOAT; }
{INTEGER} { return INTEGER; }
//Identifiers
{IDENTIFIER_PLAIN} { return IDENTIFIER; }
"@\"" { yybegin(ID_QUOT); }
{string_char}*"\"" { yybegin(YYINITIAL); return IDENTIFIER; }
<> { yybegin(YYINITIAL); return BAD_DQUOT; }
[^] { yypushback(1); yybegin(UNT_DQUOT); }
//Error handling
<> { yybegin(YYINITIAL); return BAD_SQUOT; }
{LF} { yybegin(YYINITIAL); return BAD_SQUOT; }
{all_no_nl} { }
<> { yybegin(YYINITIAL); return BAD_DQUOT; }
{LF} { yybegin(YYINITIAL); return BAD_DQUOT; }
{all_no_nl} { }
//Misc
{WHITE_SPACE} { return WHITE_SPACE; }
[^] { return BAD_CHARACTER; }