Ein EBNF Parser in Perl

Dieses Buch bei Amazon EBNF-Grammatiken (erweiterte Backus-Naur-Form) dienen der Beschreibung von Sprachen und werden im Compilerbau,aber auch in vielen anderen Bereichen der Informatik eingesetzt. Beschreibt man eine Sprache in EBNF,so kann quasi "automatisch" ein Parser konstruiert werden.

#!/usr/bin/perl -w

use strict;

# [expression] ::= [term] | [term] OR [expression]
# [term] ::= [factor] | [factor] AND [term]
# [factor] ::= ( [expression] ) | NOT [expression] | [string]
# [string] ::= ".*" | \w+

# [literal] ::= '(' | ')' | 'OR' | 'AND' | 'NOT'

sub literal($);
sub expression();
sub term();
sub factor();
sub string();
sub error($);
sub parse();

my $tab=0;
my $TAB=" ";
my $error;


parse;
exit 0;

sub literal ($) {
	$tab++;
	my $lit = $_[0];# The literal string to be consumed.
	my $test = s/^\s*\Q$lit\E\s*//;
	if ($test) {
		#print $TAB x $tab,"literal $lit\n";
		$tab--;
		return 1;
	} else {
		$tab--;
		return 0;
	}
}


sub expression () {
	$tab++;
	term;
	expression if literal 'OR';
	print $TAB x $tab,"expression $_\n";
	$tab--;
}

sub term () {
	$tab++;
	factor;
	term if literal 'AND';
	print $TAB x $tab,"term $_\n";
	$tab--;
}

sub factor () {
	$tab++;
	if ( literal '(' ) {
		expression;
		error 'missing )' unless literal ')';
	} elsif ( literal 'NOT' ) {
		error 'empty negation' if $_ eq '';
		expressionss00
	} else {
		string;
	} 
	print $TAB x $tab,"factor $_\n";
	$tab--;
}

sub string () {
	if (s/^\s*(?:"([^"]+)"|(\w+))\s*//) {
		$tab++;
		if (defined $1) {
			#print $TAB x $tab,"string $1\n";
			$tab--;
			return $1;
		} elsif (defined $2) {
			#print $TAB x $tab,"string $2\n";
			$tab--;
			return $2;
		}
		$tab--;
	}
}

sub error ($) {
	my $msg = $_[0];
	warn "$msg: $_\n";
}

sub parse () {
	while (  ) {
		chomp;
		expression;
		error 'illegal input' if $_ ne '';
	}
}

Alle Touren

Schneebergwege

Raxsteige

Geführte Touren

Perl

Literatur

Musik