Files
nunuhara_xsystem4/src/tools/ainedit/jaf_lexer.l
T

192 lines
5.2 KiB
Plaintext

/* Copyright (C) 2019 Nunuhara Cabbage <nunuhara@haniwa.technology>
*
* This program 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.
*
* This program 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 this program; if not, see <http://gnu.org/licenses/>.
*
* Based on ANSI C grammar from http://www.quut.com/c/ANSI-C-grammar-l-2011.html
*/
%e 1019
%p 2807
%n 371
%k 284
%a 1213
%o 1117
O [0-7]
D [0-9]
NZ [1-9]
L [a-zA-Z_]
A [a-zA-Z_0-9]
H [a-fA-F0-9]
HP (0[xX])
E ([Ee][+-]?{D}+)
P ([Pp][+-]?{D}+)
FS (f|F|l|L)
IS (((u|U)(l|L|ll|LL)?)|((l|L|ll|LL)(u|U)?))
CP (u|U|L)
SP (u8|u|U|L)
ES (\\(['"\?\\abfnrtv]|[0-7]{1,3}|x[a-fA-F0-9]+))
WS [ \t\v\n\f]
%{
#pragma GCC diagnostic ignored "-Wunused-function"
#include <stdio.h>
#include "system4/string.h"
#include "jaf_parser.tab.h"
extern void yyerror(const char *); /* prints grammar violation message */
extern int sym_type(const char *); /* returns type from symbol table */
static void comment(void);
static int check_type(void);
#define RETURN_STRING(tok_type) yylval.string = make_string(yytext, yyleng); return tok_type
%}
%%
"/*" { comment(); }
"//".* { /* consume //-comment */ }
"break" { return(BREAK); }
"case" { return(CASE); }
"char" { return(CHAR); }
"const" { return(CONST); }
"continue" { return(CONTINUE); }
"default" { return(DEFAULT); }
"do" { return(DO); }
"else" { return(ELSE); }
"enum" { return(ENUM); }
"float" { return(FLOAT); }
"for" { return(FOR); }
"goto" { return(GOTO); }
"if" { return(IF); }
"int" { return(INT); }
"long" { return(LONG); }
"return" { return(SYM_RETURN); }
"string" { return(STRING); }
"struct" { return(STRUCT); }
"switch" { return(SYM_SWITCH); }
"union" { return(UNION); }
"void" { return(VOID); }
"while" { return(WHILE); }
"bool" { return BOOL; }
"__func__" { return FUNC_NAME; }
"ref" { return SYM_REF; }
{L}{A}* { return check_type(); }
{HP}{H}+{IS}? { RETURN_STRING(I_CONSTANT); }
{NZ}{D}*{IS}? { RETURN_STRING(I_CONSTANT); }
"0"{O}*{IS}? { RETURN_STRING(I_CONSTANT); }
{CP}?"'"([^'\\\n]|{ES})+"'" { RETURN_STRING(I_CONSTANT); }
{D}+{E}{FS}? { RETURN_STRING(F_CONSTANT); }
{D}*"."{D}+{E}?{FS}? { RETURN_STRING(F_CONSTANT); }
{D}+"."{E}?{FS}? { RETURN_STRING(F_CONSTANT); }
{HP}{H}+{P}{FS}? { RETURN_STRING(F_CONSTANT); }
{HP}{H}*"."{H}+{P}{FS}? { RETURN_STRING(F_CONSTANT); }
{HP}{H}+"."{P}{FS}? { RETURN_STRING(F_CONSTANT); }
({SP}?\"([^"\\\n]|{ES})*\"{WS}*)+ { RETURN_STRING(STRING_LITERAL); }
"..." { return ELLIPSIS; }
">>=" { return RIGHT_ASSIGN; }
"<<=" { return LEFT_ASSIGN; }
"+=" { return ADD_ASSIGN; }
"-=" { return SUB_ASSIGN; }
"*=" { return MUL_ASSIGN; }
"/=" { return DIV_ASSIGN; }
"%=" { return MOD_ASSIGN; }
"&=" { return AND_ASSIGN; }
"^=" { return XOR_ASSIGN; }
"|=" { return OR_ASSIGN; }
"<-" { return REF_ASSIGN; }
">>" { return RIGHT_OP; }
"<<" { return LEFT_OP; }
"++" { return INC_OP; }
"--" { return DEC_OP; }
"&&" { return AND_OP; }
"||" { return OR_OP; }
"<=" { return LE_OP; }
">=" { return GE_OP; }
"==" { return EQ_OP; }
"!=" { return NE_OP; }
";" { return ';'; }
("{"|"<%") { return '{'; }
("}"|"%>") { return '}'; }
"," { return ','; }
":" { return ':'; }
"=" { return '='; }
"(" { return '('; }
")" { return ')'; }
("["|"<:") { return '['; }
("]"|":>") { return ']'; }
"." { return '.'; }
"&" { return '&'; }
"!" { return '!'; }
"~" { return '~'; }
"-" { return '-'; }
"+" { return '+'; }
"*" { return '*'; }
"/" { return '/'; }
"%" { return '%'; }
"<" { return '<'; }
">" { return '>'; }
"^" { return '^'; }
"|" { return '|'; }
"?" { return '?'; }
{WS}+ { /* whitespace separates tokens */ }
. { /* discard bad characters */ }
%%
int yywrap(void) /* called at end of input */
{
return 1; /* terminate now */
}
static void comment(void)
{
int c;
while ((c = input()) != 0)
if (c == '*')
{
while ((c = input()) == '*')
;
if (c == '/')
return;
if (c == 0)
break;
}
yyerror("unterminated comment");
}
static int check_type(void)
{
switch (sym_type(yytext))
{
case TYPEDEF_NAME: /* previously defined */
RETURN_STRING(TYPEDEF_NAME);
case ENUMERATION_CONSTANT: /* previously defined */
RETURN_STRING(ENUMERATION_CONSTANT);
default: /* includes undefined */
RETURN_STRING(IDENTIFIER);
}
}