#!/usr/local/bin/perl
#
# Copyright (C) 1996 Tetsuji KUBOYAMA and Makoto AMAMIYA
#

#
# main loop
#
# $shift{$state,$1}
# $sr_conf{$state,$1}
# $rr_conf{$state,$1}

print "true --> scan(S) | s(S,[0]).\n";

while (<>){
    if (/^rule (\d+)[ \t]+(\w+) -> ([\w ]+)/) {
	$head{$1}="$2";
	@tmp=split(" ",$3);
	$tmp="C1";
	for ($i=2; $i<=1+$#tmp; $i++) {
	    $tmp .= ",C$i";
	}				
	$body{$1}=$tmp;
    }
    if (/^state (\d+)/) {
	$state = $1;
    }
    if (/(\$|\w+)[ \t]+shift, and go to state (\d+)/){
	#  $state ǵ $1 ˤ $2 ˥ե
	$states{"$state $1"}=1;
	$shift{"$state $1"}=$2;

    }
    if (/([\$\w]+)[ \t\[]+reduce using rule (\d+) \((\w+)\)/) {
	# print " $state ǵ $1 ˤ $3 ˵§ $2 ѤƴԸ\n";
	$states{"$state $1"}=1;
	$reduce{"$state $1"} .= " $2";
	$rr_conf{"$state $1"}++;

    }			      
    if (/^[ \t]*([\$\w]+)[ \t]+go to state (\d+)/){
	if ($1 eq "\$") {
	    print "s(['\$'|X],[$state|Y]) --> s(['\$'|X],[$2|Y]).\n";
	} else {
	    $goto .= " $state,'$1',$2";
	}
    }
    if (/([\$\w]+)[ \t]+accept/){
	print "s(['\$'|_],[$state,Info|_]) --> builtin:print(Info) | false.\n";
    }
}

##print join("\n",reverse sort keys %states);
foreach $state (reverse sort keys %states) { # ƾ˾ʬ
    ($st,$sym)=split(" ",$state);        # ֤ϵ
    if (defined($shift{$state})) { # եȤ
	$sym{$st} .= " '$sym'";
	print "s(['$sym'(C)|X],[$st|Y]) --> s(X,[$shift{$state},'$sym'(C),$st|Y])";
	if ($rr_conf{$state}==0) {	# եȤΤߤξ
	    print ".\n";  
	} else {		# ե/Ըξ
	    @reduce=split(" ",$reduce{$state}); # Ը
	    foreach $rule (@reduce) {
		print ";reduce_$rule(['$sym'(C)|X],Y)";
	    }
	    print ".\n";
	}
    } elsif ($rr_conf{$state}>0) { # Ը(ޤ)ξ
	$cnstrt="";
	if ($sym eq "\$default") {
	    $sym="Z";		 
	    $cnstrt=",{functor(Z,F,_),".join("\\=F,",split(" ",$sym{$st}))."\\=F}" if ($sym{$st});
	} else {
	    $sym="\'$sym\'";
	}
	print "s([$sym|X],[$st|Y])$cnstrt --> ";
	@reduce=split(" ",$reduce{$state}); # Ը
	$interm=0;
	foreach $rule (@reduce) {
	    print ";" if ($interm);
	    print "reduce_$rule([$sym|X],Y)";
	    $interm=1;
	}
	print ".\n";
    }
}
foreach $rule (keys %head) {
    $bd=$body{$rule};
    $bd2=join(",_,",reverse split(",",$bd));
    $hd=$head{$rule};
    print "reduce_$rule(X,[$bd2,S|Y]), goto(S,'$hd',NS) --> s(X,[NS,'$hd'($bd),S|Y]).\n";
}



foreach $i (split(' ',$goto)){
    print "true --> goto($i).\n";
}
#print "goto(X,S,Y),goto(Y,S,Z) --> goto(X,S,Z).\n";

print "\n%%%%\n";
print <<EOF;
:- kl1_program.

scan(Ss) :-    
  klicio:klicio([stdin(normal(In))]),
  In = [gett(s(S))],
  main:append(S,['\$'],Ss).
EOF
    
    
