ARG,sin(
ARG,si
ARG,n
####
use strict;
use warnings;
package DFA;
my $dfa = {
start =>{nextstate =>{s =>'var1_1orfun1_1'},
entrytoken=>'OTHER'},
var1_1orfun1_1=>{nextstate =>{i =>'var1_2orfun1_2'}},
var1_2orfun1_2=>{exittoken =>{n =>'',
default=>'ARG'},
nextstate =>{n =>'fun1_3',
s =>'var1_1orfun1_1'}},
fun1_3 =>{nextstate =>{'(' =>'fun1_4'}},
fun1_4 =>{exittoken =>{default=>'ARG'},
nextstate =>{s =>'var1_1orfun1_1'}}
};
bless($dfa,"DFA");
sub lex {
my $self = shift;
my @input = split('',shift);
my @output = ();
my $buffer = '';
my $currentstate = $self->{start};
for my $c (@input) {
#exit action
if( my $a = $currentstate->{exittoken} ) {
if( my $tt = defined($a->{$c})?$a->{$c}:$a->{default} ) {
push(@output,{type=>$tt,value=>$buffer});
$buffer = '';
}
}#end exit action if
#state transition
my $s = $currentstate->{nextstate}->{$c} || 'start';
$currentstate = $self->{$s};
$buffer = $buffer.$c;
#entry action
if( my $tt = $currentstate->{entrytoken} ) {
push(@output,{type=>$tt,value=>$buffer});
$buffer = '';
}#end entry action if
}#end for loop
#eof exit action
if($buffer) {
my $a = $currentstate->{exittoken};
my $tt = ($a)?$a->{default}:'OTHER';
push(@output,{type=>$tt,value=>$buffer});
}
return @output;
}#end function lex
my $inputstring = 'sin(';
print("an input of $inputstring produced the following output.\n");
for my $tok ($dfa->lex($inputstring)) {
print("$tok->{type},$tok->{value}\n");
}
$inputstring = 'sisin(si';
print("an input of $inputstring produced the following output.\n");
for my $tok ($dfa->lex($inputstring)) {
print("$tok->{type},$tok->{value}\n");
}
$inputstring = 'sin(sisin(';
print("an input of $inputstring produced the following output.\n");
for my $tok ($dfa->lex($inputstring)) {
print("$tok->{type},$tok->{value}\n");
}
####
an input of sin( produced the following output.
ARG,sin(
an input of sisin(si produced the following output.
ARG,si
ARG,sin(
ARG,si
an input of sin(sisin( produced the following output.
ARG,sin(
ARG,si
ARG,sin(