Initial commit. Grammar has some conflicts, no rules.
This commit is contained in:
commit
65b38e33c2
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
/Monicelli.tab.*
|
||||||
|
/Monicelli.output
|
||||||
|
/mcc
|
11
Makefile
Normal file
11
Makefile
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
compile:
|
||||||
|
bison --verbose -d Monicelli.y
|
||||||
|
flex Monicelli.ll
|
||||||
|
gcc -DYYDEBUG=1 Monicelli.tab.c lex.yy.c main.c -o mcc
|
||||||
|
rm Monicelli.tab.* lex.yy.c
|
||||||
|
|
||||||
|
graph:
|
||||||
|
bison --graph Monicelli.y
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f Monicelli.dot Monicelli.tab.* lex.yy.c Monicelli.output
|
166
Monicelli.ll
Normal file
166
Monicelli.ll
Normal file
|
@ -0,0 +1,166 @@
|
||||||
|
%{
|
||||||
|
#include "Type.h"
|
||||||
|
#include "Monicelli.tab.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
extern int lineNumber;
|
||||||
|
extern void yyerror(const char *);
|
||||||
|
%}
|
||||||
|
|
||||||
|
%option noyywrap
|
||||||
|
|
||||||
|
DIGIT [0-9]
|
||||||
|
HEXDIGIT [0-9a-zA-Z]
|
||||||
|
CHAR [a-zA-Z_]
|
||||||
|
|
||||||
|
%%
|
||||||
|
("\r\n"|"\n") {
|
||||||
|
lineNumber += 1;
|
||||||
|
return NEWLINE;
|
||||||
|
}
|
||||||
|
|
||||||
|
^"bituma"[^\n]* {
|
||||||
|
lineNumber += 1;
|
||||||
|
}
|
||||||
|
"Lei ha clacsonato" {
|
||||||
|
return MAIN;
|
||||||
|
}
|
||||||
|
"vaffanzum" {
|
||||||
|
return RETURN;
|
||||||
|
}
|
||||||
|
"Necchi" {
|
||||||
|
yylval.typeval = TYPENAME_INT;
|
||||||
|
return TYPENAME;
|
||||||
|
}
|
||||||
|
"Mascetti" {
|
||||||
|
yylval.typeval = TYPENAME_CHAR;
|
||||||
|
return TYPENAME;
|
||||||
|
}
|
||||||
|
"Perozzi" {
|
||||||
|
yylval.typeval = TYPENAME_FLOAT;
|
||||||
|
return TYPENAME;
|
||||||
|
}
|
||||||
|
"Melandri" {
|
||||||
|
yylval.typeval = TYPENAME_BOOL;
|
||||||
|
return TYPENAME;
|
||||||
|
}
|
||||||
|
"Sassaroli" {
|
||||||
|
yylval.typeval = TYPENAME_DOUBLE;
|
||||||
|
return TYPENAME;
|
||||||
|
}
|
||||||
|
"conte" {
|
||||||
|
return STAR;
|
||||||
|
}
|
||||||
|
"voglio il" {
|
||||||
|
return VARDECL;
|
||||||
|
}
|
||||||
|
"come fosse" {
|
||||||
|
return ASSIGN;
|
||||||
|
}
|
||||||
|
("il"|"lo"|"la"|"i"|"gli"|"le"|"un"|"una"|"dei") {
|
||||||
|
return ARTICLE;
|
||||||
|
}
|
||||||
|
"più" {
|
||||||
|
return OP_PLUS;
|
||||||
|
}
|
||||||
|
"meno" {
|
||||||
|
return OP_MINUS;
|
||||||
|
}
|
||||||
|
"per" {
|
||||||
|
return OP_TIMES;
|
||||||
|
}
|
||||||
|
"diviso" {
|
||||||
|
return OP_DIV;
|
||||||
|
}
|
||||||
|
"sinistra" {
|
||||||
|
return OP_SHL;
|
||||||
|
}
|
||||||
|
"destra" {
|
||||||
|
return OP_SHR;
|
||||||
|
}
|
||||||
|
"minore di" {
|
||||||
|
return OP_LT;
|
||||||
|
}
|
||||||
|
"maggiore di" {
|
||||||
|
return OP_GT;
|
||||||
|
}
|
||||||
|
"minore o uguale a" {
|
||||||
|
return OP_LTE;
|
||||||
|
}
|
||||||
|
"maggiore o uguale a" {
|
||||||
|
return OP_GTE;
|
||||||
|
}
|
||||||
|
"a posterdati" {
|
||||||
|
return PRINT;
|
||||||
|
}
|
||||||
|
"mi porga" {
|
||||||
|
return INPUT;
|
||||||
|
}
|
||||||
|
"ho visto la" {
|
||||||
|
return ASSERT_BEGIN;
|
||||||
|
}
|
||||||
|
"!" {
|
||||||
|
return ASSERT_END;
|
||||||
|
}
|
||||||
|
"stuzzica" {
|
||||||
|
return LOOP_BEGIN;
|
||||||
|
}
|
||||||
|
"e brematura anche, se" {
|
||||||
|
return LOOP_CONDITION;
|
||||||
|
}
|
||||||
|
"che cos'è" {
|
||||||
|
return BRANCH_CONDITION;
|
||||||
|
}
|
||||||
|
"?" {
|
||||||
|
return BRANCH_BEGIN;
|
||||||
|
}
|
||||||
|
"tarapia tapioco" {
|
||||||
|
return BRANCH_ELSE;
|
||||||
|
}
|
||||||
|
"e velocità di esecuzione" {
|
||||||
|
return BRANCH_END;
|
||||||
|
}
|
||||||
|
":" {
|
||||||
|
return COLON;
|
||||||
|
}
|
||||||
|
"blinda la supercazzola" {
|
||||||
|
return FUNDECL;
|
||||||
|
}
|
||||||
|
"con" {
|
||||||
|
return PARAMS;
|
||||||
|
}
|
||||||
|
"," {
|
||||||
|
return COMMA;
|
||||||
|
}
|
||||||
|
"{" {
|
||||||
|
return LCURL;
|
||||||
|
}
|
||||||
|
"}" {
|
||||||
|
return RCURL;
|
||||||
|
}
|
||||||
|
"brematurata la supercazzola" {
|
||||||
|
return FUNCALL;
|
||||||
|
}
|
||||||
|
"avvertite don ulrico" {
|
||||||
|
return ABORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
[ \t\f\v] {}
|
||||||
|
|
||||||
|
{CHAR}({DIGIT}|{CHAR})* {
|
||||||
|
yylval.strval = strdup(yytext);
|
||||||
|
return ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
{DIGIT}+ {
|
||||||
|
yylval.intval = strtol(yytext, NULL, 10);
|
||||||
|
return NUMBER;
|
||||||
|
}
|
||||||
|
|
||||||
|
. {
|
||||||
|
yyerror("Unexpected token\n");
|
||||||
|
return -1;
|
||||||
|
};
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
149
Monicelli.y
Normal file
149
Monicelli.y
Normal file
|
@ -0,0 +1,149 @@
|
||||||
|
%{
|
||||||
|
#include "Type.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
extern void emit(const char *, ...);
|
||||||
|
%}
|
||||||
|
|
||||||
|
%union {
|
||||||
|
Type typeval;
|
||||||
|
int intval;
|
||||||
|
double floatval;
|
||||||
|
char *strval;
|
||||||
|
}
|
||||||
|
|
||||||
|
%token MAIN
|
||||||
|
%token RETURN
|
||||||
|
%token NEWLINE
|
||||||
|
%token ARTICLE TYPENAME STAR
|
||||||
|
%token VARDECL ASSIGN
|
||||||
|
%token PRINT INPUT
|
||||||
|
%token ASSERT_BEGIN ASSERT_END
|
||||||
|
%token LOOP_BEGIN LOOP_CONDITION
|
||||||
|
%token BRANCH_CONDITION BRANCH_BEGIN BRANCH_ELSE BRANCH_END
|
||||||
|
%token COLON COMMA LCURL RCURL
|
||||||
|
%token FUNDECL PARAMS FUNCALL
|
||||||
|
%token ABORT
|
||||||
|
%token ID NUMBER FLOAT
|
||||||
|
|
||||||
|
%left OP_LT OP_GT OP_LTE OP_GTE
|
||||||
|
%left OP_PLUS OP_MINUS
|
||||||
|
%left OP_TIMES OP_DIV
|
||||||
|
%left OP_SHL OP_SHR
|
||||||
|
|
||||||
|
%nonassoc LOWER_THAN_ELSE
|
||||||
|
%nonassoc BRANCH_ELSE
|
||||||
|
|
||||||
|
%start program
|
||||||
|
|
||||||
|
%type<strval> expression;
|
||||||
|
%type<intval> NUMBER;
|
||||||
|
%type<floatval> FLOAT;
|
||||||
|
%type<strval> ID;
|
||||||
|
%type<typeval> TYPENAME;
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
program:
|
||||||
|
fun_decls main fun_decls
|
||||||
|
;
|
||||||
|
fun_decls:
|
||||||
|
/* epsilon */ | fun_decls fun_decl
|
||||||
|
;
|
||||||
|
fun_decl:
|
||||||
|
FUNDECL ID args LCURL statements RCURL
|
||||||
|
;
|
||||||
|
args:
|
||||||
|
/* epsilon */ | PARAMS arglist
|
||||||
|
;
|
||||||
|
arglist:
|
||||||
|
ID | ID COMMA arglist
|
||||||
|
;
|
||||||
|
main:
|
||||||
|
MAIN NEWLINE statements
|
||||||
|
;
|
||||||
|
statements:
|
||||||
|
/* epsilon */ | statements statement
|
||||||
|
;
|
||||||
|
statement:
|
||||||
|
var_decl | assign_stmt | print_stmt | input_stmt | return_stmt |
|
||||||
|
loop_stmt | branch_stmt | fun_call | abort_stmt | assert_stmt
|
||||||
|
;
|
||||||
|
var_decl:
|
||||||
|
VARDECL pointer ID COMMA TYPENAME var_init NEWLINE
|
||||||
|
;
|
||||||
|
pointer:
|
||||||
|
/* epsilon */ | STAR
|
||||||
|
;
|
||||||
|
var_init:
|
||||||
|
/* epsilon */ | ASSIGN numeric
|
||||||
|
;
|
||||||
|
numeric:
|
||||||
|
NUMBER | FLOAT
|
||||||
|
;
|
||||||
|
variable:
|
||||||
|
ID | ARTICLE ID
|
||||||
|
;
|
||||||
|
assign_stmt:
|
||||||
|
ID ASSIGN expression NEWLINE
|
||||||
|
;
|
||||||
|
print_stmt:
|
||||||
|
expression PRINT
|
||||||
|
;
|
||||||
|
input_stmt:
|
||||||
|
INPUT variable
|
||||||
|
;
|
||||||
|
return_stmt:
|
||||||
|
RETURN NEWLINE | RETURN expression NEWLINE;
|
||||||
|
;
|
||||||
|
loop_stmt:
|
||||||
|
LOOP_BEGIN statements LOOP_CONDITION expression
|
||||||
|
;
|
||||||
|
branch_stmt:
|
||||||
|
BRANCH_CONDITION variable BRANCH_BEGIN
|
||||||
|
branch_body
|
||||||
|
BRANCH_END
|
||||||
|
;
|
||||||
|
branch_body:
|
||||||
|
cases %prec LOWER_THAN_ELSE |
|
||||||
|
cases BRANCH_ELSE COLON statements
|
||||||
|
;
|
||||||
|
cases:
|
||||||
|
case_stmt | case_stmt cases
|
||||||
|
;
|
||||||
|
case_stmt:
|
||||||
|
case_hp COLON statements
|
||||||
|
;
|
||||||
|
case_hp:
|
||||||
|
numeric | variable
|
||||||
|
;
|
||||||
|
fun_call:
|
||||||
|
FUNCALL ID args NEWLINE | FUNCALL ID NEWLINE
|
||||||
|
;
|
||||||
|
abort_stmt:
|
||||||
|
ABORT {
|
||||||
|
emit("exit(1);\n");
|
||||||
|
}
|
||||||
|
;
|
||||||
|
assert_stmt:
|
||||||
|
ASSERT_BEGIN expression ASSERT_END {
|
||||||
|
emit("assert(", $2, ");\n");
|
||||||
|
}
|
||||||
|
;
|
||||||
|
expression:
|
||||||
|
numeric |
|
||||||
|
variable |
|
||||||
|
expression OP_LT expression |
|
||||||
|
expression OP_GT expression |
|
||||||
|
expression OP_LTE expression |
|
||||||
|
expression OP_GTE expression |
|
||||||
|
expression OP_PLUS expression |
|
||||||
|
expression OP_MINUS expression |
|
||||||
|
expression OP_TIMES expression |
|
||||||
|
expression OP_DIV expression |
|
||||||
|
expression OP_SHL expression |
|
||||||
|
expression OP_SHR expression
|
||||||
|
;
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
209
Specification.txt
Normal file
209
Specification.txt
Normal file
|
@ -0,0 +1,209 @@
|
||||||
|
Proposte per la definizione di un linguaggio di programmazione esoterico "Monicelli"
|
||||||
|
|
||||||
|
Il "main" del programma inizia in corrispondenza di:
|
||||||
|
Lei ha clacsonato
|
||||||
|
che da il via alla supercazzola (cioè al programma)
|
||||||
|
|
||||||
|
|
||||||
|
Il programma termina con l'istruzione
|
||||||
|
vaffanzum
|
||||||
|
che equivale a
|
||||||
|
return
|
||||||
|
Può essere usato anche per terminare le funzioni restituendo un valore di ritorno:
|
||||||
|
vaffanzum antani
|
||||||
|
|
||||||
|
*** Tipi di dato ***
|
||||||
|
* Necchi -> int
|
||||||
|
* Mascetti -> char
|
||||||
|
* Perozzi -> float
|
||||||
|
* Melandri -> bool
|
||||||
|
* Sassaroli -> double
|
||||||
|
|
||||||
|
I puntatori si dichiarano anteponendo "conte" al nome della variabile
|
||||||
|
|
||||||
|
quindi
|
||||||
|
conte Mascetti
|
||||||
|
è
|
||||||
|
char*
|
||||||
|
|
||||||
|
|
||||||
|
*** Dichiarazione variabili ***
|
||||||
|
Si usa la sintassi:
|
||||||
|
voglio il <nome>, <tipo>[, come fosse <espressione>]
|
||||||
|
Esempio:
|
||||||
|
voglio il cappellano, Necchi
|
||||||
|
dichiara la variabile "cappellano" di tipo int
|
||||||
|
e:
|
||||||
|
voglio lo scrittoio, conte Mascetti
|
||||||
|
dichiara la variabile "scrittoio" di tipo "char*"
|
||||||
|
Eventualmente si può anche inizializzare immediatamente la variabile usando l'operatore di assegnamento (spiegato meglio nel seguito)
|
||||||
|
voglio il cappellano, Necchi, come fosse 4
|
||||||
|
|
||||||
|
Ogni volta che si deve utilizzare una variabile, è possibile precederla con un articolo.
|
||||||
|
La concordanza dell'articolo non è semanticamente verificata, ma ci si assicura sintatticamente
|
||||||
|
che l'articolo sia effettivamente un articolo.
|
||||||
|
|
||||||
|
|
||||||
|
*** Operatori ***
|
||||||
|
definiti a parole, per meglio integrarsi graficamente nella supercazzola.
|
||||||
|
|
||||||
|
Aritmetici
|
||||||
|
* più
|
||||||
|
* meno
|
||||||
|
* per
|
||||||
|
* diviso
|
||||||
|
|
||||||
|
Di shift:
|
||||||
|
con scappellamento a <direzione> per X
|
||||||
|
dove X e il numero di posizioni dello shift e direzione può essere
|
||||||
|
* sinistra
|
||||||
|
* destra
|
||||||
|
Esempio:
|
||||||
|
antani con scappellamento a destra per 2
|
||||||
|
equivale a
|
||||||
|
antani >> 2
|
||||||
|
|
||||||
|
|
||||||
|
Di confronto
|
||||||
|
* minore di
|
||||||
|
* maggiore di
|
||||||
|
* minore o uguale a
|
||||||
|
* maggiore o uguale a
|
||||||
|
|
||||||
|
|
||||||
|
Di assegnamento
|
||||||
|
è "come fosse".
|
||||||
|
Perciò:
|
||||||
|
vicesindaco come fosse antani per due a destra
|
||||||
|
equivale a
|
||||||
|
vicesindaco = antani >> 2
|
||||||
|
|
||||||
|
|
||||||
|
Operatore di output (postfisso):
|
||||||
|
a posterdati
|
||||||
|
Esempio:
|
||||||
|
antani a posterdati
|
||||||
|
Stampa la variabile "antani" a video
|
||||||
|
|
||||||
|
|
||||||
|
Operatore di input:
|
||||||
|
mi porga <variabile>
|
||||||
|
Esempio
|
||||||
|
mi porga il cappellano
|
||||||
|
richiede all'utente di inserire il valore della variabile "cappellano" da standard input
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
*** Cicli ***
|
||||||
|
|
||||||
|
Stuzzica-Brematura
|
||||||
|
Stuzzica il palato eseguendo almeno una volta il corpo del ciclo, ed eventualmente lo brematura altre volte.
|
||||||
|
Sintassi:
|
||||||
|
stuzzica
|
||||||
|
<corpo del ciclo>
|
||||||
|
e brematura anche, se <condizione>
|
||||||
|
|
||||||
|
|
||||||
|
*** Costrutto di selezione (switch+if) ***
|
||||||
|
"Che cos'è"
|
||||||
|
È l'unico costrutto di selezione, facente funzione sia di if, sia di switch
|
||||||
|
Sintassi:
|
||||||
|
che cos'è <articolo> <variabileDiControllo>?
|
||||||
|
<ipotesi>:
|
||||||
|
<codice>
|
||||||
|
<ipotesi>:
|
||||||
|
<codice>
|
||||||
|
[tarapia tapioco: #Else/default, opzionale
|
||||||
|
<codice>
|
||||||
|
]
|
||||||
|
e velocità di esecuzione.
|
||||||
|
|
||||||
|
<ipotesi> può essere:
|
||||||
|
* <espressione>:
|
||||||
|
il codice viene eseguito se il risultato dell'espressione è uguale alla variabileDiControllo
|
||||||
|
* <op_confronto> <espressione>:
|
||||||
|
il codice viene eseguito se è vero che: <variabileDiControllo> <op_confronto> <espressione>
|
||||||
|
|
||||||
|
Esempio:
|
||||||
|
che cos'è il genio?
|
||||||
|
fantasia:
|
||||||
|
antani come se fosse vicesindaco per due
|
||||||
|
intuizione:
|
||||||
|
mi porga il cappellano
|
||||||
|
zingarata come fosse cappellano più uno
|
||||||
|
zingarata a posterdati
|
||||||
|
maggiore di mobiletto:
|
||||||
|
genio a posterdati
|
||||||
|
tarapia tapioco:
|
||||||
|
mi porga il cappello
|
||||||
|
e velocita di esecuzione
|
||||||
|
|
||||||
|
Che corrisponde a (pseudocodice):
|
||||||
|
switch(genio) {
|
||||||
|
case genio=fantasia:
|
||||||
|
antani = vicesindaco*2
|
||||||
|
case genio=intuizione:
|
||||||
|
input cappellano
|
||||||
|
zingarata = cappellano+1
|
||||||
|
print zingarata
|
||||||
|
case genio > mobiletto:
|
||||||
|
print genio
|
||||||
|
default:
|
||||||
|
input cappello
|
||||||
|
}
|
||||||
|
|
||||||
|
*** Funzioni ***
|
||||||
|
Una funzione può essere definita con la sintassi:
|
||||||
|
blinda la supercazzola <nome> [con <parametro>[, <parametro>]] {
|
||||||
|
<codice>
|
||||||
|
}
|
||||||
|
|
||||||
|
che definisce la funzione <nome> con i parametri in ingresso specificati
|
||||||
|
|
||||||
|
|
||||||
|
Le funzioni sono invocate con la sintassi:
|
||||||
|
brematurata la supercazzola <nome> con [<parametro>[, <parametro>]]
|
||||||
|
|
||||||
|
*** Eccezioni ***
|
||||||
|
Esiste un'unica eccezione possibile (di fatto, corrispondente a segnalare un errore non gestibile e
|
||||||
|
causa la terminazione del programma).
|
||||||
|
L'eccezione può essere lanciata tramite la frase:
|
||||||
|
avvertite don ulrico
|
||||||
|
|
||||||
|
Esempio:
|
||||||
|
che cos'è il thermos?
|
||||||
|
un oggetto:
|
||||||
|
barilotto come se fosse antani per due
|
||||||
|
> 0:
|
||||||
|
thermos come se fosse thermos meno 1
|
||||||
|
tarapia tapioco:
|
||||||
|
avvertite don ulrico
|
||||||
|
e velocità di esecuzione
|
||||||
|
|
||||||
|
Che corrisponde a (pseudocodice):
|
||||||
|
switch(thermos) {
|
||||||
|
case thermos==oggetto:
|
||||||
|
barilotto = antani * 2
|
||||||
|
case thermos>0:
|
||||||
|
thermos = thermos-1
|
||||||
|
default:
|
||||||
|
raise exception
|
||||||
|
}
|
||||||
|
|
||||||
|
*** Commenti ***
|
||||||
|
Ogni riga iniziata da "bituma" è un commento e viene completamente ignorata dal compilatore
|
||||||
|
|
||||||
|
Esempio:
|
||||||
|
bituma il codice che esegue la FFT
|
||||||
|
|
||||||
|
|
||||||
|
*** Asserzioni ***
|
||||||
|
ho visto la <condizione>!
|
||||||
|
verifica che la condizione risulti vera, altrimenti avverte don Ulrico (ossia, lancia un'eccezione)
|
||||||
|
|
||||||
|
Esempio:
|
||||||
|
ho visto il cappellano come fosse la lavagna!
|
||||||
|
equivale a
|
||||||
|
assert(cappellano==lavagna)
|
13
Type.h
Normal file
13
Type.h
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#ifndef TYPE_H
|
||||||
|
#define TYPE_H
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
TYPENAME_INT,
|
||||||
|
TYPENAME_CHAR,
|
||||||
|
TYPENAME_FLOAT,
|
||||||
|
TYPENAME_BOOL,
|
||||||
|
TYPENAME_DOUBLE
|
||||||
|
} Type;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
31
main.c
Normal file
31
main.c
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
#include "Type.h"
|
||||||
|
#include "Monicelli.tab.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
int lineNumber = 1;
|
||||||
|
|
||||||
|
void yyerror(const char *message) {
|
||||||
|
fprintf(stderr, "At line %d: %s\n", lineNumber, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
void emit(const char *text, ...) {
|
||||||
|
va_list args;
|
||||||
|
va_start(args, text);
|
||||||
|
|
||||||
|
const char *t;
|
||||||
|
for (t = text; t != NULL; t = va_arg(args, const char *)) {
|
||||||
|
printf("%s", t);
|
||||||
|
}
|
||||||
|
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
#if YYDEBUG
|
||||||
|
yydebug = 1;
|
||||||
|
#endif
|
||||||
|
return yyparse();
|
||||||
|
}
|
||||||
|
|
Reference in New Issue
Block a user