1999-09-27 18:44:28 +00:00
|
|
|
// -*- C++ -*-
|
|
|
|
// Generalized simple lexical analizer.
|
|
|
|
// It can be used for simple syntax parsers, like lyxrc,
|
|
|
|
// texclass and others to come. [asierra30/03/96]
|
|
|
|
//
|
|
|
|
// (C) 1996 Lyx Team.
|
1999-12-01 00:57:31 +00:00
|
|
|
#ifndef LYXLEX_H
|
|
|
|
#define LYXLEX_H
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
|
|
#ifdef __GNUG__
|
|
|
|
#pragma interface
|
|
|
|
#endif
|
|
|
|
|
1999-12-01 00:57:31 +00:00
|
|
|
#include <cstdio>
|
1999-09-27 18:44:28 +00:00
|
|
|
#include "LString.h"
|
|
|
|
|
|
|
|
///
|
|
|
|
struct keyword_item {
|
|
|
|
///
|
1999-12-01 00:57:31 +00:00
|
|
|
char const * tag;
|
1999-09-27 18:44:28 +00:00
|
|
|
///
|
|
|
|
short code;
|
|
|
|
};
|
|
|
|
|
|
|
|
/*@Doc:
|
|
|
|
Generalized simple lexical analizer.
|
|
|
|
It can be used for simple syntax parsers, like lyxrc,
|
|
|
|
texclass and others to come.
|
|
|
|
See lyxrc.C for an example of usage.
|
|
|
|
*/
|
|
|
|
class LyXLex {
|
|
|
|
public:
|
|
|
|
///
|
1999-12-01 00:57:31 +00:00
|
|
|
LyXLex (keyword_item *, int);
|
1999-09-27 18:44:28 +00:00
|
|
|
///
|
|
|
|
~LyXLex() { if (file && owns_file) fclose(file); };
|
|
|
|
|
|
|
|
/// Lex basic codes
|
|
|
|
enum {
|
|
|
|
///
|
|
|
|
LEX_UNDEF = -1,
|
|
|
|
///
|
|
|
|
LEX_FEOF = -2,
|
|
|
|
///
|
|
|
|
LEX_DATA = -3,
|
|
|
|
///
|
|
|
|
LEX_TOKEN = -4
|
|
|
|
};
|
|
|
|
|
|
|
|
/// file is open and end of file is not reached
|
1999-12-01 00:57:31 +00:00
|
|
|
bool IsOK() const;
|
1999-09-27 18:44:28 +00:00
|
|
|
/// return true if able to open file, else false
|
1999-10-02 16:21:10 +00:00
|
|
|
bool setFile(string const & filename);
|
1999-09-27 18:44:28 +00:00
|
|
|
/// if file is already read from, line numbers will be wrong.
|
|
|
|
// should be removed
|
1999-12-01 00:57:31 +00:00
|
|
|
void setFile(FILE * f);
|
1999-09-27 18:44:28 +00:00
|
|
|
///
|
|
|
|
// should be removed
|
1999-12-01 00:57:31 +00:00
|
|
|
FILE * getFile() { return file; }
|
1999-09-27 18:44:28 +00:00
|
|
|
/// Danger! Don't use it unless you know what you are doing.
|
|
|
|
void setLineNo(int l) { lineno = l; }
|
|
|
|
/// returns a lex code
|
|
|
|
int lex();
|
|
|
|
|
|
|
|
/** Just read athe next word. If esc is true remember that
|
|
|
|
some chars might be escaped: "\ atleast */
|
|
|
|
bool next(bool esc = false);
|
|
|
|
|
|
|
|
/** Read next token. This one is almost the same as next,
|
|
|
|
but it will consider " as a regular character and always
|
|
|
|
split a word if it contains a backslash.
|
|
|
|
*/
|
|
|
|
bool nextToken();
|
|
|
|
|
|
|
|
///
|
1999-12-01 00:57:31 +00:00
|
|
|
int GetLineNo() const { return lineno; }
|
1999-09-27 18:44:28 +00:00
|
|
|
///
|
1999-12-01 00:57:31 +00:00
|
|
|
int GetInteger() const;
|
1999-09-27 18:44:28 +00:00
|
|
|
///
|
1999-12-01 00:57:31 +00:00
|
|
|
bool GetBool() const;
|
1999-09-27 18:44:28 +00:00
|
|
|
///
|
1999-12-01 00:57:31 +00:00
|
|
|
float GetFloat() const;
|
1999-09-27 18:44:28 +00:00
|
|
|
///
|
1999-10-02 16:21:10 +00:00
|
|
|
string GetString() const;
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
|
|
/// get a long string, ended by the tag `endtag'
|
1999-12-01 00:57:31 +00:00
|
|
|
string getLongString(string const & endtoken);
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
|
|
///
|
|
|
|
bool EatLine();
|
|
|
|
///
|
1999-12-01 00:57:31 +00:00
|
|
|
int FindToken(char const * string[]);
|
1999-09-27 18:44:28 +00:00
|
|
|
///
|
1999-12-01 00:57:31 +00:00
|
|
|
int CheckToken(char const * string[], int print_error);
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
|
|
///
|
1999-12-01 00:57:31 +00:00
|
|
|
char const * text() const { return &buff[0]; }
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
|
|
/** Pushes a token list on a stack and replaces it with a new one.
|
|
|
|
*/
|
1999-12-01 00:57:31 +00:00
|
|
|
void pushTable(keyword_item *, int);
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
|
|
/** Pops a token list into void and replaces it with the one now
|
|
|
|
on top of the stack.
|
|
|
|
*/
|
|
|
|
void popTable();
|
|
|
|
|
|
|
|
/** Prints an error message with the corresponding line number
|
|
|
|
and file name. If message contains the substring `$$Token',
|
|
|
|
it is replaced with the value of GetString()
|
|
|
|
*/
|
1999-12-01 00:57:31 +00:00
|
|
|
void printError(string const & message) const;
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
|
|
/**
|
1999-10-07 18:44:17 +00:00
|
|
|
Prints the current token table on cerr.
|
1999-09-27 18:44:28 +00:00
|
|
|
*/
|
|
|
|
void printTable();
|
|
|
|
protected:
|
|
|
|
///
|
|
|
|
enum {
|
1999-12-01 00:57:31 +00:00
|
|
|
///
|
1999-09-27 18:44:28 +00:00
|
|
|
LEX_MAX_BUFF = 2048
|
|
|
|
};
|
|
|
|
|
|
|
|
///
|
|
|
|
struct pushed_table {
|
|
|
|
///
|
|
|
|
pushed_table(){
|
1999-11-15 12:01:38 +00:00
|
|
|
next= 0;
|
|
|
|
table_elem= 0;
|
1999-09-27 18:44:28 +00:00
|
|
|
}
|
|
|
|
///
|
1999-12-01 00:57:31 +00:00
|
|
|
pushed_table * next;
|
1999-09-27 18:44:28 +00:00
|
|
|
///
|
1999-12-01 00:57:31 +00:00
|
|
|
keyword_item * table_elem;
|
1999-09-27 18:44:28 +00:00
|
|
|
///
|
|
|
|
int table_siz;
|
|
|
|
};
|
|
|
|
|
|
|
|
///
|
1999-12-01 00:57:31 +00:00
|
|
|
FILE * file;
|
1999-09-27 18:44:28 +00:00
|
|
|
///
|
|
|
|
bool owns_file;
|
|
|
|
///
|
1999-10-02 16:21:10 +00:00
|
|
|
string name;
|
1999-09-27 18:44:28 +00:00
|
|
|
///
|
|
|
|
int lineno;
|
|
|
|
///
|
1999-12-01 00:57:31 +00:00
|
|
|
keyword_item * table;
|
1999-09-27 18:44:28 +00:00
|
|
|
///
|
|
|
|
int no_items;
|
|
|
|
///
|
|
|
|
char buff[LEX_MAX_BUFF];
|
|
|
|
///
|
1999-12-01 00:57:31 +00:00
|
|
|
pushed_table * pushed;
|
1999-09-27 18:44:28 +00:00
|
|
|
///
|
|
|
|
int search_kw(char const * const) const;
|
|
|
|
///
|
|
|
|
short status;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
inline
|
1999-12-01 00:57:31 +00:00
|
|
|
bool LyXLex::IsOK() const
|
1999-09-27 18:44:28 +00:00
|
|
|
{
|
|
|
|
return (file && !feof(file));
|
|
|
|
}
|
|
|
|
|
1999-12-01 00:57:31 +00:00
|
|
|
// This is needed to ensure that the pop is done upon exit from methods
|
|
|
|
// with more than one exit point or that can return as a response to
|
|
|
|
// exceptions. (Lgb)
|
|
|
|
struct pushpophelper {
|
|
|
|
pushpophelper(LyXLex & lexrc, keyword_item * i, int s) : lex(lexrc) {
|
|
|
|
lex.pushTable(i, s);
|
|
|
|
}
|
|
|
|
~pushpophelper() {
|
|
|
|
lex.popTable();
|
|
|
|
}
|
|
|
|
LyXLex & lex;
|
|
|
|
};
|
|
|
|
|
1999-09-27 18:44:28 +00:00
|
|
|
#endif
|