/*
* This file is part of ZigBrains.
*
* Copyright (C) 2023-2024 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.zig.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.zig.psi.ZigTypes.*;
%%
%class ZigFlexLexer
%implements FlexLexer
%function advance
%type IElementType
CRLF=\R
WHITE_SPACE=[\s]+
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= \\ .
| [^\'\n]
string_char= \\ .
| [^\"\n]
all_nl_wrap=[^\n]* [ \n]*
all_nl_nowrap=[^\n]* \n
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_]*
BUILTINIDENTIFIER="@"[A-Za-z_][A-Za-z0-9_]*
%state STR_LIT
%state STR_MULT_LINE
%state CHAR_LIT
%state ID_QUOT
%state UNT_QUOT
%state CDOC_CMT
%state DOC_CMT
%state LINE_CMT
%%
//Comments
"//!" { yybegin(CDOC_CMT); }
{all_nl_wrap} "//!" { }
{all_nl_nowrap} { yybegin(YYINITIAL); return CONTAINER_DOC_COMMENT; }
"///" { yybegin(DOC_CMT); }
{all_nl_wrap} "///" { }
{all_nl_nowrap} { yybegin(YYINITIAL); return DOC_COMMENT; }
"//" { yybegin(LINE_CMT); }
{all_nl_wrap} "//" { }
{all_nl_nowrap} { yybegin(YYINITIAL); return LINE_COMMENT; }
//Symbols
"&" { return AMPERSAND; }
"&=" { return AMPERSANDEQUAL; }
"*" { return ASTERISK; }
"**" { return ASTERISK2; }
"*=" { return ASTERISKEQUAL; }
"*%" { return ASTERISKPERCENT; }
"*%=" { return ASTERISKPERCENTEQUAL; }
"*|" { return ASTERISKPIPE; }
"*|=" { return ASTERISKPIPEEQUAL; }
"^" { return CARET; }
"^=" { return CARETEQUAL; }
":" { return COLON; }
"," { return COMMA; }
"." { return DOT; }
".." { return DOT2; }
"..." { return DOT3; }
".*" { return DOTASTERISK; }
".?" { return DOTQUESTIONMARK; }
"=" { return EQUAL; }
"==" { return EQUALEQUAL; }
"=>" { return EQUALRARROW; }
"!" { return EXCLAMATIONMARK; }
"!=" { return EXCLAMATIONMARKEQUAL; }
"<" { return LARROW; }
"<<" { return LARROW2; }
"<<=" { return LARROW2EQUAL; }
"<<|" { return LARROW2PIPE; }
"<<|=" { return LARROW2PIPEEQUAL; }
"<=" { return LARROWEQUAL; }
"{" { return LBRACE; }
"[" { return LBRACKET; }
"(" { return LPAREN; }
"-" { return MINUS; }
"-=" { return MINUSEQUAL; }
"-%" { return MINUSPERCENT; }
"-%=" { return MINUSPERCENTEQUAL; }
"-|" { return MINUSPIPE; }
"-|=" { return MINUSPIPEEQUAL; }
"->" { return MINUSRARROW; }
"%" { return PERCENT; }
"%=" { return PERCENTEQUAL; }
"|" { return PIPE; }
"||" { return PIPE2; }
"|=" { return PIPEEQUAL; }
"+" { return PLUS; }
"++" { return PLUS2; }
"+=" { return PLUSEQUAL; }
"+%" { return PLUSPERCENT; }
"+%=" { return PLUSPERCENTEQUAL; }
"+|" { return PLUSPIPE; }
"+|=" { return PLUSPIPEEQUAL; }
//This one is directly in the tokenizer, because it conflicts with identifiers without context
// "c" { return LETTERC; }
"?" { return QUESTIONMARK; }
">" { return RARROW; }
">>" { return RARROW2; }
">>=" { return RARROW2EQUAL; }
">=" { return RARROWEQUAL; }
"}" { return RBRACE; }
"]" { return RBRACKET; }
")" { return RPAREN; }
";" { return SEMICOLON; }
"/" { return SLASH; }
"/=" { return SLASHEQUAL; }
"~" { return TILDE; }
// keywords
"addrspace" { return KEYWORD_ADDRSPACE; }
"align" { return KEYWORD_ALIGN; }
"allowzero" { return KEYWORD_ALLOWZERO; }
"and" { return KEYWORD_AND; }
"anyframe" { return KEYWORD_ANYFRAME; }
"anytype" { return KEYWORD_ANYTYPE; }
"asm" { return KEYWORD_ASM; }
"async" { return KEYWORD_ASYNC; }
"await" { return KEYWORD_AWAIT; }
"break" { return KEYWORD_BREAK; }
"callconv" { return KEYWORD_CALLCONV; }
"catch" { return KEYWORD_CATCH; }
"comptime" { return KEYWORD_COMPTIME; }
"const" { return KEYWORD_CONST; }
"continue" { return KEYWORD_CONTINUE; }
"defer" { return KEYWORD_DEFER; }
"else" { return KEYWORD_ELSE; }
"enum" { return KEYWORD_ENUM; }
"errdefer" { return KEYWORD_ERRDEFER; }
"error" { return KEYWORD_ERROR; }
"export" { return KEYWORD_EXPORT; }
"extern" { return KEYWORD_EXTERN; }
"fn" { return KEYWORD_FN; }
"for" { return KEYWORD_FOR; }
"if" { return KEYWORD_IF; }
"inline" { return KEYWORD_INLINE; }
"noalias" { return KEYWORD_NOALIAS; }
"nosuspend" { return KEYWORD_NOSUSPEND; }
"noinline" { return KEYWORD_NOINLINE; }
"opaque" { return KEYWORD_OPAQUE; }
"or" { return KEYWORD_OR; }
"orelse" { return KEYWORD_ORELSE; }
"packed" { return KEYWORD_PACKED; }
"pub" { return KEYWORD_PUB; }
"resume" { return KEYWORD_RESUME; }
"return" { return KEYWORD_RETURN; }
"linksection" { return KEYWORD_LINKSECTION; }
"struct" { return KEYWORD_STRUCT; }
"suspend" { return KEYWORD_SUSPEND; }
"switch" { return KEYWORD_SWITCH; }
"test" { return KEYWORD_TEST; }
"threadlocal" { return KEYWORD_THREADLOCAL; }
"try" { return KEYWORD_TRY; }
"union" { return KEYWORD_UNION; }
"unreachable" { return KEYWORD_UNREACHABLE; }
"usingnamespace" { return KEYWORD_USINGNAMESPACE; }
"var" { return KEYWORD_VAR; }
"volatile" { return KEYWORD_VOLATILE; }
"while" { return KEYWORD_WHILE; }
"'" { yybegin(CHAR_LIT); }
{char_char}*"'" { yybegin(YYINITIAL); return CHAR_LITERAL; }
[^] { yypushback(1); yybegin(UNT_QUOT); }
{FLOAT} { return FLOAT; }
{INTEGER} { return INTEGER; }
"\"" { yybegin(STR_LIT); }
{string_char}*"\"" { yybegin(YYINITIAL); return STRING_LITERAL_SINGLE; }
[^] { yypushback(1); yybegin(UNT_QUOT); }
"\\\\" { yybegin(STR_MULT_LINE); }
{all_nl_wrap} "\\\\" { }
{all_nl_nowrap} { yybegin(YYINITIAL); return STRING_LITERAL_MULTI; }
{IDENTIFIER_PLAIN} { return IDENTIFIER; }
"@\"" { yybegin(ID_QUOT); }
{string_char}*"\"" { yybegin(YYINITIAL); return IDENTIFIER; }
[^] { yypushback(1); yybegin(UNT_QUOT); }
{BUILTINIDENTIFIER} { return BUILTINIDENTIFIER; }
[^\n]*{CRLF} { yybegin(YYINITIAL); return BAD_CHARACTER; }
{WHITE_SPACE} { return WHITE_SPACE; }
[^] { return BAD_CHARACTER; }