%{
/* This file is part of Eclat.
Copyright (C) 2012-2018 Sergey Poznyakoff.
Eclat 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 3, or (at your option)
any later version.
Eclat 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 Eclat. If not, see . */
#include "libeclat.h"
#include
#include
#include
#include
#include "forlangrm.h"
#include "forlan.h"
static const char *forlan_input_base;
static size_t forlan_input_len;
static size_t forlan_input_pos;
#undef YY_INPUT
#define YY_INPUT(buf,result,max_size) \
do { \
if (forlan_input_base) { \
size_t __s = forlan_input_len - forlan_input_pos; \
if (__s > max_size) \
__s = max_size; \
if (__s > 0) { \
memcpy(buf, forlan_input_base, __s); \
forlan_input_pos += __s; \
} \
result = __s; \
} else \
result = fread(buf, 1, max_size, yyin); \
} while(0)
#define YY_USER_ACTION do { \
if (YYSTATE == 0) { \
yylloc.beg = grecs_current_locus_point; \
yylloc.beg.col++; \
} \
grecs_current_locus_point.col += yyleng; \
yylloc.end = grecs_current_locus_point; \
} while (0);
static int yywrap(void);
%}
%option noinput
%option nounput
WS [ \t\f][ \t\f]*
ID [a-zA-Z_][a-zA-Z_0-9-]*
%x COMMENT ML STR
%%
/* Comments */
"/*" BEGIN(COMMENT);
[^*\n]* /* eat anything that's not a '*' */
"*"+[^*/\n]* /* eat up '*'s not followed by '/'s */
\n grecs_locus_point_advance_line(grecs_current_locus_point);
"*"+"/" BEGIN(INITIAL);
"//".* ;
/* Decimal numbers */
-?[0-9][0-9]* { grecs_line_begin();
grecs_line_add(yytext, yyleng);
yylval.string = grecs_line_finish();
return STRING; }
/* Keywords */
if return IF;
else return ELSE;
last return LAST;
for return FOR;
let return LET;
in return IN;
break return BREAK;
continue return CONTINUE;
! return NOT;
"&&" return AND;
"||" return OR;
"==" return EQ;
"!=" return NE;
{ID} { grecs_line_begin();
grecs_line_add(yytext, yyleng);
yylval.string = grecs_line_finish();
return IDENT; }
/* Quoted strings */
\"[^\\"\n]*\" { grecs_line_begin();
grecs_line_add(yytext + 1, yyleng - 2);
yylval.string = grecs_line_finish();
return STRING; }
\"[^\\"\n]*\\\n { BEGIN(STR);
grecs_line_begin();
grecs_line_acc_grow_unescape_last(yytext + 1,
yyleng - 1,
&yylloc);
grecs_locus_point_advance_line(grecs_current_locus_point); }
\"[^\\"\n]*\\. { BEGIN(STR);
grecs_line_begin();
grecs_line_acc_grow_unescape_last(yytext + 1,
yyleng - 1,
&yylloc); }
\"[^\\"\n]*\\\n { grecs_line_acc_grow_unescape_last(yytext, yyleng,
&yylloc);
grecs_locus_point_advance_line(grecs_current_locus_point); }
[^\\"\n]*\\. { grecs_line_acc_grow_unescape_last(yytext, yyleng, &yylloc); }
[^\\"\n]*\" { BEGIN(INITIAL);
if (yyleng > 1)
grecs_line_add(yytext, yyleng - 1);
yylval.string = grecs_line_finish();
return STRING; }
/* Other tokens */
{WS} ;
\n { grecs_locus_point_advance_line(grecs_current_locus_point); }
[.,;{}()\[\]=\*%] return yytext[0];
. { if (isascii(yytext[0]) && isprint(yytext[0]))
grecs_error(&yylloc, 0,
_("stray character %c"), yytext[0]);
else
grecs_error(&yylloc, 0,
_("stray character \\%03o"),
(unsigned char) yytext[0]); }
%%
static int
yywrap()
{
return 1;
}
void
forlan_lex_from_buffer(const char *input, size_t length,
struct grecs_locus_point *pt)
{
forlan_input_base = input;
forlan_input_len = length;
grecs_current_locus_point = *pt;
yy_flex_debug = debug_level(forlan_dbg) >= FORLAN_DBG_LEX;
grecs_line_acc_create();
}
void
forlan_lex_from_file(FILE *fp, struct grecs_locus_point *pt)
{
yyin = fp;
forlan_input_base = NULL;
grecs_current_locus_point = *pt;
yy_flex_debug = debug_level(forlan_dbg) >= FORLAN_DBG_LEX;
grecs_line_acc_create();
}
void
forlan_lex_end()
{
grecs_line_acc_free();
}