%{ /* 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(); }