• Keine Ergebnisse gefunden

1. REGULÄRE AUSDRÜCKE

N/A
N/A
Protected

Academic year: 2021

Aktie "1. REGULÄRE AUSDRÜCKE"

Copied!
12
0
0

Wird geladen.... (Jetzt Volltext ansehen)

Volltext

(1)

T E X T M U S T E R V E R A R B E I T U N G

UNIX - Werkzeug

L E X

Kurze Einführung

1. REGULÄRE AUSDRÜCKE

Ein regulärer Ausdruck beschreibt eine (nicht leere) Menge von Zeichenfolgen (im folgenden auch als "Textmuster" bezeichnet).

Ein regulärer Ausdruck ist eine Folge von "normalen" Textzeichen und/oder Spezialzeichen. Spezialzeichen stellen Operatoren dar, mit deren Hilfe komplexe Textmuster beschrieben werden können.

a) Literale

Der reguläre Ausdruck

a

erkennt ein Zeichen 'a' im Eingabetext.

EBCDIC

stimmt mit allen Zeichenketten im Eingabetext überein, die Zeichenkette 'EBCDIC' enthalten.

(2)

b) Zeichenklassen

Operatoren, die jeweils eine Klasse von Zeichen beschreiben:

. Platzhalter für ein beliebiges Zeichen (außer Zeilenendezeichen) - x.y paßt auf allen Zeichenfolgen, die mit einem 'x' anfangen - z.B. 'x+y', 'x-y', 'x*y' usw.

[..] Platzhalter für genau ein Zeichen aus der angegebenen Menge:

In den Klammern stehen Zeichenfolgen wie z.B. [abc]. Dieser Ausdruck paßt auf 'a', 'b' oder 'c'.

[a-z] Bereiche von Zeichen – paßt auf alle Zeichen von 'a' bis 'z'.

Kombinationen [a-zAEIOU] sind möglich.

'^' am Klammeranfang – komplementäre Zeichenfolge z.B.

[^0-9] paßt somit auf jedes nicht-numerische Zeichen.

c) Wiederholungsoperatoren Sei a ein regulärer Ausdruck.

a* Vorkommen von a 0mal oder mehrmals,

z.B. E*BCDIC erkennt das Textmuster 'BCDIC', 'EBCDIC', 'EEBCDIC' usw.,

a? Vorkommen von a 0mal oder 1mal:

So erkennt der Ausdruck E?BCDIC die Zeichenketten 'BCDIC' oder 'EBCDIC',

a+ Vorkommen von a 1mal oder mehrmals - E+BCDIC -->

'EBCDIC', 'EEBCDIC' usw.

(3)

Wiederholungsoperatoren können sich auch auf Zeichenklassen- ausdrücke beziehen. Z. B. bei dem Ausdruck

[fe]?grep

besteht das erzeugte Muster aus den Zechenketten 'fgrep', 'egrep' und 'grep'.

d) Kontextoperatoren

^a Vorkommen des folgenden Ausdrucks nur am Zeilenanfang.

Z. B. der reguläre Ausdruck ^EBCDIC findet alle Zeilen mit der Kette 'EBCDIC' am Zeilenanfang.

a$ Vorkommen des vorhergehenden Ausdrucks nur am Zeilen- ende. Somit erkennt der Ausdruck EBCDIC$ alle Zeilen mit der Kette 'EBCDIC' am Zeilenende.

e) Komplexe Ausdrücke

Seien a und b reguläre Ausdrücke. Dann ist ab ebenfalls ein regulärer Ausdruck.

Die Verkettungsoperation hat keinen eigenen Operator ; sie wird durch die simple Aneinanderreihung von regulären Ausdrücken realisiert, z. B.

[a-zA-Z][a-zA-Z0-9]* beschreibt die Syntax von Bezeichnern.

a|b Verknüpfung von alternativen Ausdrücken:

EBCDIC|ASCII beschreibt alle Ketten 'EBCDIC' oder 'ASCII'.

(4)

Generell erfolgt die Abarbeitung von regulären Ausdrücken von links nach rechts. Die Reichweite der Operatoren ist auf die unmittelbare linke oder rechte Umgebung beschränkt. Die Operatoren werden in der Reihenfolge '[..]', Wiederholungs-operatoren '?', '+', '*', Verkettung und '|' abgearbeitet. Abweichungen von der Verarbeitungsreihenfolge können nur durch Klammerung erreicht werden.

(..) Gruppierung von (Teil-)Ausdrücken:

Die vorher aufgeführten Operatoren '?', '+', '*', '^', '$' und '|' können auf geklammerte Ausdrücke angewendet werden.

Beispiel:

(ab|cd+)?(ef)+ erkennt alle Zeichenketten der Form 'abef', 'efefef', 'cdef' usw., 'ab' bzw. 'cd' optional sind.

