{"id":22124211,"url":"https://github.com/federicoponzi/sapy","last_synced_at":"2025-03-24T07:42:43.996Z","repository":{"id":14533709,"uuid":"17248408","full_name":"FedericoPonzi/Sapy","owner":"FedericoPonzi","description":"Sapy is a programming language inspired by Basic for my Advanced Programming University course 2012/2013.","archived":false,"fork":false,"pushed_at":"2016-07-27T08:57:15.000Z","size":146,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-29T13:12:09.480Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/FedericoPonzi.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-02-27T12:43:49.000Z","updated_at":"2022-04-27T21:23:12.000Z","dependencies_parsed_at":"2022-09-22T09:01:07.432Z","dependency_job_id":null,"html_url":"https://github.com/FedericoPonzi/Sapy","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FedericoPonzi%2FSapy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FedericoPonzi%2FSapy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FedericoPonzi%2FSapy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FedericoPonzi%2FSapy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/FedericoPonzi","download_url":"https://codeload.github.com/FedericoPonzi/Sapy/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245230988,"owners_count":20581600,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-01T15:46:55.374Z","updated_at":"2025-03-24T07:42:43.964Z","avatar_url":"https://github.com/FedericoPonzi.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"Sapy\n====\n\nSapy è il nome del progetto per il corso di metodologie di programmazione dell' anno 2012/2013. Realizzato in java ed inspirato al linguaggio Basic.\n\nRelazione\n==========\nIl progetto Sapy è strutturato come un compilatore. Il progetto dovrà essere fondato su 4 diversi strati: a quello iniziale, troviamo il Lexer (Lexical Analyzer). Il suo compito sarà quello di prendere in input del plain text e controllarne la grammatica ovvero dovrà controllare se l’utente ha inserito termini presenti nell’ alfabeto di Sapy.\nDopo di che, dovrà trasformare ogni termine base in un oggetto di tipo Token: un Token è una stringa formata da uno o più caratteri che presi insieme ha un significato ben preciso. Il processo che si fà per creare questi Token viene chiamato tokenizzazione.\n\nTramite l’aggiunta del token “Funzione” tutto ciò che non viene riconosciuto come parte del linguaggio verrà salvato come questo tipo.\n\nTokenizzazione\n=============\nLa tokenizzazione può essere di tue tipi: \n“Sofisticata”, tramite l’utilizzo delle regex (regular expressions); \n“Semplice”, ovvero utilizzando dei delimitatori (nel caso di Sapy, gli spazi).\nNel mio progetto, ho scelto il primo tipo di tokenizzazione.\nIl Lexer di Sapy\nIl lexer di Sapy prevede di base:\nUn metodo per tokenizzare,\nUn metodo per restituite la lista di oggetti tokens,\nUn metodo richiamato dal main per stampare a video i nomi dei tokens.\nInoltre come attributi:\nUna stringa per contenere le istruzioni prese come input;\nUn (Array)List contenente la lista di tokens.\n\ntokenizzare()\nDopo aver costruite un oggetto Lexer, che prende in input una lista di istruzioni sottoforma di stringa, il metodo tokenizzare si occupa appunto di dividere la stringa in lessemi.\nScorrendo carattere per carattere, tokenizzare prende in considerazione diversi casi:\nE’ uno spazio: risparmiando i controlli successivi, se stà considerando uno spazio lo salta.\nComincia con $: Se comincia col simbolo del dollaro, tutto ciò che lo segue fino allo spazio sarà il nome di una variabile. Per definizione di Sapy, le variabili possono contere solamente caratteri alfanumerici e simbolo di underscore: è effettivamente questo utilizzato come input della regex, che cerca il primo carattere diverso da questo insieme.\nComincia con doppio apice: Se comincia con doppio apice, allora stiamo considerando una stringa. Il lexer la prenderà finchè non troverà un’altro doppio apice seguito da un fine riga (duepunti, o backslash n).\nE’ un intero: Se è un intero, bisogna salvarne il valore in un token.\nE’ un booleano: Come sopra.\nE’ un simbolo: Nel caso sia un simbolo vede se è \u003c o \u003e: in questo caso controlla il carattere successivo (diverso da uno spazio) per vedere se è  \u003e o =.\nE’ una funzione conosciuta: Se è una funzione compresa fra quelle di base di Sapy, allora viene costruito l’oggetto Token apposito.\nE’ una funzione: L’ultimo caso, stiamo considerando qualcosa di non presente in Sapy e la cataloghiamo quindi come funzione.\n\ngetListaTokens()\nQuesto metodo è l’interfaccia con lo strato successivo, il parser: questo si occupa di restituire la lista dei tokens generata dal metodo tokenizzare.\ngetListaTokensStringa()\nMetodo utilizzato esclusivamente dal main: serve a stampare la lista dei tokens presi come input da file dal Lexer quando viene eseguito direttamente.\n\n\nIl Parser\n=================\nNel secondo strato troviamo il parser: questo deve controllare se la sintassi seguita dalle istruzioni è giusta.\nLa sintassi è la branca della linguistica che studia i diversi modi in cui le parole si uniscono tra loro per formare una proposizione ed i vari modi in cui le proposizioni si collegano per formare un periodo (Wikipedia).\nIl parser quindi dovrà vedere se ogni elemento è stato inserito nel giusto ordine e in una posizione possibile.\nPrenderà in input quindi una (Array)List di Tokens dallo strato superiore, il Lexer, e farà l’analisi sintattica aggiungendo all’ campo statico ListaIstruzioni dell’oggetto Programma Eseguibile (creato dalla classe principale del programma, Sapy.java) i corretti oggetti Istruzione.\n\nA tempo di costruzione, ogni oggetto Istruzione controlla se l’input fornito dal parser sottoforma di una ArrayList di Tokens è esatto: se si si salva i dati di cui ha bisogno per una successiva esecuzione.\n\nCasi particolari sono quelli in cui abbiamo un’istruzione FOR o una IF: per questi due, visto che accettano una lista di istruzioni come input, ho deciso di fare una mutua ricorsione.\nIl metodo parse() parsa le istruzioni una alla volta, e ritornando un’oggetto istruzione per volta. Nel caso in cui incontra un IF, chiama un metodo parseIF creato apposta per parsare gli IF che poi richiamerà il parse() ricorsivamente. \nIn questo modo, è possibile incapsulare IF dentro a IF. Un lavoro simile è svolto per il metodo parseFOR().\n\nPer quanto riguarda il parsing delle operazioni matematiche, ho ovviamente scelto il parser ricorsivo discendente che viene richiamato dalle istruzioni per risolvere operazioni matematiche.\n\nInterprete\n============\nAl terzo livello troviamo l’ interprete: questo è in pratica una consolle che permette di eseguire istruzioni Sapy una alla volta.\nLa sua realizzazione è basata su quella del file principale, sapy.java, ed è un ciclo while infinito (che terminerà con l’input di un’istruzione END) che prende in input una istruzione per volta.\nRichimerà il lexer, poi il parser, eseguirà le istruzioni e le rimuoverà da ProgrammaEseguibile (lasciando invariate le variabili).\n\nSapy\n===========\nIl quarto ed ultimo livello è quello del compilatore: il file Sapy è il file principale del progetto. Prende in input la path di un file di testo contenente istruzioni Sapy e le esegue una per uno chiamando prima il Lexer, poi il Parser, ed infine eseguendo gli oggetti istruzioni da ProgrammaEseguibile.\nE’ fornito anche di un campo ProgramCounter che funge da puntatore per l’utilizzo dell’istruzione GOTO.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffedericoponzi%2Fsapy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffedericoponzi%2Fsapy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffedericoponzi%2Fsapy/lists"}