/* * epos/src/parser.h * (c) geo@cuni.cz * 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 in doc/COPYING for more details. * * This file defines how an input file or string is to be parsed. * It's sole function is to tell the constructor of "unit" * which UNIT (depth) should be the next unit at any given moment. * The constructor will then either return to parent, descend to * a new-born child, or advance to the next character in the parser. * */ #define CHARSET_SIZE 256 #define PARSER_MODES 2 /* do NOT count PARSER_MODE_FILE */ #define PARSER_MODE_RAW 0 #define PARSER_MODE_INPUT 1 #define PARSER_MODE_FILE 2 class parser { unsigned char *xml; unsigned char *xmllen; unsigned char *text; // allocated dynamically unsigned int txtlen; // length of text (not counting \0) unsigned char *current; // the byte to be parsed next unsigned char token; // the current token // to be initialized in the constructor: static unsigned char transl_input[PARSER_MODES][CHARSET_SIZE]; unsigned char *char_level; // just a cached value const char *downgradables; int mode; // the first index to CHAR_LEVEL and TRANSL_INPUT static void alias(int mode, const char *canon, const char *alias); static void regist(int mode, unsigned char *table, UNIT assigned_function, const char* list); public: parser(const char *s, int parser_mode); void init(); ~parser(); UNIT level; // contains the UNIT level of the next symbol // int f, i, t; // f, i, t of the next symbol (usually zero) float t; UNIT depth; // if set, the level which triggers downgrades unsigned char identify_token(); static bool is_garbage(UNIT level, UNIT last_level, UNIT toomuch); unsigned char gettoken(); // gets the next symbol UNIT chrlev(unsigned char c); // what level c is to be analysed at void done(); // shriek if some input left static void init_tables(lang *); // fills in CHAR_LEVEL, TRANSL_INPUT void *operator new(size_t size); void operator delete(void *ptr); }; #define NO_CONT '_' // null contents of a unit /* * Special tokens "added" to ASCII instead of some never used ctrl chars: * DOTS ... \~ * DECPOINT 1.3 \. * URLDOT .com \d * RANGE 1-3 \- * MINUS -3 \m * * _INTERNAL1 \X (never generated by the parser) * _INTERNAL2 \Y (never generated by the parser) * _INTERNAL3 \Z (never generated by the parser) * _INTERNAL4 \W (never generated by the parser) * _INTERNAL5 \V (never generated by the parser) * _INTERNAL6 \U (never generated by the parser) * * Two or more '-''s are always output as a single '-' token * * These tokens are generated by parser::gettoken() and reverted * to their original form by fmtchar(). It is possible to refer to * them in rule files and .ini files by the escape sequences just * shown. * * Adding special tokens: parser::gettoken(), fmtchar(), .ini * files must recognize the token (probably as a perm_phone), for * which you have to add some intuitive escape sequence to option.lst, * namely to token_esc and value_esc defaults. * Then add some appropriate handling within the rules. */ #define DOTS 1 #define DECPOINT 2 #define URLDOT 3 #define RANGE 4 #define MINUS 5 #define _INTERNAL1 31 #define _INTERNAL2 30 #define _INTERNAL3 29 #define _INTERNAL4 28 #define _INTERNAL5 27 #define _INTERNAL6 26