Équivalence

This commit is contained in:
Yohann D'ANELLO 2020-05-16 02:49:34 +02:00
parent 80b4e20831
commit c78a047ec3
4 changed files with 35 additions and 3 deletions

2
.gitignore vendored
View File

@ -2,5 +2,7 @@ exclude-executables.sh
lexical/example lexical/example
lexical/flux lexical/flux
lexical/string lexical/string
syntaxique/expr
syntaxique/lang
*.c *.c
*.o *.o

View File

@ -30,7 +30,7 @@ typedef struct varlist // variable reference (used for print statement)
typedef struct expr // boolean expression typedef struct expr // boolean expression
{ {
int type; // TRUE, FALSE, OR, AND, NOT, 0 (variable) int type; // TRUE, FALSE, OR, AND, EQUIV, NOT, 0 (variable)
var *var; var *var;
struct expr *left, *right; struct expr *left, *right;
} expr; } expr;
@ -130,6 +130,7 @@ stmt* make_stmt (int type, var *var, expr *expr,
%left OR XOR %left OR XOR
%left AND %left AND
%right NOT %right NOT
%left EQUIV
%% %%
@ -158,6 +159,7 @@ expr : IDENT { $$ = make_expr(0,find_ident($1),NULL,NULL); }
| expr XOR expr { $$ = make_expr(XOR,NULL,$1,$3); } | expr XOR expr { $$ = make_expr(XOR,NULL,$1,$3); }
| expr OR expr { $$ = make_expr(OR,NULL,$1,$3); } | expr OR expr { $$ = make_expr(OR,NULL,$1,$3); }
| expr AND expr { $$ = make_expr(AND,NULL,$1,$3); } | expr AND expr { $$ = make_expr(AND,NULL,$1,$3); }
| expr EQUIV expr { $$ = make_expr(EQUIV,NULL,$1,$3); }
| NOT expr { $$ = make_expr(NOT,NULL,$2,NULL); } | NOT expr { $$ = make_expr(NOT,NULL,$2,NULL); }
| TRUE { $$ = make_expr(TRUE,NULL,NULL,NULL); } | TRUE { $$ = make_expr(TRUE,NULL,NULL,NULL); }
| FALSE { $$ = make_expr(FALSE,NULL,NULL,NULL); } | FALSE { $$ = make_expr(FALSE,NULL,NULL,NULL); }
@ -179,6 +181,12 @@ int eval (expr *e)
case XOR: return eval(e->left) ^ eval(e->right); case XOR: return eval(e->left) ^ eval(e->right);
case OR: return eval(e->left) || eval(e->right); case OR: return eval(e->left) || eval(e->right);
case AND: return eval(e->left) && eval(e->right); case AND: return eval(e->left) && eval(e->right);
case EQUIV: {
int right = eval(e->right);
int left = eval(e->left);
return (right && left) || (!right && !left); // Équivalent avec left == right avec la définition.
// Toutefois, on privilégie cette forme car faux = 0 et vrai = tout entier non nul.
}
case NOT: return !eval(e->left); case NOT: return !eval(e->left);
case 0: return e->var->value; case 0: return e->var->value;
} }

View File

@ -13,10 +13,11 @@ DIG [0-9]
"false" { return FALSE; } "false" { return FALSE; }
":=" { return ASSIGN; } ":=" { return ASSIGN; }
"^" { return XOR; } "^" { return XOR; }
"||" { return OR; } "||" { return OR; }
"&&" { return AND; } "&&" { return AND; }
"!" { return NOT; } "!" { return NOT; }
"<=>" { return EQUIV; }
[a-z_][a-z0-9_]* { yylval.i = strdup(yytext); return IDENT; } [a-z_][a-z0-9_]* { yylval.i = strdup(yytext); return IDENT; }

21
syntaxique/test.my Normal file
View File

@ -0,0 +1,21 @@
bool x,y,z;
x := true;
y := true;
z := x <=> y;
print x,y,z;
x := true;
y := false;
z := x <=> y;
print x,y,z;
x := false;
y := true;
z := x <=> y;
print x,y,z;
x := false;
y := false;
z := x <=> y;
print x,y,z