Function and globaks with expr calling

 #include <stdio.h>
#include "commons.h"
#include <stdlib.h>

void array_decl(_bool* is_arraydecl)
{
  static _bool is_open_sqbr = FALSE;
  static int count =0;
    if(tok == '[')
    {
      count++;
      if(count > 1)
      {
         make_error("unexpected [ \n",_FATAL_ERR, getTokenNumber(), __LINE__,__func__);
         return;
      }

      is_open_sqbr = TRUE;
      nextToken();
    }
else if(tok == ID || tok == ICONST || tok == FCONST)
{  _bool is_expr;
if(is_expr(&expr))
{
}
else if(tok == ID && lookupToken() == '(')
{
  function_caller();
}
else
{
}
// need to check whether it's an expression
nextToken();
}
    else if(tok == ']')
    {
        count--;
        if(is_open_sqbr == FALSE)
        {
           make_error("expected [ \n", _FATAL_ERR, getTokenNumber(), __LINE__, __func__);
           return;
        }
        *is_arraydecl = TRUE;
        is_open_sqbr = FALSE;
        nextToken();
        return;
    }
    else if(is_open_sqbr == TRUE) // expression
    {
        nextToken();
    }

    if(tok == EOF)
      return;
    else if(tok != ID || tok != ';')
      array_decl(is_arraydecl); 
}


void declaration_specifiers(_bool* is_decl_sp, int* type)
{
    if(tok == TYPEDEF || 
       tok == EXTERN || 
       tok == STATIC || 
       tok == AUTO || 
       tok == REGISTER)
    {
      nextToken();   
    }
    if(tok == CONST ||
      tok == VOLATILE)
    {
        
       nextToken(); 
    }
    
    if(tok == SIGNED ||
       tok == UNSIGNED)
    {

      nextToken();
    }

    if(tok == VOID || 
       tok == CHAR ||
       tok == SHORT || 
       tok == INT ||
       tok == LONG ||
       tok == FLOAT ||
       tok == DOUBLE ||
       tok == SIGNED ||
       tok == UNSIGNED
       )
       {
          *type = tok; 
          *is_decl_sp = TRUE;
          nextToken(); 
       }
       else if(tok == STRUCT ||
         tok == UNION)
      {
           nextToken();
           if(tok == ID)
           {
              *is_decl_sp = TRUE;
              nextToken();
           }
          //struct_or_union();
      }
      else {
         make_error("Type missing in declaration\n", _FATAL_ERR, getTokenNumber(), __LINE__, __func__);
         return;
      }
     while(tok == '*')
     {
        nextToken();
     }
     if(tok == '[')
     {
        _bool is_validarr=FALSE;
        array_decl(&is_validarr);

     }   

 
      if(tok == ID && *is_decl_sp == TRUE)
      {
         *is_decl_sp = TRUE;
         nextToken();

      }
      else {
         make_error("Identifier missing in declaration\n", _FATAL_ERR, getTokenNumber(), __LINE__, __func__);
         return;
      }

 
   return;
}
void args(_bool *is_args)
{
 static _bool is_comma = FALSE;
   if(tok == '(')
   {
     *is_args = TRUE;
     nextToken();
   }
   else if(tok == ',')
   {
      is_comma = TRUE;
      nextToken();

   }
   else if(tok == ')')
   {
      if(is_comma == TRUE) // for case " int id ,)"
      {
         make_error("expected identifier between , and ) \n", _FATAL_ERR, getTokenNumber(), __LINE__, __func__);
         return;
      }

      if(*is_args == FALSE)
      {
         make_error("expected \'( \' \n", _FATAL_ERR, getTokenNumber(), __LINE__, __func__);
         return;
      } 


      nextToken();
      return; 
   }
   else
   {
      if( is_args == FALSE && is_comma == FALSE)
      {
         make_error("expected , or ( before  \n", _FATAL_ERR, getTokenNumber(), __LINE__, __func__);
         return;
      }
      _bool paramter_var = FALSE;
      int type;
      declaration_specifiers( &paramter_var, &type);
      if(paramter_var == FALSE)
      {
         make_error("Function argument is invalid\n", _FATAL_ERR, getTokenNumber(), __LINE__, __func__);
      }
      else
      {
        is_comma = FALSE;
      }
   }

   if(tok == ';')
     return;
   else if(tok == EOF)
   {
       make_error(" ; expected!\n", _FATAL_ERR,getTokenNumber() , __LINE__, __func__);
       return; // return is needed to kill the infinite recursion
   }
   else if(tok != ';')
    args(is_args); 
}

