Il seguente documento contiene la specifica del linguaggio MyFun implementato all'interno del progetto.
- Project SDK: 17
- Project Language Level: SDK Default
- Maven: Utilizzato (pom.xml versione MacOS su Gitlab)
GENERAZIONE PARSER,LEXER E JAR: Si consiglia di utilizzare le configurazioni fornite in IntelliJ.
ISTRUZIONI ESECUZIONE: Si consiglia di utilizzare per il lancio del progetto le configurazioni create in IntelliJ (eventualmente modificando i path per aggiungere file esterni), inoltre è stato fornito il test file 8, vuoto per l'eventuale aggiunta di codice di test.
ATTENZIONE: Il file valid2.txt contiene alcuni errori sintattici che sono stati corretti, rispetto alla versione originiale (' all'interno di stringhe, e l'utilzzo della variabile continue, keyword di C).
Indice dei contenuti:
- Analisi Lessicale
- Analisi Sintattica
- Analisi Semantica e Generazione del Codice Intermedio
- Bug Noti e Scelte Progettuali Fatte
Per l'analisi lessicale si è utilizzato JFLEX, per la generazione automatica del LEXER, le specifiche necessarie sono state inserite all'interno del file MyFun.flex.
Sono stati generati i seguenti errori:
- Stringa costante non completata: nel caso in cui il programma in input presenti una stringa costante aperta ma non chiusa (es. "questa è una stringa non chiusa ).
- Commento non chiuso: nel caso in cui il programma in input presenti un commento non chiuso (es. /* questo è un commento non chiuso )
N.B.: in entrambi i casi si raggiunge l'EOF mentre si sta riconoscendo un commento o una stringa. Se si usano gli stati jflex (ad es. COMMENT e STRING), questo si traduce nell'incontrare un EOF mentre si è nel corrispondente stato.
All'interno del linguaggio i commenti iniziano con # oppure con //. Inoltre un blocco di commenti è delimitato da #* e #.
Nel linguaggio sono implementate le seguenti parole chiave:
| Identificativo | Valore |
|---|---|
| MAIN | main |
| ID | /[$_A-Za-z][$_a-za-z0-9]*/ |
| INTEGER | integer |
| STRING | string |
| REAL | real |
| BOOL | bool |
| LPAR | ( |
| RPAR | ) |
| COLON | : |
| FUN | fun |
| END | end |
| IF | if |
| THEN | then |
| ELSE | else |
| WHILE | while |
| LOOP | loop |
| READ | % |
| WRITE | ? |
| WRITELN | ?. |
| WRITEB | ?, |
| WRITET | ?: |
| ASSIGN | := |
| PLUS | + |
| MINUS | - |
| TIMES | * |
| DIVINT | div |
| DIV | / |
| POW | ^ |
| STR_CONCAT | & |
| EQ | = |
| NE | <> or != |
| LT | < |
| LE | <= |
| GT | > |
| GE | >= |
| AND | and |
| OR | or |
| NOT | not |
| NULL | null |
| TRUE | true |
| FALSE | false |
| INTEGER_CONST | (([1-9][0-9]*)|(0)) |
| REAL_CONST | (([1-9][0-9]*)|(0)).(([0-9]*[1-9]+)|(0)) |
| STRING_CONST | any string between " or between ' |
| SEMI | ; |
| COMMA | , |
| RETURN | return |
| OUTPAR | @ |
| VAR | var |
| OUT | out |
| LOOP | loop |
Per l'analisi lessicale si è utilizzato il CUP, per la generaazione automatica di un PARSER di tipo Top Down, le specifiche necessarie sono state inserite all'interno del file MyFun.cup.
Sono state utilizzate le seguenti regole di precedenza dalla più alta alla più bassa. Eventuali altre ambiguità sono state risolte tramite l'uso dell'associativià sinistra (se non indicata nella tabella):
| Operatore | Precendenza |
|---|---|
| uminus | |
| ( ) | |
| ^ | destra |
| * / div / divint | |
| + - | |
| & | |
| = != <> < <= > >= | nessuna |
| not | destra |
| and | |
| or |
N.B.: Sono state codificate in javacup solo quelle necessarie all'eliminazione dei conflitti.
Un programma è composta da:
Program ::= VarDeclList FunList MainUn Main è composto da:
Main ::= MAIN VarDeclList StatList END MAIN SEMIUna dichiarazione di una variabile è composta da:
VarDecl ::= Type IdListInit SEMI
| VAR IdListInitObbl SEMIUna lista di dichiarazioni di variabili può essere vuota oppure composta da:
VarDeclList ::= ε
| VardDecl VarDeclListUn tipo è defito come segue:
Type ::= INTEGER | BOOL | REAL | STRINGUna lista semplice di ID e composta da una ID oppure da:
IdList ::= ID
| IdList COMMA IDUna lista di inizializazzioni di ID e composta da un ID oppure da:
IdListInit ::= ID
| IdListInit COMMA ID
| ID ASSIGN Expr
| IdListInit COMMA ID ASSIGN ExprUna lista di inizializzazioni obbligatorie è definita come:
IdListInitObbl ::= ID ASSIGN Const
| IdListInitObbl COMMA ID ASSIGN ConstUna costante è definita come segue:
Const ::= INTEGER_CONST | REAL_CONST | TRUE | FALSE | STRING_CONSTUna dichiarazione di funzione è composta da:
Fun := FUN ID LPAR ParamDeclList RPAR COLON Type VarDeclList StatList END FUN SEMI
| FUN ID LPAR ParamDeclList RPAR VarDeclList StatList END FUN SEMIUna lista di funzioni puo essere vuota o composta da:
FunList ::= ε
| Fun FunListUna chiamata di funzione è composta da:
CallFun ::= ID LPAR ExprList RPAR
| ID LPAR RPARUn parametro è composto da:
ParDecl ::= Type ID
| OUT Type IDUna lista di parametri puo essere vuota o composta da:
ParamDeclList ::= ε
| NonEmptyParamDeclListUna lista non vuota di paramentri è composta da:
NonEmptyParamDeclList ::= ParDecl
| NonEmptyParamDeclList COMMA ParDeclUno statement è definito in uno dei seguenti modi:
Stat ::= IfStat SEMI
| WhileStat SEMI
| ReadStat SEMI
| WriteStat SEMI
| AssignStat SEMI
| CallFun SEMI
| RETURN Expr SEMIUna lista di statement puo essere vuota o composta da:
StatList ::= ε
| StatList StatUno statement di assegnamento è composto da:
AssignStat ::= ID ASSIGN ExprUno statement di lettura è composto da:
ReadStat ::= READ IdList Expr
| READ IdListUno statement di scrittura è definito in uno dei seguenti modi:
WriteStat ::= WRITE Expr
| WRITELN Expr
| WRITET Expr
| WRITEB ExprUno statement if è composto da:
IfStat ::= IF Expr THEN VarDeclList StatList Else END IFLo statement Else è composto da la parola vuota oppure:
Else ::= ε
| ELSE VarDeclList StatListLo statement while è composta da:
WhileStat ::= WHILE Expr LOOP VarDeclList StatList END LOOPUna espressione è composta nel seguente modo:
Expr ::= TRUE
| FALSE
| INTEGER_CONST
| REAL_CONST
| STRING_CONST
| ID
| CallFun
| Expr PLUS Expr
| Expr MINUS Expr
| Expr TIMES Expr
| Expr DIV Expr
| Expr DIVINT Expr
| Expr AND Expr
| Expr POW Expr
| Expr STR_CONCAT Expr
| Expr OR Expr
| Expr GT Expr
| Expr GE Expr
| Expr LT Expr
| Expr LE Expr
| Expr EQ Expr
| Expr NE Expr
| MINUS Expr
| NOT Expr
| LPAR Expr RPARUna lista di espressioni è composta da un espressione oppure:
ExprList ::= Expr
| Expr COMMA ExprList
| OUTPAR ID
| OUTPAR ID COMMA ExprListPer l'analisi sematica è stato utilizzato il patter VISITOR implementato nel file Semantic_Visitor.java: per l'analisi semantica;
Di seguito, le regole di type checking utilizzate all'interno del visitor per l'analisi semantica.
Costanti
ID
Operatori unari
Tabella per optype1(op, t)
| op1 | operando | risultato |
|---|---|---|
| MINUS | integer | integer |
| MINUS | real | real |
| NOT | bool | bool |
Operatori binari
Tabella per optype2(op,
| op1 | operando | operando2 | risultato |
|---|---|---|---|
| PLUS, MINUS, TIMES, DIV | integer | integer | integer |
| PLUS, MINUS, TIMES, DIV | integer | real | real |
| PLUS, MINUS, TIMES, DIV | real | integer | real |
| PLUS, MINUS, TIMES, DIV | real | real | real |
| DIVINT | integer | integer | integer |
| DIVINT | real | integer | integer |
| STR_CONCAT | string | string | string |
| STR_CONCAT | string | integer | string |
| STR_CONCAT | string | real | string |
| STR_CONCAT | string | bool | string |
| AND | bool | bool | bool |
| OR | bool | bool | bool |
| GT, GE, LT, LE | integer | integer | bool |
| GT, GE, LT, LE | integer | real | bool |
| GT, GE, LT, LE | real | integer | bool |
| GT, GE, LT, LE | real | real | bool |
| EQ, NE | integer | integer | bool |
| EQ, NE | real | real | bool |
| EQ, NE | integer | real | bool |
| EQ, NE | real | integer | bool |
| EQ, NE | string | string | bool |
| EQ, NE | bool | bool | bool |
Lista di istruzioni
Assegnazione
Chiamata a funzione con o senza tipo di ritorno
Istruzione while
Istruzione if then else
Istruzione read
Istruzione write
Istruzione return
## Generazione del Codice Intermedio
Per la generazione del codice è stato utilizza il pattern VISITOR implementato nel file CodeGen_Visitor.java: per la generazione del codice intermedio (C).
-
Sono state introdotte le librerie stdio.h, stdlib.h, stdbool.h e string.h al fine di effettuare le operazioni standard di input/output, effettuare operazioni sulle stringhe (es. strcmp, strcpy) e poter gestire i tipi booleani.
-
Per la gestione della concatenazione delle stringhe e le conversione implicite richieste sono state create quattro funzioni all'interno del codice C:
char *concatInt(char *string, int toConcat)char *concatReal(char *string, float toConcat)char *concatBool(char *string, int toConcat)char *concatString(char *string, char *toConcat)
Nell'implementazione del progetto, con lo scopo di rendere il codice più pulito e mantenibile possibile si è scelto di non supportare alcuni casi estremamente particolari e di difficile riproduzione.
Casi particolari non supportati noti:
- Gestione di concatenazioni di stringha al seguito della dichiarazione di una variabile globale (Sia tramite IdInitNode che IdInitObblNode).