Wenn die Alternative 'cd' zutritt, so können beliebige Wiederho- lungen von 'd' gefunden werden ('cd', 'cdd', 'cddd' usw.) Die gefundene Zeichenkette muß unmittelbar gefolgt sein mindestens einem Vorkommen der Zeichenkette 'ef'.

f) Maskierung von Spezialzeichen

Die Spezialbedeutung der Operatoren kann durch das Zeichen '\' außer Kraft gesetzt werden:

^\. sucht alle Kommandos mit dem Punkt '.' am Anfang der Zeile.

Wenn das '\'-Zeichen vor einem Literal steht, so hat dies keinen weiteren Effekt. 'a' und '\a' sind also äquivalent.

Wenn das Zeichen '\' selbst gesucht werden soll, muß er verdoppelt werden. Ausnahme: innerhalb von '[..]'-Ausdrücken verliert '\' seine Bedeutung und steht für sich selbst.

(5)

2. ZEICHENKETTENERSETZUNG MIT LEX

Ein LEX Quellprogramm besteht aus den folgenden Teilen:

Definitionen %%

Regeln %%

Funktionen

Der Definitionsteil enthält Vereinbarungen, die vom Programmgenerator LEX für die Programmerzeugung benutzt werden. Außerdem können hier speziell gekennzeichnete Anweisungen der Wirtssprache stehen, die von LEX in das erzeugte Programm übernommen werden.

Die Regeln enthalten Benutzerangaben in Form einer Tabelle, in der die linke Spalte reguläre Ausdrücke und die rechte Spalte Aktionen enthält.

Aktionen sind Programmfragmente, die dann ausgeführt werden, wenn die zugehörigen Ausdrücke erkannt werden.

Im Funktionsteil werden in erster Linie Routinen der Wirtssprache untergebracht, die vom Regelteil aufgerufen werden.

Definitionen und Funktionen brauchen nicht zwingend angegeben zu werden. Der Regelteil sollte allerdings vorhanden sein, um eine sinnvolle Anwendung durchführen zu können.

Die drei Quellprogrammteile werden durch doppelte Prozentzeichen (%%) am Anfang der Zeile voneinander getrennt. Wenn das Programm lediglich aus dem Regelteil besteht, muß dennoch das einleitende '%%' gesetzt werden.

(6)

Beispiel 1:

Ein Programm, das die Zeichenkette 'integer' im Eingabedatenstrom sucht und durch den String 'INT' ersetzt:

%%

integer printf("INT");

Beispiel 2:

Beispiel, wie verschiedene Wörter von der britischen in die amerikanische Schreibweise umgesetzt werden:

%%

int i, k;

colour { printf ("color");

i++;

}

mechanise { printf ("mechanize"); k++; }

3. LEX – AUFRUF UND ERZEUGUNG DES ANALYSE- PROGRAMMS

Quelltext: Name.l oder Name.lex

Die Erzeugung eines LEX-Programms läuft in zwei Schritten ab.

Zunächst muß die LEX-Quelle in ein Programm der Wirtssprache (in C bei uns) umgewandelt werden.

Das umgewandelte Programm: lex.yy.c

Dann muß dieses Programm compiliert und gewöhnlich zusammen mit einer Bibliothek von LEX-Unterprogrammen geladen werden.

(7)

Das uebersetzte Programm: a.out oder Name.exe usw.

Das Analyseprogramm liest aus der Standardeingabe und schreibt seine Ergebnisse in die Standardausgabe.

Die Funktion des Analyseprogramms vom Beispiel 1:

Nehmen wir an, die Eingabe lautet:

'Ganze Zahlen werden durch "integer" Werte dargestellt.' Dann erzeugt das Analyseprogramm die Ausgabe:

'Ganze Zahlen werden durch "INT" Werte dargestellt.'

4. BENUTZERSPEZIFIZIERTE AKTIONEN

a) Benutzer kann verschiedene von ihm spezifizierte Aktionen des Analyseprogramms angeben. Z. B.:

Beispiel 3: Ignorieren des Eingabe:

[ \t\n] ; Leerzeichen, Tabulator- und Zeilenendzeichen im C-Programm werden ignoriert

b) Als Aktionen sind grundsätzlich alle Anweisungen der Wirts- sprache zugelassen, so daß hier nicht näher darauf eingegangen wird. Der Programmierer hat aber die Möglichkeit, zusätzlich zu seinen selbstdefinierenden Variablen eingebaute LEX-Variable in seinen Aktionen zu verwenden.

(8)

5. INTERNE LEX-VARIABLE

Lex supplies a number of variables and routines useful in the programming of actions:

- yytext a string variable, containing the matched text.

- yyleng the length of yytext, i.e. length(yytext). Note that the first and last character in yytext are yytext[0] and yytext[yyleng-1],

respectively.

- yylineno the current line number in the input file; useful, e.g., in giving diagnostics.

