skip to main content

kiesler.at

Lexikalische Analyse mit Lex
updated by rck, 2004-08-27

In Unix finden sich viele Spezialisten. cat gibt dateien aus, cut zerschneidet sie spaltenweise, paste fügt sie wieder zusammen... und lex macht aus einer Text-Datei Tokens.
1 | 2 | 3 | 4 | 5 | 6

Word Count

Ich möchte an dieser Stelle ein kleines flex Programm vorstellen, welches ich für dieses Tutorial entwickelt habe. Es hört auf den schlichten Namen wc, die Abkürzung für Word Count, und gehört in einer mächtigeren Version ebenfalls zu jedem Unix dazu.

Nachdem es sehr anschaulich das bisher erklärte zusammenfasst, habe ich mir erlaubt, es nachzuprogrammieren. Wordcount liefert in der vorliegenden Version die Anzahl an Wörtern und Zeilen einer Eingabedatei

wc.lex

1 /*              Word Count with Lex.
2 
3                 part of a lex-tutorial on
4                 http://www.kiesler.at/
5 */
6 
7 
8                 int words=0;
9                 int lines=0;
10 
11 
12 WORD            [a-zA-Z0-9_]+
13 
14 PUNCTUATION     [\.\ ?\;\,\!\-\&]+
15 WHITESPACE      [ \t]+
16 IGNORE          {PUNCTUATION}|{WHITESPACE}
17 
18 NEWLINE         [\n]+
19 
20 
21 %%
22 
23 
24 {WORD}          words++;
25 {IGNORE}        /* */
26 {NEWLINE}       lines++;
27 
28 
29 %%
30 
31 
32                 main(int argc, char **argv) {
33                         yyin=argc>1 ? fopen(argv[1], "r") : stdin;
34                         yylex();
35                         printf("%d word(s), %d line(s).\n",
36                                 words, lines);
37                         exit(0);
38                 }

makefile zu wc.lex

1 wc: wc.lex
2         flex -owc.c wc.lex
3         gcc -o wc wc.c -lfl

Beispiel

$ wc text
5 word(s), 1 line(s).
$

Funktionsweise im Schnelldurchlauf

Lex-Datei

8-9 nachdem wir Wort- und Zeilenanzahl wissen möchten, müssen wir sie zählen. Dafür legen wir hier die Variablen an

12-18 hier definieren wir Muster. \t und \n stehen, wie von C gewohnt, für Tabulator, respektive \n

16 Das Pipe-Symbol | steht für eine Oderverknüpfung. IGNORE trifft also auf Zeichen aus PUNCTUATION oder WHITESPACE zu

21 Das erste %% trennt den Definitionsteil von den Regeln, das zweite, auf Zeile 29 den Regelteil von den Benutzerroutinen

24-26 hier wird festgelegt, was beim Eintreten der Symbole passieren soll. Sollte also ein Wort gefunden werden, wird die Wortanzahl erhöht, und so weiter.

32-38 Unser Hauptprogramm. Nimmt die Eingaben entweder vom angegebenen Kommandozeilenparameter entgegen (Aufruf zB wc /etc/passwd) oder von der Standard-Eingabe, wenn kein Parameter angegeben wurde (Aufruf zB wc < /etc/passwd). yylex() startet den lexxer, im Anschluß geben wir noch das Ergebnis aus und beenden mit exit-code 0 (alles ok)


makefile

1 Wenn sich wc.lex ändert, muß wc neu kompiliert werden.

2 Wir wünschen uns, dass unser Flex-Programm in wc.c umgewandelt wird.

3 Wenn Flex erfolgreich war, kompilieren wir es mit dem C-Compiler gcc, verlinken es mit der Flex-Bibliothek fl (-lfl) und erhalten die Ausführbare Datei wc (-o wc).

1 | 2 | 3 | 4 | 5 | 6



RSSComments - Make a comment
The comments are owned by the poster. We are not responsible for its content.
RSSAll Articles
2008, 2007, 2006, 2005, 2004