NotesWhat is notes.io?

Notes brand slogan

Notes - notes.io

%{
/*## extensions */

static void make_expression_statements (BlockStat* b, ExpressionList* x) { //E#3 <...
if (x)
for (ExpressionList::iterator i = x->begin(); i != x->end(); ++i)
b->add (*new ExpressionStat (**i));
} //E#3 ...>

struct etiquette { //E#4 <...
const char* et;
const int nb;

etiquette (const char* e, int n) : et (e), nb (n) { }
};

list<etiquette> pile_etiquettes;
static int compteur_etiquettes = 0;

static int chercher_etiquette (const char* e) {
for (list<etiquette>::const_iterator i = pile_etiquettes.begin(); i != pile_etiquettes.end(); ++i)
if ((*i).et == e) return (*i).nb;
return 0;
}

static int nouvelle_etiquette (const char* e) {
int n = 0;
if (e) {
n = chercher_etiquette (e);
if (n != 0) name_error ("etiquette deja declaree", e, yylineno);
n = ++compteur_etiquettes;
}
pile_etiquettes.push_front (etiquette (e, n));
return n;
}

static void oublier_etiquette() {
pile_etiquettes.pop_front();
}

static int trouver_etiquette (const char* e) {
int n = chercher_etiquette (e);
if (n == 0) name_error ("etiquette pas declaree", e, yylineno);
return n;
}

static void verifier_dans_boucle() {
if (pile_etiquettes.empty()) error ("le break n'est pas dans une boucle", yylineno);
} //E#4 ...>


static const ClassType* check_cast_type (Expression* e) { //E#5 <...
// il faudrait detruire l'arbre, car il est inutile pour la suite
if (SimpleDesignator* t = dynamic_cast<SimpleDesignator*>(e))
if (t->prefix() == 0) return search_class (t->member_name());
error ("il faut un nom de type pour le 'cast'", yylineno);
return &objectClass;
} //E#5 ...>


%}

%union {
int val;
const char* str; /* car pas possible d'avoir string dans une union */

const ClassType* cla;
const Type* typ;

const ParameterList* cpl;
ParameterList* pli;
Parameter* par;

Statement* sta;

Expression* exp;
ExpressionList* eli;

VariableDesignator* var; //E#5 et E#6 modifie: VariableDesignator* var;
CallDesignator* app;
Designator* des;
}

%token <str> IDENT CHAINE
%token <val> NOMBRE

%token KCLASS KEXTENDS KINT KBOOL KSTRING KVOID KNULL KTRUE KFALSE
%token KRETURN KEXTERN KIF KELSE KWHILE KSUPER KTHIS KNEW KMAIN
%token EQU NEQ GEQ LEQ
%token ELLIPSE

%right '='
%right '?' ':'
%left OR
%left AND
%nonassoc EQU NEQ
%nonassoc '<' LEQ '>' GEQ /* on interdit donc a < b < c */
%left '+' '-'
%left '*' '/' '%'
%left UMOINS
%left '!'

/*### ajout pour instance_of et cast */
%left KINSTOF //E#5
%left ')' //E#5

%type<str> nom_meth
%type<cla> herite type_classe
%type<typ> type type_simple declattr declvars
%type<cpl> parametres xparametres
%type<pli> listparam xlistparam sxlistparam
%type<par> parametre
%type<sta> instruction bloc
%type<exp> expression expression_opt
%type<eli> arguments liste_expr
%type<eli> liste_expr_opt init_for //E#3
%type<var> variable
%type<app> appel
%type<des> designateur prefixe

/********************************/
/*### extensions */
%token PP MM //E#1
%token KFOR //E#3
%token KBREAK //E#4
%token KROCHET //E#6

%type<exp> init_opt //E#2
%type<val> etiq_opt //E#4
%type<val> croch_opt //E#6
%type<eli> dimensions //E#6
/********************************/

%%

/* on emploie de preference des regles recursives a gauche */
/* ceci permet de provoquer les reductions plus rapidement */
/* et de ne pas encombrer la pile d'analyse */

program : listdecl main
;

listdecl : /* vide */
| listdecl defclasse
| listdecl declclasse
| listdecl declexterne
;

declclasse : KCLASS IDENT ';' { declare_class ($2); }
;

defclasse : debclasse '{' membres '}' PVO { end_class(); }
;

/* debutclasse est necessaire pour provoquer une reduction (et donc faire l'action) */
/* il faut en effet declarer la classe avant ses membres, et ouvrir une portee */

