From 7e2e6ca176afbde66e1f5ae147470fd229da97de Mon Sep 17 00:00:00 2001 From: schodet Date: Wed, 8 Feb 2006 23:02:23 +0000 Subject: - restructuration du parser - création de ConfigParser - amélioration du report d'erreur - passage en 2006 --- i/marvin/src/config/Makefile.defs | 4 +- i/marvin/src/config/config.hh | 7 +- i/marvin/src/config/config_data.cc | 81 ++---------------- i/marvin/src/config/config_data.hh | 6 +- i/marvin/src/config/config_data.tcc | 8 +- i/marvin/src/config/config_parser.cc | 142 ++++++++++++++++++++++++++++++++ i/marvin/src/config/config_parser.hh | 77 +++++++++++++++++ i/marvin/src/config/lexer.ll | 30 ++++--- i/marvin/src/config/parser.yy | 26 +++--- i/marvin/src/config/parser_extra.hh | 47 ----------- i/marvin/src/config/test_config_data.cc | 6 +- 11 files changed, 270 insertions(+), 164 deletions(-) create mode 100644 i/marvin/src/config/config_parser.cc create mode 100644 i/marvin/src/config/config_parser.hh delete mode 100644 i/marvin/src/config/parser_extra.hh (limited to 'i/marvin/src') diff --git a/i/marvin/src/config/Makefile.defs b/i/marvin/src/config/Makefile.defs index 7683a6c..d255c9b 100644 --- a/i/marvin/src/config/Makefile.defs +++ b/i/marvin/src/config/Makefile.defs @@ -1,6 +1,6 @@ PROGRAMS += test_config_data -config_OBJECTS = lexer.o parser.o config_data.o +config_OBJECTS = lexer.o parser.o config_data.o config_parser.o test_config_data_OBJECTS = $(config_OBJECTS) test_config_data.o @@ -13,4 +13,4 @@ lexer.o: parser.hh lexer.hh: lexer.cc parser.o: lexer.hh -config_data.o: lexer.hh +config_parser.o: lexer.hh diff --git a/i/marvin/src/config/config.hh b/i/marvin/src/config/config.hh index c88ec98..bcec7d8 100644 --- a/i/marvin/src/config/config.hh +++ b/i/marvin/src/config/config.hh @@ -1,11 +1,11 @@ #ifndef config_hh #define config_hh // config.hh -// robert - programme du robot 2005. {{{ +// marvin - programme du robot 2006. {{{ // -// Copyright (C) 2005 Nicolas Schodet +// Copyright (C) 2006 Nicolas Schodet // -// Robot APB Team/Efrei 2005. +// Robot APB Team/Efrei 2006. // Web: http://assos.efrei.fr/robot/ // Email: robot AT efrei DOT fr // @@ -27,7 +27,6 @@ #include "config_data.hh" #include -#include /// Classe d'accés à la configuration. class Config diff --git a/i/marvin/src/config/config_data.cc b/i/marvin/src/config/config_data.cc index 33a78c0..a8721fb 100644 --- a/i/marvin/src/config/config_data.cc +++ b/i/marvin/src/config/config_data.cc @@ -1,9 +1,9 @@ // config_data.cc -// robert - programme du robot 2005. {{{ +// marvin - programme du robot 2006. {{{ // -// Copyright (C) 2005 Nicolas Schodet +// Copyright (C) 2006 Nicolas Schodet // -// Robot APB Team/Efrei 2005. +// Robot APB Team/Efrei 2006. // Web: http://assos.efrei.fr/robot/ // Email: robot AT efrei DOT fr // @@ -24,9 +24,7 @@ // }}} #include "config.hh" #include "config_data.hh" -#include "parser_extra.hh" -#include "parser.hh" -#include "lexer.hh" +#include "config_parser.hh" #include @@ -68,74 +66,7 @@ ConfigData::add (const std::string &id, any &val) void ConfigData::init (int &argc, char **&argv, const std::string &file) { - parseFile (file); -} - -int yyparse (void *); - -/// Lance le parseur sur un fichier. -void -ConfigData::parseFile (const std::string &file) -{ - FILE *f; - f = fopen (file.c_str (), "r"); - if (!f) - throw std::runtime_error ("can not open config file \"" + file + "\""); - try - { - // Crée un scanner, initialise son tampon d'entré, puis parse. - yyscan_t scanner; - YY_BUFFER_STATE buf; - ParserExtra pe (*this); - yylex_init (&scanner); - yyset_extra (&pe, scanner); - buf = yy_create_buffer (f, YY_READ_BUF_SIZE, scanner); - yy_switch_to_buffer (buf, scanner); - int ret = yyparse (scanner); - yy_delete_buffer (buf, scanner); - yylex_destroy (scanner); - if (ret) - throw std::runtime_error ("parse error"); - } - catch (const std::runtime_error &e) - { - fclose (f); - throw std::runtime_error ("in config file \"" + file + "\": " - + e.what ()); - } - fclose (f); -} - -/// Lance le parseur sur une chaîne. -void -ConfigData::parseString (const std::string &s) -{ - try - { - // Crée un scanner, initialise son tampon d'entré, puis parse. - yyscan_t scanner; - YY_BUFFER_STATE buf; - ParserExtra pe (*this); - yylex_init (&scanner); - yyset_extra (&pe, scanner); - buf = yy_scan_bytes (s.data (), s.size (), scanner); - int ret = yyparse (scanner); - yy_delete_buffer (buf, scanner); - yylex_destroy (scanner); - if (ret) - throw std::runtime_error ("parse error"); - } - catch (const std::runtime_error &e) - { - throw std::runtime_error ("in config string \"" + s + "\": " - + e.what ()); - } -} - -/* Shut up warning for this wrongly declared static function. */ -static int -yy_init_globals (yyscan_t yyscanner) -{ - return yy_init_globals (yyscanner); + ConfigParser p (*this); + p.parseFile (file); } diff --git a/i/marvin/src/config/config_data.hh b/i/marvin/src/config/config_data.hh index 0d0944e..a0dbacf 100644 --- a/i/marvin/src/config/config_data.hh +++ b/i/marvin/src/config/config_data.hh @@ -1,11 +1,11 @@ #ifndef config_data_hh #define config_data_hh // config_data.hh -// robert - programme du robot 2005. {{{ +// marvin - programme du robot 2006. {{{ // -// Copyright (C) 2005 Nicolas Schodet +// Copyright (C) 2006 Nicolas Schodet // -// Robot APB Team/Efrei 2005. +// Robot APB Team/Efrei 2006. // Web: http://assos.efrei.fr/robot/ // Email: robot AT efrei DOT fr // diff --git a/i/marvin/src/config/config_data.tcc b/i/marvin/src/config/config_data.tcc index 60f4910..31b62bc 100644 --- a/i/marvin/src/config/config_data.tcc +++ b/i/marvin/src/config/config_data.tcc @@ -1,9 +1,9 @@ // config_data.tcc -// robert - programme du robot 2005. {{{ +// marvin - programme du robot 2006. {{{ // -// Copyright (C) 2005 Nicolas Schodet +// Copyright (C) 2006 Nicolas Schodet // -// Robot APB Team/Efrei 2005. +// Robot APB Team/Efrei 2006. // Web: http://assos.efrei.fr/robot/ // Email: robot AT efrei DOT fr // @@ -23,7 +23,7 @@ // // }}} -#include +#include /// Récupère une valeur de configuration, fonction générique. template diff --git a/i/marvin/src/config/config_parser.cc b/i/marvin/src/config/config_parser.cc new file mode 100644 index 0000000..ee0a6e3 --- /dev/null +++ b/i/marvin/src/config/config_parser.cc @@ -0,0 +1,142 @@ +// config_parser.cc +// marvin - programme du robot 2006. {{{ +// +// Copyright (C) 2006 Nicolas Schodet +// +// Robot APB Team/Efrei 2006. +// Web: http://assos.efrei.fr/robot/ +// Email: robot AT efrei DOT fr +// +// This program 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 2 of the License, or +// (at your option) any later version. +// +// This program 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 this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// }}} +#include "config_parser.hh" +#include "config.hh" + +#include "parser.hh" +#include "lexer.hh" + +#include +#include + +int yyparse (void *); + +/// Constructeur. +ConfigParser::ConfigParser (ConfigData &configData) + : configData_ (configData) +{ +} + +/// Lance le parseur sur un fichier. +void +ConfigParser::parseFile (const std::string &file) +{ + FILE *f; + f = fopen (file.c_str (), "r"); + if (!f) + throw std::runtime_error ("can not open file \"" + file + "\""); + try + { + // Crée un scanner, initialise son tampon d'entré, puis parse. + yyscan_t scanner; + YY_BUFFER_STATE buf; + Extra e (configData_, *this, true); + yylex_init (&scanner); + yyset_extra (&e, scanner); + buf = yy_create_buffer (f, YY_READ_BUF_SIZE, scanner); + yy_switch_to_buffer (buf, scanner); + int ret = yyparse (scanner); + yy_delete_buffer (buf, scanner); + yylex_destroy (scanner); + if (ret) + { + if (e.errorValid_) + throw std::runtime_error (e.error_); + else + throw std::runtime_error ("parse error"); + } + } + catch (const std::runtime_error &e) + { + fclose (f); + throw std::runtime_error ("in file \"" + file + "\": " + e.what ()); + } + fclose (f); +} + +/// Lance le parseur sur une chaîne. +void +ConfigParser::parseString (const std::string &s) +{ + try + { + // Crée un scanner, initialise son tampon d'entré, puis parse. + yyscan_t scanner; + YY_BUFFER_STATE buf; + Extra e (configData_, *this, false); + yylex_init (&scanner); + yyset_extra (&e, scanner); + buf = yy_scan_bytes (s.data (), s.size (), scanner); + int ret = yyparse (scanner); + yy_delete_buffer (buf, scanner); + yylex_destroy (scanner); + if (ret) + { + if (e.errorValid_) + throw std::runtime_error (e.error_); + else + throw std::runtime_error ("parse error"); + } + } + catch (const std::runtime_error &e) + { + throw std::runtime_error ("in config string \"" + s + "\": " + + e.what ()); + } +} + +/// Constructeur pour initialiser les références. +ConfigParser::Extra::Extra (ConfigData &configData_, ConfigParser + &configParser_, bool useLine) + : configData (configData_), configParser (configParser_), + line (1), errorValid_ (false), useLine_ (useLine) +{ +} + +/// Recueille l'erreur de bison. +void +ConfigParser::Extra::error (const std::string &e) +{ + if (!errorValid_) + { + error_ = e; + errorValid_ = true; + if (useLine_) + { + std::stringstream os; + os << line; + error_ += ", line "; + error_ += os.str (); + } + } +} + +/* Shut up warning for this wrongly declared static function. */ +static int +yy_init_globals (yyscan_t yyscanner) +{ + return yy_init_globals (yyscanner); +} + diff --git a/i/marvin/src/config/config_parser.hh b/i/marvin/src/config/config_parser.hh new file mode 100644 index 0000000..abbf214 --- /dev/null +++ b/i/marvin/src/config/config_parser.hh @@ -0,0 +1,77 @@ +#ifndef config_parser_hh +#define config_parser_hh +// config_parser.hh +// marvin - programme du robot 2006. {{{ +// +// Copyright (C) 2006 Nicolas Schodet +// +// Robot APB Team/Efrei 2006. +// Web: http://assos.efrei.fr/robot/ +// Email: robot AT efrei DOT fr +// +// This program 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 2 of the License, or +// (at your option) any later version. +// +// This program 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 this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// }}} + +#include + +class ConfigData; + +/// Structure d'information passée au parser. +class ConfigParser +{ + public: + struct Extra + { + public: + /// Chaîne temporaire utilisée pendant l'analyse lexicale. + std::string tmp; + /// Référence vers le ConfigData qui doit recevoir la configuration. + ConfigData &configData; + /// Référence vers l'instance de ConfigParser. + ConfigParser &configParser; + /// Ligne courante. + int line; + private: + /// Permet de stocker l'erreur de bison. + std::string error_; + /// Indique si error est significatif. + bool errorValid_; + /// Utilise ou non le comptage de lignes. + bool useLine_; + public: + /// Constructeur pour initialiser les références. + Extra (ConfigData &configData_, ConfigParser &configParser_, + bool useLine); + /// Recueille l'erreur de bison. + void error (const std::string &e); + /// Accés réservé pour ConfigParser. + friend class ConfigParser; + }; + private: + /// Référence vers le ConfigData qui doit recevoir la configuration. + ConfigData &configData_; + public: + /// Constructeur. + ConfigParser (ConfigData &configData); + /// Lance le parseur sur un fichier. + void parseFile (const std::string &file); + /// Lance le parseur sur une chaîne. + void parseString (const std::string &s); +}; + +#define YY_EXTRA_TYPE ConfigParser::Extra * + +#endif // config_parser_hh diff --git a/i/marvin/src/config/lexer.ll b/i/marvin/src/config/lexer.ll index 96a90b3..34522dc 100644 --- a/i/marvin/src/config/lexer.ll +++ b/i/marvin/src/config/lexer.ll @@ -1,9 +1,9 @@ %{ -// robert - programme du robot 2005. {{{ +// marvin - programme du robot 2006. {{{ // -// Copyright (C) 2005 Nicolas Schodet +// Copyright (C) 2006 Nicolas Schodet // -// Robot APB Team/Efrei 2005. +// Robot APB Team/Efrei 2006. // Web: http://assos.efrei.fr/robot/ // Email: robot AT efrei DOT fr // @@ -23,7 +23,7 @@ // // }}} #include "config/config.hh" -#include "config/parser_extra.hh" +#include "config/config_parser.hh" #include "utils/any.hh" #include "parser.hh" %} @@ -75,17 +75,19 @@ FLOATNUM {FLOAT1}|{FLOAT2} yyextra->tmp.clear (); } -[=\n()] return yytext[0]; +\n { + yyextra->line++; + return yytext[0]; +} -"img:" return IMG; -"data:" return DATA; +[=()] return yytext[0]; [ \t]+ /* Skip. */ #.* /* Skip comments. */ . { - yylval->c = yytext[0]; - std::cout << "UNKNOWN " << yytext[0] << std::endl; + yyextra->error (std::string ("unexpected character \'") \ + + yytext[0] + '\''); return UNKNOWN; } @@ -98,14 +100,18 @@ FLOATNUM {FLOAT1}|{FLOAT2} \\n yyextra->tmp += '\n'; \\r yyextra->tmp += '\r'; \\t yyextra->tmp += '\t'; -\\(.|\n) yyextra->tmp += yytext[1]; +\\. yyextra->tmp += yytext[1]; +\\\n { + yyextra->line++; + yyextra->tmp += yytext[1]; +} . yyextra->tmp += yytext[0]; \n { - yylval->c = yytext[0]; + yyextra->error ("unexpected end of line inside string"); + yyextra->line++; return UNKNOWN; } - %% /* vim:ft=lex: diff --git a/i/marvin/src/config/parser.yy b/i/marvin/src/config/parser.yy index 1aeb986..dc2be24 100644 --- a/i/marvin/src/config/parser.yy +++ b/i/marvin/src/config/parser.yy @@ -1,9 +1,9 @@ %{ -// robert - programme du robot 2005. {{{ +// marvin - programme du robot 2006. {{{ // -// Copyright (C) 2005 Nicolas Schodet +// Copyright (C) 2006 Nicolas Schodet // -// Robot APB Team/Efrei 2005. +// Robot APB Team/Efrei 2006. // Web: http://assos.efrei.fr/robot/ // Email: robot AT efrei DOT fr // @@ -22,28 +22,25 @@ // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // // }}} -#define YYPARSE_PARAM scanner -#define YYLEX_PARAM scanner - #include "config/config.hh" #include "config/config_data.hh" -#include "config/parser_extra.hh" +#include "config/config_parser.hh" // Fichiers d'en-tête générés. #include "parser.hh" #include "lexer.hh" -#include // XXX à virer. - -void yyerror (const char *); - #undef yyextra #define yyextra (yyget_extra (scanner)) +void yyerror (void *scanner, const char *e); + %} %error-verbose %pure-parser +%lex-param {void *scanner} +%parse-param {void *scanner} %defines %union { char c; @@ -64,7 +61,6 @@ void yyerror (const char *); %token FLOAT %token ID STRING %token BOOLEAN -%token IMG DATA %type int_list %type float_list @@ -159,9 +155,11 @@ string_list: %% -void yyerror (const char *e) +/// Traite une erreur de Bison. +void +yyerror (void *scanner, const char *e) { - std::cerr << e << std::endl; + yyextra->error (e); } /* Shut up warning for this wrongly declared static function. */ diff --git a/i/marvin/src/config/parser_extra.hh b/i/marvin/src/config/parser_extra.hh deleted file mode 100644 index aa5f80f..0000000 --- a/i/marvin/src/config/parser_extra.hh +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef parser_extra_hh -#define parser_extra_hh -// parser_extra.hh -// robert - programme du robot 2005. {{{ -// -// Copyright (C) 2005 Nicolas Schodet -// -// Robot APB Team/Efrei 2005. -// Web: http://assos.efrei.fr/robot/ -// Email: robot AT efrei DOT fr -// -// This program 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 2 of the License, or -// (at your option) any later version. -// -// This program 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 this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -// }}} -#include - -class ConfigData; - -/// Structure d'information passée au parser. -struct ParserExtra -{ - /// Chaîne temporaire utilisée pendant l'analyse lexicale. - std::string tmp; - /// Référence vers le ConfigData qui doit recevoir la configuration. - ConfigData &configData; - public: - /// Constructeur pour initialiser la référence. - ParserExtra (ConfigData &configData_) - : configData (configData_) - { } -}; - -#define YY_EXTRA_TYPE ParserExtra * - -#endif // parser_extra_hh diff --git a/i/marvin/src/config/test_config_data.cc b/i/marvin/src/config/test_config_data.cc index 052a4c8..2ddb610 100644 --- a/i/marvin/src/config/test_config_data.cc +++ b/i/marvin/src/config/test_config_data.cc @@ -1,9 +1,9 @@ // test_config_data.cc -// robert - programme du robot 2005. {{{ +// marvin - programme du robot 2006. {{{ // -// Copyright (C) 2005 Nicolas Schodet +// Copyright (C) 2006 Nicolas Schodet // -// Robot APB Team/Efrei 2005. +// Robot APB Team/Efrei 2006. // Web: http://assos.efrei.fr/robot/ // Email: robot AT efrei DOT fr // -- cgit v1.2.3