diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2012-09-22 16:15:48 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2012-09-22 16:30:07 +0300 |
commit | 0666fc3caae8e2db660d781e43bee2258bf06a00 (patch) | |
tree | 97380903872520efa3b2bf659465e63f2cf51a2a /lib/forlanlex.l | |
parent | 7f3dd0599ac3fb3a69c512b0ecfd043c67ca94ee (diff) | |
download | eclat-0666fc3caae8e2db660d781e43bee2258bf06a00.tar.gz eclat-0666fc3caae8e2db660d781e43bee2258bf06a00.tar.bz2 |
Introduce output formatting language
* configure.ac: Check for lex and yacc.
* lib/diag.c: New file (moved from ../src with edits)
* lib/forlan.c: New file.
* lib/forlan.h: New file.
* lib/forlangrm.y: New file.
* lib/forlanlex.l: New file.
* lib/.gitignore: Add new files.
* lib/Makefile.am: Add new file.
* lib/libeclat.h: Add diagnostics-related stuff.
* src/Makefile.am (eclat_SOURCES): Remove diag.c
* src/cmdline.opt (set_program_name): Move to ../lib/diag.c
* src/diag.c: Remove (see above).
* src/config.c: Reflect changes to the diagnostics subsystem.
* src/eclat.c: Likewise.
* src/eclat.h: Remove diagnostics-related stuff.
It lives in libeclat.h from now on.
* src/error.c: Remove.
* tests/forlan01.at: New testcase.
* tests/testsuite.at: Include forlan01.at
* tests/tforlan.c: New file.
* tests/.gitignore: Add new files.
* tests/Makefile.am: Add new files.
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(); +} + + + + + |