用Perl编写的一个小的词法分析器

#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#
#	@File  : Lexical_Analyzer.pl
#	@Author: Roc
#	@Date  : 2013/10/21
#	@Func  : Lexical analyser
#	@Idea  :  In this program,we cut sentences to words.
#			  Then,we will match each word.
#
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

#!/usr/bin/perl
use warnings;
use 5.010;

say "Please input your program here.(Input '__END__' to stop inputing)";

##
#input here
#
open (FH, ">LexicalAnalyser.txt") or die "can't open the file: $!";
while (<STDIN>) {
	if (/__END__/){
		#Input over.Close file 
		close (FH) or die "Can't close file: $!";
		last;	#Interrupt here
	} else {	
		#debug
		#print "I saw $_";
		chomp ($_);	#delete 'Enter'
		say FH $_;

	}
} #End of while

##
#output program here.We just test our input.
#
$count = 1;
say "\n+------------------------------------------------+";
say "\tInput over.Here is your program.\n";
#
#Read file here.
#We just want to see if we write into the file
#
open (FH, "<LexicalAnalyser.txt") or die "can't open the file: $!";
foreach (<FH>) {
	chomp;
	say "Line $count: $_";
	$count++;
}
say "+------------------------------------------------+\n";
close (FH) or die "can't close file: $!";
#debug
#say "@Tmp\n";


##
#Exchange special flags here.I just list a little:like , } { ) ( and ;
#
open (FH, "<LexicalAnalyser.txt") or die "can't open the file: $!";
foreach (<FH>){
	foreach (split){
		#debug
		#print "!!!!!!!!!!!!!!!!!!!!\n";
		
		#We have already separated each word.
		#Thus, it doesn't matter if we add g here.
		s/(\w+)(,|;|\)|\(|\}|\{)/$1 $2/g;
		s/(,|;|\(|\)|\{|\}|:|\[|\])(\w+)/$1 $2/g;
		s/(;|\(|\)|\{|\})/ $1/g;
		#Store in Tmp2
		push @Tmp2, $_;
	}
}
close (FH) or die "can't close file: $!";


##
#We match here
#
foreach (@Tmp2){
	#debug
	#say "$_";
 foreach (split){
	 #debug
	 #print "!!!!!!!!!!!!!!!!!!!!\n";
	 if ($_ =~ /main\(\)/){
		 push @Tmp3, "\(2, \"main\"\)";
     } elsif ($_ =~ /(int|float|for|while|do|return|break|continue|unsigned|public|void)/){
		 push @Tmp3, "\(1, \"$_\"\)";
	 } elsif ($_ =~ /[a-z]+/){
		 push @Tmp3, "\(2, \"$_\"\)";
	 } elsif ($_ =~ /\p{Digit}.*/){
   		 push @Tmp3, "\(3, \"$_\"\)";
     } elsif ($_ =~ /(=|>=|<=|!=|!|>|<|\+|-|\*|\/)/){
		 push @Tmp3, "\(4, \"$_\"\)";
	 } elsif ($_ =~ /(\(|\)|\{|\}|;|,|:)/){
		 push @Tmp3, "\(5, \"$_\"\)";
	 }
	 #debug
	 #print "$_\n";
	# push @Tmp1, $_;    #再设置一个暂存区
  } #End of foreach(split)
} #End of foreach(@Tmp2)

##
#Output here
#
say "++++++++++++Final Answer+++++++++++";
say "-----------------------------------";
foreach (@Tmp3){
	say "$_";
}
say "+---------------------------------+";
say "+++++++++++++++END+++++++++++++++++";

编程技巧