Come creare un interprete come TypeScript



Realizzazione di un interprete che converte un’istruzione del linguaggio TypeScript in  JavaScript  utilizzando Flex per il lexer e Bison per il parser.
di Antonio Lamorgese


In questo tutorial, realizzerai uninterpreteche converte un’istruzione del linguaggioTypeScriptin JavaScript utilizzandoFlexper il lexer eBisonper il parser. Il tuo traduttore di codice prenderà in input un file TypeScript e genererà un file JavaScript corrispondente. Esattamente quello che fa Typescript con il comando “tsc” che è l’abbreviazione diTypeScript Compilered è lo strumento principale per compilare il codice TypeScript in JavaScript.

1. Installazione degli strumenti necessari

Per la progettazione di questo interprete devi assicurati di avere installati Flex e Bison. Di seguito troverai le istruzioni da eseguire per installare questi due strumenti gratuiti sui più diffusi sistemi operativi:

Linux (Ubuntu/Debian)

sudo apt update
sudo apt install flex bison gcc

 MacOS  (con Homebrew)

brew install flex bison gcc

Windows (con MSYS2 e pacman)

MSYS2 è un ambiente che fornisce una shell Unix-like su Windows e permette di installare strumenti GNU, come Flex e Bison, utilizzando il  gestore di pacchetti pacman(simile a quello di Arch Linux).

Innanzitutto scarica e installaMSYS2dal sito ufficiale:https://www.msys2.org/.MSYS2(acronimo diMinimal System 2) è un ambiente di sviluppo open-source per Windows, che fornisce strumenti Unix-like per compilare, eseguire e gestire software in modo simile a un sistema dotato di  kernel Linux .Basato su Cygwin e MinGW-w64, MSYS2 offre una shell  Bash , in poche parole un terminale, e ungestore di pacchetti Pacman, simile a quello di Arch Linux.

READ Ottenere un dominio gratis scegliendo il miglior hosting gratuito

Dopo l’installazione, apriMSYS2 MSYS, e aggiorna il package manager con il comando:

pacman -Syu

Nota: Dopo questo comando, MSYS2 potrebbe chiudersi automaticamente. Riaprilo e riesegui pacman -Syu per completare l’aggiornamento.

Ora, devi installareFlex,BisoneGCCeseguendo questo semplice comando all’interno del terminale MSYS2:

pacman -S mingw-w64-x86_64-flex mingw-w64-x86_64-bison mingw-w64-x86_64-gcc

Assicurati che il percorsoC:\msys64\mingw64\binsia aggiunto alla variabile d’ambientePATHdi Windows, in modo da poter eseguire Flex e Bison da qualsiasi posizione all’interno del file system.


Leggi anche:Creare un linguaggio di programmazione con Python


2. Creazione del Lexer con Flex

Illexeranalizza il codice TypeScript e suddivide le parole chiave, gli identificatori e i simboli intoken. A questo punto crea un file di nome “lexer.l”, copia e incolla il seguente codice al suo interno:

File: lexer.l

%{

// Include il file header generato da Bison
#include "parser.tab.h"
#include <stdio.h>
%}

// Evita problemi con l'input di Flex
%option noyywrap

%%
Let       { return LET; }
[a-zA-Z_][a-zA-Z0-9_]*  { yylval.str = strdup(yytext); return IDENTIFIER; }
[0-9]+    { yylval.num = atoi(yytext); return NUMBER; }
=         { return ASSIGN; }
;         { return SEMICOLON; }
[ \t\n]   { /* Ignora spazi e nuove righe */ }
.         { printf("Carattere sconosciuto: %s\n", yytext); }

%%

3. Creazione del Parser con Bison

Ilparseranalizza la sequenza di token, restituiti dal lexer, e genera un file JavaScript corrispondente.

File: parser.y

%{

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void yyerror(const char *s);
int yylex();
extern int yylineno;
FILE *outputFile;

%}

%union {
    char *str;
    int num;
}

%token LET IDENTIFIER ASSIGN NUMBER SEMICOLON
%type <str> IDENTIFIER
%type <num> NUMBER

%%

program:
    statement { fprintf(outputFile, "var %s = %d;\n", $1, $3); }
    ;

statement:
    LET IDENTIFIER ASSIGN NUMBER SEMICOLON { $$ = $2; $$ = $4; }
    ;

%%

void yyerror(const char *s) {
    fprintf(stderr, "Errore: %s alla riga %d\n", s, yylineno);
}

4. Creazione del File di Esecuzione

File: main.c

#include <stdio.h>
#include <stdlib.h>
extern FILE *yyin;
extern FILE *outputFile;
int yyparse();

int main(int argc, char *argv[]) {
    if (argc < 3) {
        fprintf(stderr, "Usa: %s input.ts output.js\n", argv[0]);
        return 1;
    }

    yyin = fopen(argv[1], "r");
    if (!yyin) {
        perror("Errore nell'apertura del file sorgente");
        return 1;
    }

    outputFile = fopen(argv[2], "w");
    if (!outputFile) {
        perror("Errore nella creazione del file di output");
        fclose(yyin);
        return 1;
    }

    yyparse();
    fclose(yyin);
    fclose(outputFile);
    return 0;

}

5. Compilazione e Esecuzione

Ora puoi compilare il tuo interprete di codice inLinux, macOS e Windows. Prima però crea il file “input.ts” con questa istruzione:“Let x = 42;”e successivamente l’interprete creerà il file “output.js” con questa istruzione: “var x = 42;” cioè con l’istruzione Typescript convertita in Javascript.

READ Sviluppa la tua prima web app con Node JS

Linux/macOS

bison -d parser.y -o parser.tab.c
flex -o lexer.c lexer.l
gcc -o transpiler lexer.c parser.tab.c main.c -lfl
./transpiler input.ts output.js

Windows (MSYS2)

bison -d parser.y -o parser.tab.c
flex -o lexer.c lexer.l
gcc -o transpiler.exe lexer.c parser.tab.c main.c -lfl
./transpiler input.ts output.js

6. Conclusione

Hai creato un interprete di codice che converte da TypeScript in JavaScript utilizzando Flex e Bison. Ora, per migliorarlo, potresti implementare la gestione ditipi TypeScript. Rivedi pazientemente quanto è stato fatto nei file lexer.l e parser.y e aggiungi le istruzioni necessarie per integrare la conversione di altre istruzioni. 

Antonio Lamorgese

Amministratore di rete e sviluppatore. Dopo anni di esperienza nel settore, ho ideato un sistema di gestione dati MYSQL in PHP senza scrivere una sola riga di codice. Scopri di più....