getc. Grab the whole line and operate on it all at once.
@chars = split //, $input;
while (@chars) {
$c = shift @chars;
# State machine;
}
Is far too low level. Try something more like:
sub parse_expr {
local $_ = shift;
my @tokens = ();
my $paren = 0;
my $want_term = 1;
while (length) {
s/^\s*//;
if (s/^\(//) {
return unless $want_term;
push @tokens, '(';
$paren++;
$want_term = 1;
next;
}
if (s/^\)//) {
return if $want_term;
push @tokens, ')';
if ($paren < 1) {
return;
}
--$paren;
$want_term = 0;
next;
}
if (s/^and\b//i || s/^&&?//) {
return if $want_term;
push @tokens, '&';
$want_term = 1;
next;
}
if (s/^or\b//i || s/^\|\|?//) {
return if $want_term;
push @tokens, '|';
$want_term = 1;
next;
}
if (s/^not\b//i || s/^~// || s/^!//) {
return unless $want_term;
push @tokens, '~';
$want_term = 1;
next;
}
if (s/^(\w+)//) {
push @tokens, '&' unless $want_term;
push @tokens, $1 . '()';
$want_term = 0;
next;
}
return;
}
return "@tokens";
}
Forward to Avoid Symbolic References
Back to Use foreach() Loops
Up to index
Copyright © 1998, Tom Christiansen
All rights reserved.