- yymore appends the next match to the current one (normally, the next match will overwrite the current one).

- yyless the counterpart of yymore; yyless(n) causes the current match to be restricted to the first n characters, and returns the remain- ing characters at the end of the match to be reread by the lexical analyzer. This supplies a crude form of "lookahead“.

- reject rejects the current match and executes whatever was "second choice" after the current rule, adjusting the match accordingly.

- return return(n), n an integer value, causes yylex to return with the indicated value.

- begin_ begin_(s) puts the lexical analyzer in start state s , where s is either 0 (default start state) or names a user-defined start state.

(9)

6. ZUSAMMENFASSUNG DER LEX-AUSDRÜCKE

Expression Matches Example --- c any non-operator character c a

\c character c literally \*

"s" string s literally "**"

. any character but newline a.*b

^ beginning of line ^abc

$ end of line abc$

[s] any character in s [abc]

[^s] any character not in s [^abc]

r* zero or more r's a*

r+ one or more r's a+

r? zero or one r a?

r{m,n} m to n occurrences of r a{1,5}

r1r2 r1 then r2 ab r1|r2 r1 or r2 a|b (r) r (a|b) r1/r2 r1 when followed by r2 abc/123 ---

(10)

7. EINFACHE LEX-PROGRAMM BEISPIELE

int num_lines = 0, num_chars = 0;

%%

\n ++num_lines; ++num_chars;

. ++num_chars;

%%

main() {

yylex();

printf( "# of lines = %d, # of chars = %d\n", num_lines, num_chars );

}

This scanner counts the number of characters and the number of lines in its input (it produces no output other than the final report on the counts).

(11)

%{

/* need this for the call to atof() below */

#include <math.h>

%}

DIGIT [0-9]

ID [a-z][a-z0-9]*

%%

{DIGIT}+ { printf ("An integer: %s(%d)\n", yytext, atoi( yytext ) );

}

{DIGIT}+"."{DIGIT}*

{ printf ( "A float: %s (%g)\n", yytext, atof( yytext ) );

}

if|then|begin|end|procedure|function

{ printf ( "A keyword: %s\n", yytext );

}

{ID} printf ( "An identifier: %s\n", yytext );

"+"|"-"|"*"|"/"

printf ( "An operator: %s\n", yytext );

"{"[^}\n]*"}" /* eat up one-line comments */

[ \t\n]+ /* eat up whitespace */

. printf ( "Unrecognized character: %s\n", yytext );

%%

main( argc, argv )

int argc; char **argv;

{

++argv, --argc; /* skip over program name */

if ( argc > 0 ) yyin = fopen( argv[0], "r" );

else yyin = stdin;

yylex();

}

This is the beginnings of a simple scanner for a language like Pascal. It identifies different types of TOKENS and reports on what it has seen.

(12)

/* Definitionen */

%{

int bu = 0, zi = 0, so = 0;

}*

Zi [0..9]

Bu [a-zA-Z]

So [^0-9a-zA-Z\t\n]

%%

/* Regeln */

\n ;

{Bu} bu++;

{Zi} zi++;

{So} so++;

%%

/* Benutzer-Funktion */

yywrap();

{

printf ("Buchstaben: %d\n", bu);

printf ("Ziffern: %d\n", zi);

printf ("Sonstige Zeichen: %d\n", so);

return (1);

}

Referenzen

ÄHNLICHE DOKUMENTE

ten ohne Weiteres in die technische Vorbereitungsciasse ein. Unter derselben Bedingung werden Secundaner des Rigaschen Realgymnasiums ohne Prüfung in die H

Mit $line =&lt;INPUT&gt;; schreiben Sie die erste Zeile der Datei in die Variable $line.. Mit close (INPUT); schlieÿen Sie

rungen und Empfehlungen Matthias Holenstein / Teilnehmende Berichterstattung aus den Gruppen Matthias Holenstein / Teilnehmende Die grenzüberschreitende Zusammenar-. beit aus

Frank Benkwitz Ministerium für Arbeit und Soziales und Integration Turmschanzenstraße 25 39114 Magdeburg..  Andrea Danowsky BDEW Bundesverband der Energie- und Wasserwirtschaft

Wegen der Unsicherheit der Schätzung der Reibungswider- stände W und dem mehr nach dem Gefühl gewählten Anschluß- druck, welche beide die Größe von F’ mit bestimmen, werden

Drei Wochen in den Osterferien oder sogar drei, sechs beziehungsweise zwölf Monate geht es nach Connec- ticut, South Carolina, Texas oder Washington D.C.. und

Für jeden regulären Ausdruck e kann (in linearer Zeit :-) ein -NFA konstruiert werden, der die Sprache [[ e ]]

• Ist der Startpunkt des Programms mit true annotiert, dann erfüllt jede Programmausführung, die den Programmpunkt v erreicht, die Zusicherung an v :-). • Zum Nachweis, dass