diff options
Diffstat (limited to 'lib/forlanlex.l')
-rw-r--r-- | lib/forlanlex.l | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/lib/forlanlex.l b/lib/forlanlex.l new file mode 100644 index 0000000..99966ed --- /dev/null +++ b/lib/forlanlex.l @@ -0,0 +1,137 @@ +%{ +/* This file is part of Eclat. + Copyright (C) 2012 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 <http://www.gnu.org/licenses/>. */ + +#include "libeclat.h" +#include <grecs.h> +#include <grecs-locus.h> +#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 { \ + 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; \ + } 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); + +%} + +WS [ \t\f][ \t\f]* +IDC [a-zA-Z_0-9-] +%x COMMENT ML STR +%% + /* Comments */ +"/*" BEGIN(COMMENT); +<COMMENT>[^*\n]* /* eat anything that's not a '*' */ +<COMMENT>"*"+[^*/\n]* /* eat up '*'s not followed by '/'s */ +<COMMENT>\n grecs_locus_point_advance_line(grecs_current_locus_point); +<COMMENT>"*"+"/" BEGIN(INITIAL); +"//".* ; + /* Keywords */ +if return IF; +else return ELSE; +last return LAST; +! return NOT; +"&&" return AND; +"||" return OR; +{IDC}{IDC}* { 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); + 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); } +<STR>\"[^\\"\n]*\\\n { grecs_line_acc_grow_unescape_last(yytext, yyleng); + grecs_locus_point_advance_line(grecs_current_locus_point); } +<STR>[^\\"\n]*\\. { grecs_line_acc_grow_unescape_last(yytext, yyleng); } +<STR>[^\\"\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_begin(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_end() +{ + grecs_line_acc_free(); +} + + + + + |