From 524be5fa549d7c598740b53aeda1c4432d546b01 Mon Sep 17 00:00:00 2001 From: schodet Date: Wed, 21 May 2003 23:28:19 +0000 Subject: Version compilable. --- 2003/i/buzz/src/automate/Makefile.defs | 6 ++- 2003/i/buzz/src/automate/action.cc | 31 ++++++++++++ 2003/i/buzz/src/automate/action.h | 10 ++-- 2003/i/buzz/src/automate/expression.cc | 52 +++++++++++++++++++ 2003/i/buzz/src/automate/expression.h | 48 ++++++++++++++++++ 2003/i/buzz/src/automate/grafcet.cc | 83 ++++++++++++++++++++++++++++++- 2003/i/buzz/src/automate/grafcet.h | 39 ++++++--------- 2003/i/buzz/src/automate/grammar.yy | 55 ++++++++++++++++---- 2003/i/buzz/src/automate/lexer.ll | 11 +++- 2003/i/buzz/src/automate/receptivite.cc | 29 +++++++++++ 2003/i/buzz/src/automate/receptivite.h | 17 +++++++ 2003/i/buzz/src/automate/test_automate.cc | 11 ++++ 12 files changed, 350 insertions(+), 42 deletions(-) create mode 100644 2003/i/buzz/src/automate/expression.cc create mode 100644 2003/i/buzz/src/automate/expression.h create mode 100644 2003/i/buzz/src/automate/test_automate.cc (limited to '2003/i/buzz') diff --git a/2003/i/buzz/src/automate/Makefile.defs b/2003/i/buzz/src/automate/Makefile.defs index ca0a7a9..d5eff12 100644 --- a/2003/i/buzz/src/automate/Makefile.defs +++ b/2003/i/buzz/src/automate/Makefile.defs @@ -1,5 +1,9 @@ -automate_a_SOURCES = grafcet.cc receptivite.cc action.cc grammar.cc lexer.cc +TARGETS += test_automate +automate_a_SOURCES = grafcet.cc receptivite.cc action.cc grammar.cc lexer.cc expression.cc +test_automate_SOURCES = test_automate.cc $(automate_a_SOURCES) erreur.a extra_clean += grammar.h grammar.cc lexer.cc +test_automate: $(test_automate_SOURCES:%.cc=%.o) + automate.a: ${automate_a_SOURCES:%.cc=automate.a(%.o)} diff --git a/2003/i/buzz/src/automate/action.cc b/2003/i/buzz/src/automate/action.cc index d5e4ade..2764a44 100644 --- a/2003/i/buzz/src/automate/action.cc +++ b/2003/i/buzz/src/automate/action.cc @@ -14,4 +14,35 @@ Action::~Action () { } +// Utilisée une fois, lors de l'activation de l'action. +void +Action::start (void) +{ +} + +// Execute l'action. Renvoie true si terminée. +bool +Action::run (void) +{ + return true; +} + +// Utilisée une fois, lors de la désactivation de l'action. +void +Action::stop (void) +{ +} + +// Destructeur. +ActionPrint::~ActionPrint () +{ +} + +// Utilisée une fois, lors de l'activation de l'action. +void +ActionPrint::start (void) +{ + cout << m_s << endl; +} + } diff --git a/2003/i/buzz/src/automate/action.h b/2003/i/buzz/src/automate/action.h index 7fb9806..fcd0b2c 100644 --- a/2003/i/buzz/src/automate/action.h +++ b/2003/i/buzz/src/automate/action.h @@ -13,8 +13,12 @@ namespace Automate public: // Destructeur. virtual ~Action (); + // Utilisée une fois, lors de l'activation de l'action. + virtual void start (void); // Execute l'action. Renvoie true si terminée. - virtual bool run (void) = 0; + virtual bool run (void); + // Utilisée une fois, lors de la désactivation de l'action. + virtual void stop (void); }; class ActionPrint : public Action @@ -25,8 +29,8 @@ namespace Automate ActionPrint (string &s) : m_s (s) { } // Destructeur. ~ActionPrint (); - // Execute l'action. Renvoie true si terminée. - bool run (void); + // Utilisée une fois, lors de l'activation de l'action. + void start (void); }; } diff --git a/2003/i/buzz/src/automate/expression.cc b/2003/i/buzz/src/automate/expression.cc new file mode 100644 index 0000000..99d73b8 --- /dev/null +++ b/2003/i/buzz/src/automate/expression.cc @@ -0,0 +1,52 @@ +// expression.cc +// buzz - Programme du robot Efrei Robotique I1-I2 2003 +// Copyright (C) 2003 Nicolas Schodet +// +#include "expression.h" + +namespace Automate +{ + +// Destructeur. +Expression::~Expression () +{ +} + +// Destructeur. +ExpressionNum::~ExpressionNum () +{ +} + +// Retourne la valeur de l'expression. +int +ExpressionNum::val (void) +{ + return m_num; +} + +// Destructeur. +ExpressionNumOp::~ExpressionNumOp () +{ + if (m_left) delete m_left; + if (m_right) delete m_right; +} + +// Retourne la valeur de l'expression. +int +ExpressionNumOp::val (void) +{ + switch (m_op) + { + case '-': + return m_left->val () - m_right->val (); + case '+': + return m_left->val () + m_right->val (); + case '*': + return m_left->val () * m_right->val (); + case 'n': + return -m_right->val (); + } + return 0; +} + +} diff --git a/2003/i/buzz/src/automate/expression.h b/2003/i/buzz/src/automate/expression.h new file mode 100644 index 0000000..c349bed --- /dev/null +++ b/2003/i/buzz/src/automate/expression.h @@ -0,0 +1,48 @@ +#ifndef expression_h +#define expression_h +// expression.h +// buzz - Programme du robot Efrei Robotique I1-I2 2003 +// Copyright (C) 2003 Nicolas Schodet +#include "expression.h" + +namespace Automate +{ + class Expression + { + public: + // Destructeur. + virtual ~Expression (); + // Retourne la valeur de l'expression. + virtual int val (void) = 0; + }; + + class ExpressionNum : public Expression + { + int m_num; + public: + // Constructeur. + ExpressionNum (int num) { m_num = num; } + // Destructeur. + ~ExpressionNum (); + // Retourne la valeur de l'expression. + int val (void); + }; + + class ExpressionNumOp : public Expression + { + char m_op; + Expression *m_left, *m_right; + public: + // Constructeurs. + ExpressionNumOp (Expression *left, char op, Expression *right) + { m_left = left; m_op = op; m_right = right; } + ExpressionNumOp (char op, Expression *right) + { m_left = 0; m_op = op; m_right = right; } + // Destructeur. + ~ExpressionNumOp (); + // Retourne la valeur de l'expression. + int val (void); + }; +} + +#endif // expression_h diff --git a/2003/i/buzz/src/automate/grafcet.cc b/2003/i/buzz/src/automate/grafcet.cc index b2af52e..045b61f 100644 --- a/2003/i/buzz/src/automate/grafcet.cc +++ b/2003/i/buzz/src/automate/grafcet.cc @@ -29,7 +29,7 @@ Grafcet::Grafcet (const char *filename) // Destructeur. Grafcet::~Grafcet () { - for (vector::iterator i = m_grafcet.begin (); + for (vector::iterator i = m_grafcet.begin (); i != m_grafcet.end (); ++i) { switch (i->type) @@ -50,5 +50,86 @@ Grafcet::~Grafcet () } } +// Lance l'execution d'un pas, c'est à dire, retourne le plus vite +// possible. +void +Grafcet::run (void) +{ + // Parcours le programme et évalue les receptivitées. + int e = 0; // Étape courante. + vector::const_iterator i; + for (i = m_grafcet.begin (); i != m_grafcet.end ();) + { + switch (i->type) + { + case etape: + e = i->elem.etape->num; + ++i; + break; + case receptivite: + if (m_active_etapes[e] == active && i->elem.receptivite->test ()) + { + m_active_etapes[e] = stop; + for (++i; i != m_grafcet.end () && i->type == transition; ++i) + { + int g = i->elem.transition->num; + m_active_etapes[g > 0 ? g : -g] = g > 0 ? start : stop; + } + } + break; + case action: + case transition: + ++i; + break; + } + } + // Arète les actions en stop. + for (i = m_grafcet.begin (); i != m_grafcet.end ();) + { + if (i->type == etape) + { + e = i->elem.etape->num; + if (m_active_etapes[e] == stop) + { + for (++i; i != m_grafcet.end () && i->type == action; ++i) + i->elem.action->stop (); + } + m_active_etapes[e] = inactive; + } + else + ++i; + } + // Initialise les actions pour les etapes en start. + for (i = m_grafcet.begin (); i != m_grafcet.end ();) + { + if (i->type == etape) + { + e = i->elem.etape->num; + if (m_active_etapes[e] == start) + { + for (++i; i != m_grafcet.end () && i->type == action; ++i) + i->elem.action->start (); + } + m_active_etapes[e] = active; + } + else + ++i; + } + // Fait fonctionner les actions. + for (i = m_grafcet.begin (); i != m_grafcet.end ();) + { + if (i->type == etape) + { + e = i->elem.etape->num; + if (m_active_etapes[e] == active) + { + for (++i; i != m_grafcet.end () && i->type == action; ++i) + i->elem.action->run (); + } + } + else + ++i; + } +} } // namespace Automate diff --git a/2003/i/buzz/src/automate/grafcet.h b/2003/i/buzz/src/automate/grafcet.h index 09b87a1..ba86e87 100644 --- a/2003/i/buzz/src/automate/grafcet.h +++ b/2003/i/buzz/src/automate/grafcet.h @@ -17,14 +17,14 @@ class Grafcet { public: // Type d'un élément du grafcet. - enum GrafcetElemType + enum ElemType { etape, action, receptivite, transition }; // Structure des éléments. - struct GrafcetElem + struct Elem { - GrafcetElemType type; + ElemType type; union { Etape *etape; @@ -33,29 +33,17 @@ class Grafcet Transition *transition; } elem; // Constructeurs. - GrafcetElem (Etape *_etape) - { - type = etape; - elem.etape = _etape; - } - GrafcetElem (Action *_action) - { - type = action; - elem.action = _action; - } - GrafcetElem (Receptivite *_receptivite) - { - type = receptivite; - elem.receptivite = _receptivite; - } - GrafcetElem (Transition *_transition) - { - type = transition; - elem.transition = _transition; - } + Elem (Etape *_etape) + { type = etape; elem.etape = _etape; } + Elem (Action *_action) + { type = action; elem.action = _action; } + Elem (Receptivite *_receptivite) + { type = receptivite; elem.receptivite = _receptivite; } + Elem (Transition *_transition) + { type = transition; elem.transition = _transition; } }; // Contient le grafcet complet. - vector m_grafcet; + vector m_grafcet; // Etapes actives. enum ActiveStep { @@ -72,6 +60,9 @@ class Grafcet ~Grafcet (); // Retourne une référence vers l'instance. static Grafcet &getInstance () { return *m_instance; } + // Lance l'execution d'un pas, c'est à dire, retourne le plus vite + // possible. + void run (void); }; } diff --git a/2003/i/buzz/src/automate/grammar.yy b/2003/i/buzz/src/automate/grammar.yy index 709c8e3..04a001e 100644 --- a/2003/i/buzz/src/automate/grammar.yy +++ b/2003/i/buzz/src/automate/grammar.yy @@ -27,6 +27,7 @@ Grafcet *input_grafcet; Action *action; Receptivite *receptivite; Transition *transition; + Expression *expression; } %token NUM @@ -34,18 +35,25 @@ Grafcet *input_grafcet; %token BOOL %token STRING %token ERR GOTO +%token EQ NEQ LEQ GEQ %token PRINT %type grafcet %type etape %type action %type receptivite %type transition +%type expression %type flnum /* Priorité des opérateurs. */ -%right '+' -%right '.' -%right '!' +%left '|' +%left '&' +%left '!' +%left EQ NEQ LEQ GEQ '<' '>' + +%left '+' '-' +%left '*' '/' +%left NEG %% @@ -54,10 +62,10 @@ input: grafcet { input_grafcet = $1; } grafcet: /* Rien */ { $$ = new Grafcet (); } - | grafcet etape { $$ = $1; $$->m_grafcet.push_back (Grafcet::GrafcetElem ($2)); } - | grafcet action { $$ = $1; $$->m_grafcet.push_back (Grafcet::GrafcetElem ($2)); } - | grafcet receptivite { $$ = $1; $$->m_grafcet.push_back (Grafcet::GrafcetElem ($2)); } - | grafcet transition { $$ = $1; $$->m_grafcet.push_back (Grafcet::GrafcetElem ($2)); } + | grafcet etape { $$ = $1; $$->m_grafcet.push_back (Grafcet::Elem ($2)); } + | grafcet action { $$ = $1; $$->m_grafcet.push_back (Grafcet::Elem ($2)); } + | grafcet receptivite { $$ = $1; $$->m_grafcet.push_back (Grafcet::Elem ($2)); } + | grafcet transition { $$ = $1; $$->m_grafcet.push_back (Grafcet::Elem ($2)); } ; etape: '#' NUM { $$ = new Etape ($2); } @@ -68,11 +76,36 @@ action: PRINT STRING { $$ = new ActionPrint (*$2); delete $2; } receptivite: BOOL { $$ = new ReceptiviteBool ($1); } - | receptivite '.' receptivite - { $$ = new ReceptiviteBoolOp ($1, '.', $3); } - | receptivite '+' receptivite - { $$ = new ReceptiviteBoolOp ($1, '+', $3); } + | receptivite '&' receptivite + { $$ = new ReceptiviteBoolOp ($1, '&', $3); } + | receptivite '|' receptivite + { $$ = new ReceptiviteBoolOp ($1, '|', $3); } | '!' receptivite { $$ = new ReceptiviteBoolOp ('!', $2); } + | '(' receptivite ')' { $$ = $2; } + | expression EQ expression + { $$ = new ReceptiviteCmpOp ($1, '=', $3); } + | expression NEQ expression + { $$ = new ReceptiviteCmpOp ($1, 'n', $3); } + | expression LEQ expression + { $$ = new ReceptiviteCmpOp ($1, 'l', $3); } + | expression GEQ expression + { $$ = new ReceptiviteCmpOp ($1, 'g', $3); } + | expression '<' expression + { $$ = new ReceptiviteCmpOp ($1, '<', $3); } + | expression '>' expression + { $$ = new ReceptiviteCmpOp ($1, '>', $3); } +; + +expression: + NUM { $$ = new ExpressionNum ($1); } + | expression '+' expression + { $$ = new ExpressionNumOp ($1, '+', $3); } + | expression '-' expression + { $$ = new ExpressionNumOp ($1, '-', $3); } + | expression '*' expression + { $$ = new ExpressionNumOp ($1, '*', $3); } + | '-' expression %prec NEG + { $$ = new ExpressionNumOp ('n', $2); } ; transition: diff --git a/2003/i/buzz/src/automate/lexer.ll b/2003/i/buzz/src/automate/lexer.ll index 9cf6c93..9f3ebb7 100644 --- a/2003/i/buzz/src/automate/lexer.ll +++ b/2003/i/buzz/src/automate/lexer.ll @@ -9,7 +9,7 @@ using namespace Automate; int yyparse (void); -Grafcet *input_grafcet; +extern Grafcet *input_grafcet; %} @@ -29,7 +29,14 @@ STRING \"[^\n"]\" "print" return PRINT; -[-#+=.<>] return yytext[0]; +"&&" return '&'; +"||" return '|'; +"==" return EQ; +"!=" return NEQ; +"<=" return LEQ; +">=" return GEQ; + +[-#+=*/<>()] return yytext[0]; {FLOAT} { yylval.fl = strtod (yytext, 0); diff --git a/2003/i/buzz/src/automate/receptivite.cc b/2003/i/buzz/src/automate/receptivite.cc index 44accea..c978788 100644 --- a/2003/i/buzz/src/automate/receptivite.cc +++ b/2003/i/buzz/src/automate/receptivite.cc @@ -47,4 +47,33 @@ ReceptiviteBoolOp::test (void) return false; } +// Destructeur. +ReceptiviteCmpOp::~ReceptiviteCmpOp () +{ + if (m_left) delete m_left; + if (m_right) delete m_right; +} + +// Retourne la valeur de la receptivité. +bool +ReceptiviteCmpOp::test (void) +{ + switch (m_op) + { + case '=': + return m_left->val () == m_right->val (); + case 'n': + return m_left->val () != m_right->val (); + case 'l': + return m_left->val () <= m_right->val (); + case 'g': + return m_left->val () >= m_right->val (); + case '<': + return m_left->val () < m_right->val (); + case '>': + return m_left->val () > m_right->val (); + } + return false; +} + } diff --git a/2003/i/buzz/src/automate/receptivite.h b/2003/i/buzz/src/automate/receptivite.h index 04399b2..27a5d3e 100644 --- a/2003/i/buzz/src/automate/receptivite.h +++ b/2003/i/buzz/src/automate/receptivite.h @@ -3,6 +3,7 @@ // receptivite.h // buzz - Programme du robot Efrei Robotique I1-I2 2003 // Copyright (C) 2003 Nicolas Schodet +#include "expression.h" namespace Automate { @@ -42,6 +43,22 @@ namespace Automate // Retourne la valeur de la receptivité. bool test (void); }; + + class ReceptiviteCmpOp : public Receptivite + { + char m_op; + Expression *m_left, *m_right; + public: + // Constructeurs. + ReceptiviteCmpOp (Expression *left, char op, Expression *right) + { m_left = left; m_op = op; m_right = right; } + ReceptiviteCmpOp (char op, Expression *right) + { m_left = 0; m_op = op; m_right = right; } + // Destructeur. + ~ReceptiviteCmpOp (); + // Retourne la valeur de la receptivité. + bool test (void); + }; } #endif // receptivite_h diff --git a/2003/i/buzz/src/automate/test_automate.cc b/2003/i/buzz/src/automate/test_automate.cc new file mode 100644 index 0000000..e80ef42 --- /dev/null +++ b/2003/i/buzz/src/automate/test_automate.cc @@ -0,0 +1,11 @@ +// test_automate.cc +// buzz - Programme du robot Efrei Robotique I1-I2 2003 +// Copyright (C) 2003 Nicolas Schodet +// +#include "grafcet.h" +using namespace Automate; + +int +main (int argc, char **argv) +{ +} -- cgit v1.2.3