Il seguente documento contiene la specifica del linguaggio MyFun implementato all'interno del progetto.
- Project SDK: 17 (version 17.0.2)
- Project Language Level: SDK Default
- Maven: Non utilizzato
GENERAZIONE PARSER,LEXER E JAR: Si consiglia di utilizzare le configurazioni fornite in IntelliJ.
ISTRUZIONI PER ESEGUIRE I FILE DI TEST: Si consiglia di utilizzare le configurazioni create in IntelliJ (si possono modificare i path per aggiungere file esterni), inoltre è stato aggiunto il file Test5_Debug.txt vuoto per l'eventuale aggiunta di codice da testare.
NB: Il file Test2_Valid2.txt (equivalente di Valid2.txt) è stato modificato rispetto alla versione originale (variabile continue (parola chiave del linguaggio C) modificata in flagContinue).
Per l'analisi lessicale si è utilizzato JFLEX, per la generazione automatica del LEXER, le specifiche necessarie sono state inserite all'interno del file fun.flex.
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 |
TRUE | true |
FALSE | false |
INTEGER_CONST | [0-9]+ |
REAL_CONST | [0-9]+.[0-9]+(e-?[0-9]+)? |
STRING_CONST | qualsiasi stringa tra " oppure ' |
SEMI | ; |
COMMA | , |
RETURN | return |
OUTPAR | @ |
VAR | var |
OUT | out |
LOOP | loop |
Per l'analisi sintattica si è utilizzato il CUP, per la generazione automatica di un PARSER di tipo Top Down, le specifiche sono state inserite all'interno del file fun.cup. E' stato inoltre utilizzato il pattern VISITOR, presente nel file SyntaxVisitor.java per la generazione del Syntax tree. L'output dell'analisi sintattica (Syntax tree) è disponibile nella directory syntax_tree.
Sono state utilizzate le seguenti regole di precedenza dalla più alta alla più bassa.
Operatore | Precendenza |
---|---|
uminus | sinistra |
lpar ( , rpar ) | sinistra |
^ (pow) | destra |
* / div / divint | sinistra |
+ - | sinistra |
& (Str_Concat) | sinistra |
= != <> < <= > >= | nessuna ass |
not | destra |
and | sinistra |
or | sinistra |
Un programma del linguaggio MyFun si compone di:
Program ::= VarDeclList FunList Main
Il Main è composto da:
Main ::= MAIN VarDeclList StatList END MAIN SEMI
Una dichiarazione di una variabile è composta da:
VarDecl ::= Type IdListInit SEMI
| VAR IdListInitObbl SEMI
Una lista di dichiarazioni di variabili può essere vuota oppure composta da:
VarDeclList ::= ε
| VardDecl VarDeclList
Un tipo è cosi definito:
Type ::= INTEGER | BOOL | REAL | STRING
Una lista di ID e composta da una ID oppure da:
IdList ::= ID
| IdList COMMA ID
Una lista di inizializazzioni di identificatori (ID) e composta da un ID oppure da:
IdListInit ::= ID
| IdListInit COMMA ID
| ID ASSIGN Expr
| IdListInit COMMA ID ASSIGN Expr
Una lista di inizializzazioni obbligatorie (In MyFun --> VAR) è definita come:
IdListInitObbl ::= ID ASSIGN Const
| IdListInitObbl COMMA ID ASSIGN Const
Una costante è definita come segue:
Const ::= INTEGER_CONST | REAL_CONST | BOOL_CONST | STRING_CONST
Una 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 SEMI
Una lista di funzioni puo essere vuota o composta da:
FunList ::= ε
| Fun FunList
Una chiamata di funzione è composta da:
CallFun ::= ID LPAR ExprList RPAR
| ID LPAR RPAR
Un parametro è composto da:
ParDecl ::= Type ID
| OUT Type ID
Una lista di parametri puo essere vuota o composta da:
ParamDeclList ::= ε
| NonEmptyParamDeclList
Una lista non vuota di paramentri è composta da:
NonEmptyParamDeclList ::= ParDecl
| NonEmptyParamDeclList COMMA ParDecl
Uno statement è definito in uno dei seguenti modi:
Stat ::= IfStat SEMI
| WhileStat SEMI
| ReadStat SEMI
| WriteStat SEMI
| AssignStat SEMI
| CallFun SEMI
| ReturnStat SEMI
Una lista di statement puo essere vuota o composta da:
StatList ::= ε
| StatList Stat
Uno statement di assegnamento è composto da:
AssignStat ::= ID ASSIGN Expr
Uno statement di lettura è composto da:
ReadStat ::= READ IdList Expr
| READ IdList
Uno statement di scrittura è definito in uno dei seguenti modi:
WriteStat ::= WRITE Expr
| WRITELN Expr
| WRITET Expr
| WRITEB Expr
Uno statement if è composto da:
IfStat ::= IF Expr THEN VarDeclList StatList Else END IF
Lo statement Else è composto da la parola vuota oppure:
Else ::= ε
| ELSE VarDeclList StatList
Lo statement while è composta da:
WhileStat ::= WHILE Expr LOOP VarDeclList StatList END LOOP
Una 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 RPAR
Una lista di espressioni è composta da un espressione oppure:
ExprList ::= Expr
| Expr COMMA ExprList
| OUTPAR ID
| OUTPAR ID COMMA ExprList
Per l'analisi sematica è stato utilizzato il pattern VISITOR implementato nel file SemanticVisitor.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) (Operatori Unari)
op1 | operando | risultato |
---|---|---|
MINUS | integer | integer |
MINUS | real | real |
NOT | bool | bool |
Operatori binari
Tabella per optype2(op, type1, type2) (Operatori Binari)
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 |
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 utilizzato il pattern VISITOR implementato nel file CVisitor.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 *IntConcat(char *string, int toConcat)
char *DoubleConcat(char *string, float toConcat)
char *BoolConcat(char *string, int toConcat)
char *StringConcat(char *string, char *toConcat)