sub expect_Elements { my $stream = shift; my $expression; $p = save_position($stream); if (next_token() eq "(") { eat_token($stream); $expression = [ expect_CCL_Find($stream) ]; # It might make more sense to die() here if (eat_token() ne ")") { $expression = undef; } } else { if ($expression = expect_Set($stream)) { } elsif ($expression = expect_Terms($stream)) { } elsif ($expression = expect_Qualifiers($stream)) { if ($rel = expect_Relation($stream)) { if (next_token($stream) eq "(") { eat_token(); $expression = [ expect_CCL_Find($stream) ]; (eat_token() eq ")") or $expression = undef; } elsif ( my $terms = expect_Terms($stream) ) { $expression = [ $rel, $expression, $terms ]; } else { $expression = undef; } } elsif (next_token($stream) eq "=") { eat_token(); $string1 = expect_string($stream); $op = next_token($stream); $string2 = expect_string($stream); if (!defined $string1 or !defined $string2 or !defined $op or $op ne "-") { $expression = undef; } else { $expression = [ "=", $expression, $string1, "-", $string2 ]; } } else { $expression = undef; } } else { $expression = undef; } } if (defined $expression) { return $expression; } else { restore_position($stream, $pointer); return undef; } }