summaryrefslogtreecommitdiffabout
path: root/lib/forlanlex.l
authorSergey Poznyakoff <gray@gnu.org.ua>2012-09-22 13:15:48 (GMT)
committer Sergey Poznyakoff <gray@gnu.org.ua>2012-09-22 13:30:07 (GMT)
commit0666fc3caae8e2db660d781e43bee2258bf06a00 (patch) (side-by-side diff)
tree97380903872520efa3b2bf659465e63f2cf51a2a /lib/forlanlex.l
parent7f3dd0599ac3fb3a69c512b0ecfd043c67ca94ee (diff)
downloadeclat-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') (more/less context) (show whitespace changes)
-rw-r--r--lib/forlanlex.l137
1 files changed, 137 insertions, 0 deletions
diff --git a/lib/forlanlex.l b/lib/forlanlex.l
new file mode 100644
index 0000000..99966ed
--- a/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();
+}
+
+
+
+
+

Return to:

Send suggestions and report system problems to the System administrator.