debclasse : KCLASS IDENT herite { start_class ($2, *$3); }
;

herite : /* vide */ { $$ = &objectClass; }
| KEXTENDS type_classe { $$ = $2; }

;

membres : /* vide */
| membres declattr ';'
| membres declmeth
;

/*### modification pour les init. et les tableaux */
declattr : type IDENT croch_opt init_opt { declare_attribute ($2, $1->array_type($3, yylineno), $4); $$ = $1; } //E#2+E#6
| declattr ',' IDENT croch_opt init_opt { declare_attribute ($3, $1->array_type($4, yylineno), $5); $$ = $1; } //E#2+E#6
;
/*### modification pour les tableaux */
type : type_simple croch_opt { $$ = &$1->array_type($2, yylineno); } //E#6
| type_classe croch_opt { $$ = &$1->array_type($2, yylineno); } //E#6
;

type_simple : KINT { $$ = &intType; }
| KBOOL { $$ = &boolType; }
| KSTRING { $$ = &stringType; }
;

type_classe : IDENT { $$ = search_class ($1); }
;

croch_opt : /* vide */ { $$ = 0; } //E#6
| croch_opt KROCHET { $$ = $1 + 1; } //E#6
;

/* la reduction apres l'entete des methodes permet de faire les actions sur le nom */
/* de la methode et sur ses parametres avant d'analyser le corps de la methode */

declmeth : entete '{' corps '}' PVO { end_block (); }
;
/* l'idee de definir typeResult = type | KVOID est bonne, mais elle provoque */
/* un conflit decalage/reduction; en effet, que dire de int dans int F ? */
/* int sera reduit sans probleme a type, mais ensuite */
/* est-ce un type (avancer sur IDENT) ou un typeResult (reduire a typeResult) ? */
/* l'ecriture suivante permet d'avoir toujours un decalage sur IDENT */

entete : type nom_meth '(' parametres ')' { declare_method ($2, $1, *$4); }
| KVOID nom_meth '(' parametres ')' { declare_method ($2, &voidType, *$4); }
| nom_meth '(' parametres ')' { declare_method ($1, 0, *$3); }
;

nom_meth : IDENT { start_block(); $$ = $1; }
;

parametres : /* vide */ { $$ = &empty_parameter_list; }
| listparam { $$ = $1; }
;

listparam : parametre { $$ = new ParameterList(); $$->push_back($1); }
| listparam ',' parametre { $1->push_back($3); $$ = $1; }
;

/*### modification pour les tableaux */
parametre : type IDENT croch_opt { $$ = declare_parameter ($2, $1->array_type($3, yylineno)); } //E#6
;

corps : /* vide */ { }
| corps declvars ';' { }
| corps instruction { if ($2) current_block->add(*$2); }
;

bloc : avant_bloc '{' corps '}' { $$ = current_block; end_block(); }
;

avant_bloc : /* vide */ { start_block(); }
;

/* pas d'initialisation des variables a la declaration pour le moment */

/*### modification pour les init. et les tableaux */
declvars : type IDENT croch_opt init_opt { declare_variable ($2, $1->array_type ($3, yylineno), $4); $$ = $1; } //E#2+E#6
| declvars ',' IDENT croch_opt init_opt { declare_variable ($3, $1->array_type ($4, yylineno), $5); $$ = $1; } //E#2+E#6
;

init_opt : '=' expression { $$ = $2; } //E#2
| /* vide */ { $$ = 0; } //E#2
;

instruction : KIF '(' expression ')' instruction
{ $$ = new IfStat(*$3, $5, 0); }
| KIF '(' expression ')' instruction KELSE instruction
{ $$ = new IfStat(*$3, $5, $7); }
/* conflit shift / reduce classique du if-then-else */

