diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-05-15 13:51:03 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-05-15 14:05:39 +0300 |
commit | a0826b4c7cd66c4862d9b61bb7e14d73fcba28f6 (patch) | |
tree | 71762fca263967e5803ce803b0a0aa94555e125d /src/meta1-lex.l | |
parent | fd64fa62bc68d8c2e0d693033e874fcc1f023544 (diff) | |
download | grecs-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.l | 114 |
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)); +} + + + + |