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