| etiq_opt KWHILE '(' expression ')' instruction //E#4
{ $$ = new WhileStat(*$4, $6, $1); oublier_etiquette(); } //E#4
| KRETURN expression_opt ';' { $$ = new ReturnStat($2, yylineno); }
| KTHIS '(' arguments ')' ';' { $$ = new ConstructorStat(false, *$3, class_denoter(false), yylineno); }
| KSUPER '(' arguments ')' ';' { $$ = new ConstructorStat(true, *$3, class_denoter(true), yylineno); }
| bloc { $$ = $1; }
| expression ';' { $$ = new ExpressionStat(*$1); }
| ';' { $$ = 0; }
/*## extensions */
| etiq_opt for '(' init_for ';' expression_opt ';' liste_expr_opt ')' instruction //E#3+E#4
{
make_expression_statements (current_block, $4); //E#3
BlockStat* b = new BlockStat (current_block, yylineno); //E#3
if ($10) b->add (*$10); //E#3
make_expression_statements (b, $8); //E#3
Expression* c = $6 ? $6 : new LogicValue (yylineno, true); //E#3
current_block->add (*new WhileStat (*c, b, $1)); //E#3
$$ = current_block; end_block(); //E#3
oublier_etiquette(); //E#4
}
| KBREAK ';' { verifier_dans_boucle(); $$ = new BreakStat (0, yylineno); } //E#4
| KBREAK IDENT ';' { verifier_dans_boucle(); $$ = new BreakStat (trouver_etiquette ($2), yylineno); } //E#4
;

etiq_opt : /* vide */ { $$ = nouvelle_etiquette (0); } //E#4
| IDENT ':' { $$ = nouvelle_etiquette ($1); } //E#4

for : KFOR { start_block(); } //E#3
;

init_for : declvars { $$ = 0; } //E#3
| liste_expr_opt { $$ = $1; } //E#3
;

expression_opt : expression { $$ = $1; }
| /* vide */ { $$ = 0; }

liste_expr_opt : liste_expr { $$ = $1; } //E#3
| /* vide */ { $$ = 0; } //E#3
;

liste_expr : expression { $$ = new ExpressionList(); $$->push_back($1); }
| liste_expr ',' expression { $1->push_back($3); $$ = $1; }
;

/* on autorise naturellement f(...).g(...)... */
/* f(...) = ... sera traitee semantiquement (pas une lvalue) */
/* on ne va pas jusqu'a autoriser (a+b).c, mais ce serait possible en C++ */
/* puisque les operateurs peuvent etre surcharges par des fonctions */

expression : variable '=' expression { $$ = new Assignment(*$1, *$3); }
| expression '!'
{ ////E#1bis
ParameterList *pl =new ParameterList();
pl->push_front(new Parameter(string(), intType, 0, 1) );
declare_external ("_FACT", intType, *pl, true); /////E#2009 inutile de générer "extern" en C
ExpressionList *l = new ExpressionList();
l->push_back($1);
$$=new CallDesignator(0, "_FACT", *l, yylineno);
}
| expression '?' expression ':' expression { $$ = new Condition(*$1, *$3, *$5); }
| expression OR expression { $$ = new Logic("||", *$1, *$3); }
| expression AND expression { $$ = new Logic("&&", *$1, *$3); }
| expression EQU expression { $$ = new Comparison("==", *$1, *$3); }
| expression NEQ expression { $$ = new Comparison("!=", *$1, *$3); }
| expression '>' expression { $$ = new Comparison(">", *$1, *$3); }
| expression GEQ expression { $$ = new Comparison(">=", *$1, *$3); }
| expression '<' expression { $$ = new Comparison("<", *$1, *$3); }
| expression LEQ expression { $$ = new Comparison("<=", *$1, *$3); }
| expression '+' expression { $$ = new BinArith("+", *$1, *$3); }
| expression '-' expression { $$ = new BinArith("-", *$1, *$3); }
| expression '*' expression { $$ = new BinArith("*", *$1, *$3); }
| expression '/' expression { $$ = new BinArith("/", *$1, *$3); }
| expression '%' expression { $$ = new BinArith("%", *$1, *$3); }
| '!' expression { $$ = new UnaLogic("!", *$2); }
| '-' expression %prec UMOINS { $$ = new UnaArith("-", *$2); }
/* autorise 1 + - - 2 BOF !!! */
| NOMBRE { $$ = new Number(yylineno, $1); }
| KFALSE { $$ = new LogicValue(yylineno, 0); }
| KTRUE { $$ = new LogicValue(yylineno, 1); }
| CHAINE { $$ = new String(yylineno, $1); }
| KNULL { $$ = new Null(yylineno); }
| '(' expression ')' { $$ = new Parenthesis(*$2); }
/* puisque les priorites sont les memes qu'en C */
| KNEW type_classe { $$ = new Creation(*$2, *new ExpressionList, yylineno); }
| KNEW type_classe '(' arguments ')' { $$ = new Creation(*$2, *$4, yylineno); }
| designateur { $$ = $1; }
/***********************************************/
/*## extensions */
| PP variable { $$ = new IncDec ("++", true, *$2); } //E#1
| variable PP { $$ = new IncDec ("++", false, *$1); } //E#1
| MM variable { $$ = new IncDec ("--", true, *$2); } //E#1
| variable MM { $$ = new IncDec ("--", false, *$1); } //E#1
| '(' expression ')' expression { $$ = new Conversion (true, *check_cast_type ($2), *$4); } //E#5
| expression KINSTOF type_classe { $$ = new InstanceOf (*$1, *$3); } //E#5
| KNEW type dimensions croch_opt { $$ = new ArrayCreation (*$2, *$3, $4, yylineno); } //E#6
;

