aboutsummaryrefslogtreecommitdiff
path: root/src/meta1-lex.l
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2011-05-15 13:51:03 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2011-05-15 14:05:39 +0300
commita0826b4c7cd66c4862d9b61bb7e14d73fcba28f6 (patch)
tree71762fca263967e5803ce803b0a0aa94555e125d /src/meta1-lex.l
parentfd64fa62bc68d8c2e0d693033e874fcc1f023544 (diff)
downloadgrecs-a0826b4c7cd66c4862d9b61bb7e14d73fcba28f6.tar.gz
grecs-a0826b4c7cd66c4862d9b61bb7e14d73fcba28f6.tar.bz2
Provide a framework for multiple parsers. Implement meta1 parser.
* Makefile.am (EXTRA_DIST): Add build-aux/yyrename * am/grecs.m4: New options: parser-meta1 and all-parsers * src/.gitignore: Update. * src/Make.am [GRECS_COND_META1_PARSER]: Set GRECS_PARSER_META1 and GRECS_EXTRA_META1 (GRECS_SRC): Add new files. (EXTRA_DIST): Add GRECS_EXTRA_META1. (LEXCOMPILE,YACCCOMPILE): Redefine * src/grecs-gram.y: Don't include yygrecs.h (grecs_vasprintf,grecs_asprintf): Move to a separate file. (grecs_parse): Rename to grecs_grecs_parser. Actual grecs_parse is defined in parser.c (grecs_gram_trace): Move to parser.c * src/grecs-lex.l: Don't include yygrecs.h Use line_acc functions. * src/grecs.h (grecs_trace_flags): New extern. (GRECS_TRACE_GRAM, GRECS_TRACE_LEX): New flags. (grecs_lex_begin): Change signature. (grecs_grecs_parser,grecs_meta1_parser): New protos. (grecs_line_acc_create) (grecs_line_acc_free,grecs_line_acc_grow_char) (grecs_line_acc_grow_char_unescape) (grecs_line_acc_grow) (grecs_line_acc_grow_unescape_last): New protos. (GRECS_TXTACC_BUFSIZE): New const (grecs_txtacc_create,grecs_txtacc_free) (grecs_txtacc_grow,grecs_txtacc_finish) (grecs_txtacc_free_string): New protos. (grecs_value_match): New proto. * src/wordsplit.c (quote_transtab): Translate \" * src/yygrecs.h: Remove. * src/yytrans: New file. * build-aux/yyrename: New file. * src/asprintf.c: New file. * src/lineacc.c: New file. * src/meta1-gram.y: New file. * src/meta1-lex.l: New file. * src/parser.c: New file. * src/txtacc.c: New file. * doc/grecs_parse.3: Update. * doc/GRECS_SETUP.3: Update.
Diffstat (limited to 'src/meta1-lex.l')
-rw-r--r--src/meta1-lex.l114
1 files changed, 114 insertions, 0 deletions
diff --git a/src/meta1-lex.l b/src/meta1-lex.l
new file mode 100644
index 0000000..cb2931d
--- /dev/null
+++ b/src/meta1-lex.l
@@ -0,0 +1,114 @@
+/* MeTA1 configuration lexer for Grecs. -*- c -*- */
+%top {
+/* MeTA1 configuration lexer for Grecs.
+ Copyright (C) 2007-2011 Sergey Poznyakoff
+
+ Grecs 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 of the License, or (at your
+ option) any later version.
+
+ Grecs 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 Grecs. If not, see <http://www.gnu.org/licenses/>. */
+
+/* This file implements a lexical analyzer for MeTA1 main configuration file.
+ */
+
+#ifndef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include "grecs.h"
+#include "meta1-gram.h"
+#include <ctype.h>
+}
+
+%{
+static int yywrap(void);
+static void meta1_line_add_unescape_hex(const char *text, size_t len);
+%}
+
+%x COMMENT STR
+X [0-9a-fA-F]
+%%
+ /* C-style comments */
+"/*" BEGIN (COMMENT);
+<COMMENT>[^*\n]* /* eat anything that's not a '*' */
+<COMMENT>"*"+[^*/\n]* /* eat up '*'s not followed by '/'s */
+<COMMENT>\n ++grecs_current_locus.line;
+<COMMENT>"*"+"/" BEGIN (INITIAL);
+ /* End-of-line comments */
+#.*\n { grecs_current_locus.line++; }
+#.* /* end-of-file comment */;
+ /* Number */
+0[xX]{X}+ |
+0[0-7]+ |
+[1-9][0-9]+ { grecs_line_begin();
+ grecs_line_add(yytext, yyleng);
+ yylval.string = grecs_line_finish();
+ return META1_STRING; }
+ /* Identifiers (unquoted strings) */
+[a-zA-Z0-9_\./:\*-]+ { grecs_line_begin();
+ grecs_line_add(yytext, yyleng);
+ yylval.ident.locus = grecs_current_locus;
+ yylval.ident.string = grecs_line_finish();
+ return META1_IDENT; }
+ /* Quoted strings */
+\"[^\\"\n]*\" { grecs_line_begin();
+ grecs_line_add(yytext + 1, yyleng - 2);
+ yylval.string = grecs_line_finish();
+ return META1_STRING; }
+\"[^\\"\n]*\\x{X}{1,2} { BEGIN(STR);
+ grecs_line_begin();
+ meta1_line_add_unescape_hex(yytext + 1, yyleng - 1);
+ }
+\"[^\\"\n]*\\. { BEGIN(STR);
+ grecs_line_begin();
+ grecs_line_acc_grow_unescape_last(yytext + 1,
+ yyleng - 1); }
+<STR>[^\\"\n]*\\x{X}{1,2} { meta1_line_add_unescape_hex(yytext, yyleng); }
+<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 META1_STRING; }
+<STR>[^\\"\n]*\n { BEGIN(INITIAL);
+ grecs_error(&grecs_current_locus, 0,
+ _("newline in a string"));
+ grecs_line_add (yytext, yyleng - 1);
+ yylval.string = grecs_line_finish ();
+ return META1_STRING; }
+ /* Other tokens */
+[ \t\f][ \t\f]* ;
+\n { grecs_current_locus.line++; }
+[,;{}=] return yytext[0];
+. { grecs_error(&grecs_current_locus, 0,
+ (isascii(yytext[0]) && isprint(yytext[0])) ?
+ _("stray character %c") :
+ _("stray character \\%03o"),
+ (unsigned char) yytext[0]); }
+%%
+
+int
+yywrap()
+{
+ return 1;
+}
+
+static void
+meta1_line_add_unescape_hex(const char *text, size_t len)
+{
+ for (; text[len-1] != 'x' && len > 0; len--)
+ ;
+ grecs_line_acc_grow(text, len - 2);
+ grecs_line_acc_grow_char((char) strtoul (text + len, NULL, 16));
+}
+
+
+
+

Return to:

Send suggestions and report system problems to the System administrator.