#!/usr/bin/perl

use strict;

#Takes one argument, <grammarName>.c and writes output file temp.c
# The array tokList[] must be defined as const char *

my $ARGC = @ARGV;
my $parserName = "";
my $astActive = "false";

main();

#define	    MATCHT(t, fs)					RECOGNIZER->match(RECOGNIZER, t, fs); \
#                                            printf("MATCH %s : %d\n",tokList[t],PSRSTATE->failed)
# <TOKEN_NAME>   MATCH line XXXX
# <TOKEN_NAME> NOMATCH line XXXX
sub main()
{
  #Create file string
  my $parserFile = "<" . $ARGV[0];
  $parserName = $parserFile;
  $parserName =~ s/\.c//;
  $parserName =~ s/<//;
  my $tempFile = ">temp.c";
  my $funcPrefix = "for(int i=0;i<FOLLOWSTACK->size(FOLLOWSTACK);i++) printf(\"\%c\",32);";
  my $incString = "#include    \"" . $parserName . ".h\"";
  
  my $basePrefix = "printf(\"%12s %7s line:%6d\\n\",tokList[INDEX],";
  my $baseSuffix = ",__LINE__);";
  
  print "->$parserName<-\n";
  print "->$incString<-\n";
  
  #Input file
  open(INFILE,$parserFile);
  print "Opened $parserFile\n";
  #Output file
  open(OUTFILE,$tempFile);
  print "Opened $tempFile\n";
  
  #For each line
  while(my $line = <INFILE>)
  {
    #chomp($line); #Remove newline
    
    #print "Found " . $line;
    #String needs to prefix the CONSUME function
    if($line =~ /^\s*CONSUME\(.*/)
    {
    
    }
    else
    {
      print OUTFILE $line;
    }
    
    # The string "   ADAPTOR	= ANTLR3_TREE_ADAPTORNew..." exists only in grammars with AST output enabled
    if($line =~ /^\s*ADAPTOR\s*=\s*ANTLR3_TREE_ADAPTORNew\(/)
    {
      $astActive = "true";
      print "AST active\n";
    }
    #If this is a rule function
    elsif($line =~ /^\w*\(p$parserName ctx\)/)
    {
      my $funcName = $line;
      chomp($funcName);
      $funcName =~ s/\(p$parserName ctx\)//;
      $funcName = $funcPrefix . "printf(\" " . $funcName . "\\n\");" . "\n";
      #printf  $funcName . "\n";
      #print $funcPrefix ;
      
      $line = <INFILE>; # {
      print OUTFILE $line;
      print OUTFILE $funcName;
    }
    #SIMPLE_IDENT19 = (pANTLR3_COMMON_TOKEN) MATCHT(SIMPLE_IDENT, &FOLLOW_SIMPLE_IDENT_in_simple_identifier210); 
    #If this is a MATCH function
    elsif((($astActive eq "true") && ($line =~ /^.*\(pANTLR3_COMMON_TOKEN\)\s*MATCHT\(.*/)) ||
          (($astActive eq "false") && ($line =~ /^\s*MATCHT\(.*/))) 
    {
      my $tokName = $line;
      $tokName =~ s/.*MATCHT\((\w*),.*\n/$1/;
      #print "FOUND ->$tokName<-\n";
      if($tokName eq "EOF")
      {
        $tokName = "0";
      }

      
      my $printString = $basePrefix;
      $printString =~ s/INDEX/$tokName/;
      my $firstString = "if(PSRSTATE->failed) $printString \"NOMATCH\" $baseSuffix";
      my $secondString = "else $printString \"MATCH\" $baseSuffix\n";
      
      print OUTFILE $firstString;
      print OUTFILE $secondString;
    }
    #If this is a CONSUME function
    elsif($line =~ /^\s*CONSUME\(.*/)
    {
      my $printString = $basePrefix;
      $printString =~ s/INDEX/LA(1)/;
      my $secondString = "$printString \"MATCH\" $baseSuffix";
      
      print OUTFILE $secondString;
      print OUTFILE $line;
    }
    #If this is the include section
    elsif($line =~ /$incString/)
    {
      print OUTFILE "extern const char * tokList[];\n";
    }
    
  }
  close(INFILE);
  close(OUTFILE);
  #rename($tempFile,$parserFile);
}
