/*----------------------------------------------------------------------
Compiler Generator Coco/R,
Copyright (c) 1990, 2004 Hanspeter Moessenboeck, University of Linz
extended by M. Loeberbauer & A. Woess, Univ. of Linz
ported to C++ by Csaba Balazs, University of Szeged
with improvements by Pat Terry, Rhodes University

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, 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.

As an exception, it is allowed to write an extension of Coco/R that is
used as a plugin in non-free software.

If not otherwise stated, any source code generated by Coco/R (other than 
Coco/R itself) does not fall under the GNU General Public License.
-----------------------------------------------------------------------*/


#if !defined(COCO_PARSER_H__)
#define COCO_PARSER_H__

#include "ast.h"
#include <string>


#include "Scanner.h"



class Errors {
public:
	int count;			// number of errors detected

	Errors();
	void SynErr(int line, int col, int n);
	void Error(int line, int col, const wchar_t *s);
	void Warning(int line, int col, const wchar_t *s);
	void Warning(const wchar_t *s);
	void Exception(const wchar_t *s);

}; // Errors

class Parser {
private:
	enum {
		_EOF=0,
		_ident=1,
		_number=2,
		_string=3,
		_lparen=4,
		_rparen=5
	};
	int maxT;

	Token *dummyToken;
	int errDist;
	int minErrDist;

	void SynErr(int n);
	void Get();
	void Expect(int n);
	bool StartOf(int s);
	void ExpectWeak(int n, int follow);
	bool WeakSeparator(int n, int syFol, int repFol);

public:
	Scanner *scanner;
	Errors  *errors;

	Token *t;			// last recognized token
	Token *la;			// lookahead token

AST root;  // current program unit (procedure or main program)

bool checkParametersList()
{
  scanner->ResetPeek();
  Token* x = scanner->Peek();
  return la->kind == _ident && x->kind  == _lparen;
}

bool checkInfix()
{
    scanner->ResetPeek();
  Token* x = scanner->Peek();
  return la->kind == _ident && x->kind  == _ident;
}



	Parser(Scanner *scanner);
	~Parser();
	void SemErr(const wchar_t* msg);

	void Xreate();
	void FDecl();
	void RuleDecl();
	void Ident(std::wstring& name);
	void Type(TypeAnnotation& typ);
	void FnTag(Function& f);
	void VDecl(Function& f);
	void Expr(Expression& e);
	void TypeTerm(TypeAtom& typ);
	void ListLiteral(Expression& e);
	void TagMod(TagModifier& mod);
	void Domain(DomainAnnotation& dom);
	void RGuard(RuleGuards& guards);
	void RBody(const RuleArguments& args, const RuleGuards& guards);
	void MetaExpr(Expression& e);
	void MetaExpr2(Expression& e);
	void MetaOp(Operator& op);
	void CalleeParams(Expression& e);
	void SimExpr(Expression& e);
	void RelOp(Operator& op);
	void Term(Expression& e);
	void AddOp(Operator& op);
	void Factor(Expression& e);
	void MulOp(Operator& op);

	void Parse();

}; // end Parser



#endif