void function_caller(_bool* is_func_caller)
{
   _bool is_id_before = FALSE;
   if(tok == ID)
   {
     nextToken();
       if(tok == '(')
       {
          nextToken();
          while( tok != ')' || tok != EOF || tok != ';')
          {
             switch(tok)
             {
               case ID:
                 is_id_before = TRUE;
                 nextToken();
               break;

               case ',':
                 nextToken();
                if(is_id_before == FALSE)
                {
                  make_error("Function callee is expecting id before ,\n", _FATAL_ERR, getTokenNumber(), __LINE__, __func__);
                  return;
                }
                else
                  is_id_before = FALSE;
               break;

               default:
                  make_error("Function callee is expecting id before ,\n", _FATAL_ERR, getTokenNumber(), __LINE__, __func__);
                  return;
               break;

             }

          }
          if(tok == ')')
          {
              if(is_id_before == FALSE)
              {
                  make_error("Function callee is expecting id before )\n", _FATAL_ERR, getTokenNumber(), __LINE__, __func__);
                  return;
              }
              *is_func_caller = TRUE;
              return;
          }
          else
            *is_func_caller = FALSE;
       }

   }

}


void block_start_statement(_bool *is_blk )
{
    if(tok == '{')
    {
          block_level++;
          *is_blk = TRUE;
          nextToken(); 
    }
    
}
void block_end_statement(_bool *is_blk)
{
    if(tok == '}')
    {
          block_level--;
          *is_blk = FALSE;
          nextToken();
    }

}



void function_definition_or_declaration(_bool *is_func_def, _bool *is_func_decl)
{
    _bool is_decl=FALSE, is_args=FALSE, is_blk=FALSE , is_stmt=FALSE;
    int type;
    declaration_specifiers( &is_decl , &type);
    if(is_decl == FALSE)
    {
       *is_func_def = FALSE;
       *is_func_decl = FALSE;
        return;
    }
    args(&is_args);
    block_start_statement( &is_blk);
    if( is_blk == TRUE && is_args == TRUE)
    {
      //statement_list( &is_stmt);
      block_end_statement( &is_blk);
      *is_func_def = TRUE;
    }
    else if(tok == ';')
    {
        *is_func_decl = TRUE;
    }

    if( block_level > 1)
    {
         make_error("nested function is not allowed!\n", _FATAL_ERR, getTokenNumber(), __LINE__, __func__);
         return;
    }

}

void multiple_declaration(_bool *is_mdecl)
{
   _bool is_decl_sp = FALSE, is_comma=FALSE;
    int type; 
   declaration_specifiers(&is_decl_sp, &type); 
   if(tok == ',')
   {
      is_comma = TRUE;
      while(tok != ';' && tok != EOF)
      {
         switch(tok)
         {
           case ',':
             if(is_comma == TRUE)
             {
                make_error("Multiple commas notices \n", _FATAL_ERR, getTokenNumber(), __LINE__, __func__);
                return;
             }
            nextToken();
           break;
           case ID:
             if(is_comma == FALSE)
             {
                make_error("illegal declarations!\n", _FATAL_ERR, getTokenNumber(), __LINE__, __func__);
                return;
             }
            is_comma = FALSE;
            nextToken();
           break;

      
         }         
      }
      if(tok == ';')
      {
         *is_mdecl = TRUE;
         return;
      }
      else if(tok == EOF)
      {
         make_error("; expected ! \n", _FATAL_ERR, getTokenNumber(), __LINE__, __func__);
         return;
      }
   }
}

enum parser_check // enum is used for indexing the different types of language elements such as expr, stmt, func_def
{
   is_mdecl,
   is_func_def,
   is_func_decl,
   MAX_SIZE
}; 
void global_scope()
{
   _bool parsing_check[MAX_SIZE]; // for checking if any one of parsing is successful
   parsing_check[is_mdecl]= FALSE;
   parsing_check[is_func_def]= FALSE;
   parsing_check[is_func_decl] = FALSE;
   int i=0;
   init_error(); 
   while(tok != EOF)
   {
     multiple_declaration(&parsing_check[is_mdecl]);
     function_definition_or_declaration(&parsing_check[is_func_def], &parsing_check[is_func_decl]); 
  
     for(i=0; i<MAX_SIZE; i++) // index refers to enum parser_check
     {
        if(parsing_check[i] == TRUE)
        {
          break; 
        }

     }

      switch(i)
      {
          case is_mdecl:
           printf("multiple declaration!" );
          break;

          case is_func_def:
           printf("function defination!" );

          break;

          case is_func_decl:
           printf("function declaration!" );
          break;


      }

     if(is_mdecl == FALSE && is_func_def == FALSE && is_func_decl == FALSE )
     {
          show_error();
          exit(0);
     }

   }
}

int main()
{
    arr[0] = STATIC;
    arr[1] = INT;
    arr[2] = ID;
    arr[3] = '(';
    arr[4] = ')';
    arr[5] = '{';
    arr[6] = '}';
    arr[7] = EOF;
     global_scope();
    return 0;
}

Comments