#ifndef SYN_DEF
 #define SYN_DEF


//------------------- SYNTAX ANALYZER Module --------------------//
//						  v 08 . 04 .  2007						 //
//																 //
//								MT								 //
//---------------------------------------------------------------//



//---------------------- Incudes 
#include "stdio.h"
#include "ctype.h"
#include "strings.h"
#include "../ui/onerror.hpp"

#include "lex.hpp"
//====================== Includes


//---------------------- Defines
#define INT_SIZE 10
#define LEX_OVER "lexems are over. \0"
//====================== Defines


enum type {t_var, t_var_array, t_not_var};

class CSyntax {
	Lexeme* begin, *prev, *current, *next;
	CError Error;
	bool passed;

		void SetToBeginLex() {prev=NULL; current=begin; next=begin->next;};
		void NextLex() {   if (current->next == NULL) throw LEX_OVER;
							if (prev == NULL) prev = begin; else  
							{ prev=current; current = next; if (current->next != NULL) next=current->next; }};
		void BackLex() { next = current; current = prev; };
	
		void ShowError(const char *message);

	//---
		type  sx_Identifier();
		type  sx_RobotData();

		void  sx_Expression();
				void sx_Expression_And();
				void sx_Expression_Or();
				void sx_Expression_Bool();
				void sx_Expression_Term();
				void sx_Expression_Primary();

		void  sx_Statement();
				bool  sx_Statement_Indetifier();
				bool  sx_Statement_IfElse();
				bool  sx_Statement_Cycle();
				bool  sx_Statement_Goto();
				bool  sx_Statement_Robot();

		bool sx_Program();
		
	//===


	public:

		CSyntax(Lexeme* begin_lex) { begin = begin_lex; SetToBeginLex(); };
		~CSyntax() {  };

		bool MakeAnalysis();
};



//---------------------- GRAMMER 

/*
<Program> ::= <statement>

<lx_label> ::= @<name>
<identifier> ::= $<char>{<char>} 
<robot_commands> ::= ? [turn | auto | prod <expression> | 
						sell <expression>, <expression> | buy <expression>, <expression>
						print "<string>", <expression> {,<expression>}  ]

<statement> ::= 
	<identifier> {'['<expression>']'} := <expression> | 
	if (<expression>) <statement> [else <statement>] |
    goto <lx_label> | <lx_label> |
	'{' <statement> {;<statement>} '}' |
	<robot_commands>


<expression> ::= <and> {'&' <and>}

<and> ::= <or> {'|' <or>}
<or> ::= <bool> [ > |< |= ] <bool> ]
<bool> ::= <term> { [ +| - ] <term> }
<term> ::= <primary> {[ *| /| %] <primary>}

<name_data> ::= <char>{<char>}[ '['<expression>']' ]

<primary> ::= 
	<identifier> [ '['<expression>']' ] | 
	.<name_data>{.<name_data>} |
	<integer_const> | 
	(<expression>) |

	-<primary> | 
	!<primary>
*/


//==============================


#endif