variable : IDENT { $$ = new SimpleDesignator(0, $1, yylineno); }
| prefixe IDENT { $$ = new SimpleDesignator($1, $2, yylineno); }
| variable '[' expression ']' { $$ = new IndexedDesignator (*$1, *$3); } //E#6
| appel '[' expression ']' { $$ = new IndexedDesignator (*$1, *$3); } //E#6
;

appel : IDENT '(' arguments ')' { $$ = new CallDesignator(0, $1, *$3, yylineno); }
| prefixe IDENT '(' arguments ')' { $$ = new CallDesignator($1, $2, *$4, yylineno); }
;

designateur : KTHIS { check_in_class(); $$ = new ThisDesignator(false, yylineno); }
| variable { $$ = $1; }
| appel { $$ = $1; }
;

prefixe : designateur '.' { $$ = $1; }
| KSUPER '.' { check_in_class(); $$ = new ThisDesignator(true, yylineno); }
;

arguments : /* vide */ { $$ = new ExpressionList; }
| liste_expr { $$ = $1; }
;

dimensions : '[' expression ']' { $$ = new ExpressionList; $$->push_back ($2); } //E#6
| dimensions '[' expression ']' { $$ = $1; $$->push_back ($3); } //E#6
;

/* on pourrait avoir ici un non terminal typeResult; la presence a gauche du terminal */
/* KEXTERNE permet de `savoir' que le type n'est pas celui d'une declaration de variable */

declexterne : KEXTERN type IDENT '(' xparametres ')' ';' { declare_external ($3, *$2, *$5); }
| KEXTERN KVOID IDENT '(' xparametres ')' ';' { declare_external ($3, voidType, *$5); }
;

xparametres : /* vide */ { $$ = &empty_parameter_list; }
| xlistparam { $$ = $1; }
;

xlistparam : type sxlistparam { $2->push_front (new Parameter (string(), *$1, 0, yylineno)); $$ = $2; } //E#2
;

sxlistparam : /* vide */ { $$ = new ParameterList(); }
| ',' ELLIPSE { $$ = new ParameterList(); $$->push_front (new Ellipse (yylineno)); }
| ',' xlistparam { $$ = $2; }
;

main : KMAIN { start_main(); }
'(' ')' '{' corps '}' { end_main(); }
;

PVO : ';'
| /* vide */
;
     
 
what is notes.io
 

Notes.io is a web-based application for taking notes. You can take your notes and share with others people. If you like taking long notes, notes.io is designed for you. To date, over 8,000,000,000 notes created and continuing...

With notes.io;

  • * You can take a note from anywhere and any device with internet connection.
  • * You can share the notes in social platforms (YouTube, Facebook, Twitter, instagram etc.).
  • * You can quickly share your contents without website, blog and e-mail.
  • * You don't need to create any Account to share a note. As you wish you can use quick, easy and best shortened notes with sms, websites, e-mail, or messaging services (WhatsApp, iMessage, Telegram, Signal).
  • * Notes.io has fabulous infrastructure design for a short link and allows you to share the note as an easy and understandable link.

Fast: Notes.io is built for speed and performance. You can take a notes quickly and browse your archive.

Easy: Notes.io doesn’t require installation. Just write and share note!

Short: Notes.io’s url just 8 character. You’ll get shorten link of your note when you want to share. (Ex: notes.io/q )

Free: Notes.io works for 12 years and has been free since the day it was started.


You immediately create your first note and start sharing with the ones you wish. If you want to contact us, you can use the following communication channels;


Email: [email protected]

Twitter: http://twitter.com/notesio

Instagram: http://instagram.com/notes.io

Facebook: http://facebook.com/notesio



Regards;
Notes.io Team

     
 
Shortened Note Link
 
 
Looding Image
 
     
 
Long File
 
 

For written notes was greater than 18KB Unable to shorten.

To be smaller than 18KB, please organize your notes, or sign in.