/*-*-c++-*-
 * $Id: parser.h,v 1.1 2002/01/28 15:38:33 holzheu Exp $
 *
 * This file is part of qlcrash, a GUI for the dump-analysis tool lcrash.
 *
 * Copyright (C) 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation
 *
 * Authors:
 * Michael Geselbracht (let@users.sourceforge.net)
 * Fritz Elfert (elfert@de.ibm.com)
 * Michael Holzheu (holzheu@de.ibm.com)
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version. See the file COPYING for more
 * information.
 */
#ifndef PARSER_H
#define PARSER_H

#define _GNU_SOURCE

#include <qdict.h>
#include <qobject.h>
#include <qlist.h>
#include <qstring.h>
#include <qvector.h>

#include "crashtypes.h"

#undef QLDEBUG

struct TreeNode {
	QString name;
	QString value;
	QString arrayType;
	NodeType type;
	QList<TreeNode> childList;
	
	TreeNode() {
		childList.setAutoDelete(true);
	}
};

union TokenStruct {
	TreeNode* node;
	QString* string;
};

union TokenWhatIs {
	QList<QString>* list;
	QString* string;
	QDict<QString>* map;
};

class CParser : QObject {
	Q_OBJECT
	
public:
	CParser(QObject* parent, const char* name=0);
	~CParser();
	
	void setString(QString str);
	void reset();
	
	// create a struct tree from the "print"-output in oLexString
	void parseStruct();
	
	inline TreeNode* root() {
		return oRoot;
	}
	
	// used by the struct parser to set the created struct tree
	inline void setRoot(TreeNode* n) {
		oRoot = n;
	}
	
	// create a type map from the "whatis"-output in oLexString
	void parseWhatIs();
	
	inline QDict<QString>* typeMap() {
		return oTypeMap;
	}
	
	// used by the type parser to set the created type map
	inline void setTypeMap(QDict<QString>* dict) {
		oTypeMap = dict;
	}
	
	// returns true if the last recently issued parser has finished its job
	inline bool finished() const {
		return oFinished;
	}
	
	// returns true if an error occured during parsing
	inline bool error() const {
		return oError;
	}
	
	// set by the parsers to indicate that their job is done
	inline void setFinished(bool w) {
		oFinished = w;
	}
	
	// set by the parsers to indicate an error
	void setError(bool w);
	
	// used by the type parser to separate member names from their types
	void splitType(QList<QString>*, QString& name, QString& type);
	
	// create a task list from the "task"-output in oLexString
	void parseTaskList();
	
	inline QList<QVector<QString> >& taskList() {
		return oTaskList;
	}
	
private:
	// tokenizer
	bool getTokenStruct(int& id, TokenStruct& value);
	bool getTokenWhatIs(int& id, TokenWhatIs& value);
	bool getTokenTask(int& id, QString& value);
	
	// debug
	void printMap();
	void printNodes(TreeNode*, int level=0);
	
private:
	QString oLexString;
	int oIndex;
	void* oParser;
	void* oParserWhatIs;
	TreeNode *oRoot;
	QDict<QString>* oTypeMap;
	QList<QVector<QString> > oTaskList;
	bool oFinished;
	bool oError;
};

#endif
