Lex
Στην επιστήμη υπολογιστών το lex είναι ένα πρόγραμμα που παράγει λεκτικούς αναλυτές ("scanners" ή "lexers").
Το lex συχνά χρησιμοποιείται μαζί με τη γεννήτρια συντακτικών αναλυτών yacc.
Αρχικά το lex γράφτηκε από τον Mike Lesk και τον Eric Schmidt, και αποτελεί την κλασική γεννήτρια παραγωγής λεκτικών αναλυτών σε πολλά συστήματα Unix, και ένα εργαλείο που έχει τη συμπεριφορά του περιλαμβάνεται στο πρότυπο POSIX.
Το lex διαβάζει ένα ρεύμα εισόδου (input stream) που ορίζει το λεκτικό αναλυτή και παράγει πηγαίο κώδικα που υλοποιεί το λεκτικό αναλυτή στη γλώσσα προγραμματισμού C.
Αν και παραδοσιακά αποτέλεσε κλειστό λογισμικό, είναι διαθέσιμες εκδόσεις ανοιχτού κώδικα του lex που βασίζονται στον αρχικό κώδικα της AT&T, σαν μέρος συστημάτων όπως το OpenSolaris και το Plan 9 from Bell Labs.
Μια άλλη δημοφιλής έκδοση ανοιχτού κώδικα του lex είναι το flex, ο "γρήγορος λεκτικός αναλυτής" ("fast lexical analyzer").
Δομή ενός αρχείου lex
Η δομή ενός αρχείου lex έχει σχεδιαστεί ώστε να μοιάζει με αυτήν ενός αρχείου yacc - τα αρχεία χωρίζονται σε τρεις ενότητες που διακρίνονται μεταξύ τους από γραμμές που περιέχουν μόνο δύο σύμβολα "τοις εκατό", όπως το εξής:
Ενότητα των ορισμών (Definition section) %% Ενότητα των κανόνων (Rules section) %% Ενότητα κώδικα C (C code section)
Παράδειγμα ενός αρχείου lex
Ακολουθεί ένα παράδειγμα ενός αρχείου lex για την έκδοση flex του lex.
Αναγνωρίζει συμβολοσειρές από (ακέραιους) αριθμούς στην είσοδο και απλά τους τυπώνει.
/*** Ενότητα των ορισμών ***/ %{ /* Κώδικας C που θα αντιγραφεί ως έχει */ #include <stdio.h>
%} /* Αυτό λέει στο flex να διαβάσει μόνο ένα αρχείο εισόδου */ %option noyywrap %% /*** Ενότητα των κανόνων ***/ /* Το [0-9]+ ταιριάζει με μια συμβολοσειρά ενός η περισσότερων ψηφίων */ [0-9]+ { /* Το yytext είναι μια συμβολοσειρά που περιέχει το ταιριασμένο κείμενο.
*/ printf("Saw an integer: %s\\n", yytext); } . { /* Αγνοεί όλους τους άλλους χαρακτήρες.
*/ } %% /*** Ενότητα κώδικα C ***/ int main(void) { /* Καλεί το λεκτικό αναλυτή και στη συνέχεια τερματίζει.
*/ yylex(); return 0; }
Αν αυτή η είσοδος δοθεί στο flex, θα μετατραπεί σε ένα αρχείο C, το lex.yy.c.
Αυτό μπορεί να μεταγλωττιστεί σε ένα εκτελέσιμο το οποίο ταιριάζει και εμφανίζει συμβολοσειρές ακεραίων.
Για παράδειγμα, για είσοδο:
abc123z.!&*2ghj6
το πρόγραμμα θα τυπώσει:
Saw an integer: 123 Saw an integer: 2 Saw an integer: 6
Χρήση του lex με άλλα εργαλεία προγραμματισμού
Το lex και οι γεννήτριες συντακτικών αναλυτών, όπως το Yacc ή το Bison, συχνά χρησιμοποιούνται μαζί.
Οι γεννήτριες συντακτικών αναλυτών χρησιμοποιούν μια τυπική γραμματική για να αναλύσουν συντακτικά ένα ρεύμα εισόδου, κάτι που το lex δε μπορεί να κάνει χρησιμοποιώντας απλές κανονικές εκφράσεις (το lex περιορίζεται σε απλά αυτόματα πεπερασμένων καταστάσεων).
Όμως οι γεννήτριες συντακτικών αναλυτών δε μπορούν να διαβάσουν από ένα απλό ρεύμα εισόδου – χρειάζονται μια σειρά από λεκτικές μονάδες (tokens).
Το lex συχνά χρησιμοποιείται για να παρέχει αυτές τις λεκτικές μονάδες στη γεννήτρια συντακτικών αναλυτών.
Το make είναι ένα εργαλείο που μπορεί να χρησιμοποιηθεί για να συντηρεί προγράμματα που χρησιμοποιούν το lex.
Το make θεωρεί ότι ένα αρχείο με την κατάληξη .l είναι αρχείο πηγαίου κώδικα lex.
Η εσωτερική μακροεντολή του make LFLAGS μπορεί να χρησιμοποιηθεί για να ορίσει επιλογές του lex που θα κληθούν αυτόματα από το make.
