设定温度=126 温度=123 预排冷: 开加热 开进气 开排气 等待6 关进气 排冷: 重复3 { 压力=3 等待 压力 < 5 关排气 开进气 压力=111 等待 压力 > 100 关进气 开排气 } 升温: 压力=2 等待 压力 < 5 关排气 开进气 等待 温度>设定温度 -4 预平衡: 重复18次{ 假如 温度>设定温度 -3 {开排气 关进气} 假如 温度<设定温度 -4 {关排气 开进气} 等待1s } 开进气 关排气 温度=127 等待温度>设定温度 +0.5 灭菌: 重复18次{ 假如 温度>设定温度 +1 关加热 假如 温度<设定温度 +0.6 开加热 等待1s } 关进气 开排气 等待压力 < 5 完成:报警 %{ #include "y.tab.h" #include <stdio.h> #include <string.h> #include <stdlib.h> #define SAVE_TOKEN yylval.string = new std::string(yytext, yyleng) #define RETURN_TOKEN1 yylval.token=yytext[0];return yylval.token; #define RETURN_TOKEN2(n) yylval.token =(n);return ACTION; #define RETURN_TOKEN3(n) yylval.token =(n);return VARIABLE; %} %% #\w+\n {} [0-9]+ { SAVE_TOKEN;cout <<"0-9" <<endl;return TOINTEGER; } [0-9]+.[0-9]+ { SAVE_TOKEN;return TOFLOAT;} [a-z]+ { SAVE_TOKEN; return NAME; } \w+: { SAVE_TOKEN;return STAGE_Label; } "=" { RETURN_TOKEN1 } "<" { RETURN_TOKEN1 } ">" { RETURN_TOKEN1 } "+" { cout <<"+" <<endl;RETURN_TOKEN1 } "-" { RETURN_TOKEN1 } "*" { RETURN_TOKEN1 } "/" { RETURN_TOKEN1 } ")" { RETURN_TOKEN1 } "(" { RETURN_TOKEN1 } "{" { RETURN_TOKEN1 } "}" { RETURN_TOKEN1 } "假如" { return IF; } "否则" { return ELSE; } "重复" { return REPEAT; } "等待" { return WAIT; } "开加热" {RETURN_TOKEN2(1) } "关加热" {RETURN_TOKEN2(2) } "开进气" {RETURN_TOKEN2(3) } "关进气" {RETURN_TOKEN2(4) } "开排气" {RETURN_TOKEN2(5) } "关排气" {RETURN_TOKEN2(6) } "开抽气" {RETURN_TOKEN2(7) } "关抽气" {RETURN_TOKEN2(8) } "开回气" {RETURN_TOKEN2(9) } "关回气" {RETURN_TOKEN2(10) } "报警" {RETURN_TOKEN2(11) } "压力" {RETURN_TOKEN3(1) } "温度" {RETURN_TOKEN3(2) } "设定温度" {RETURN_TOKEN3(3) } [\n\t\r\s]+ %% %{ #include <stdio.h> #include "interperter.h" #include "lex.yy.c" #include <vector> #include <string> #define YYERROR_VERBOSE 1 void yyerror(const char* msg); Statement_Block* programBlock; int PSU=11; float TEM; float DTEM; Identifier* psu; Identifier* tem; Identifier* dtem; %} %union { AST *ast; Statement_Block *block; Expression *expr; Statement *stmt; Identifier *ident; std::string *string; int token; } %type <ident> operand %type <expr> exp arithmetic assignic numeric %type <block> stmts block program %type <stmt> stmt control_stmt select_stmt wait_stmt repeat_stmt %type <string> stage_stmt %type <token> operater %token EQ NE IF ELSE REPEAT WAIT <string>NAME <token>ACTION <token>VARIABLE STAGE STAGE_Label <string>TOINTEGER <string>TOFLOAT %left '<' '>' NE EQ %left '+' '-' %left '*' '/' %start program %% program : stmts { programBlock = $1;cout << "yacc::stmts->program "<<endl; } ; stmts : stmt { $$ = new Statement_Block(); $$->stmtlist.push_back($1); #ifdef DEBUG cout << "yacc::stmt->stmts "<<endl; #endif } | stmts stmt { $1->stmtlist.push_back($2); #ifdef DEBUG cout << "yacc::stmts+stmt "<<endl; #endif } ; stmt : exp { $$ = new Expression_Statement(*$1); #ifdef DEBUG cout << "yacc::exp->stmt "<<endl; #endif } |control_stmt |block |ACTION { $$ = new Action($1); #ifdef DEBUG // printf ( "动作 %s\n",yytext ); #endif } ; block : '{' stmts '}' { $$ = $2; } | '{' '}' { $$ = new Statement_Block(); } ; exp: arithmetic { #ifdef DEBUG cout << "yacc::arithmetic->exp "<<endl; #endif } | assignic |'(' exp ')' {$$=$2;} ; numeric: TOINTEGER { $$ = new Integer(atoi($1->c_str())); delete $1; } |TOFLOAT { $$ = new Float(atof($1->c_str())); delete $1; } ; operand: VARIABLE { switch($1) { case 1:if(psu == NULL) psu = new Identifier("压力",PSU); psu->value.type=INT_VALUE ; $$=psu;break; case 2:if(tem == NULL) tem= new Identifier("温度",TEM); tem->value.type=FLOAT_VALUE ; $$=tem; break; case 3:if(dtem == NULL) dtem= new Identifier("设定温度",DTEM); dtem->value.type=FLOAT_VALUE ; $$=dtem; break; } #ifdef DEBUG cout << "yacc:: VARIABLE->operand "<<endl; #endif } |NAME |exp |numeric { #ifdef DEBUG cout << "yacc:: numeric->operand "<<endl; #endif } ; operater:EQ|NE|'<' |'>'| '+' { #ifdef DEBUG cout << "yacc:: + "<<endl; #endif } |'-' |'*' |'/' ; arithmetic: operand operater operand { $$=new Arithmetic($1,$2,$3); #ifdef DEBUG cout << "yacc::arithmetic "<<endl; #endif } ; assignic: operand'=' operand { $$=(Expression*) new Assign($1,$3); #ifdef DEBUG cout << "yacc:: '='->assignic "<<endl; #endif } ; control_stmt: select_stmt | wait_stmt | repeat_stmt ; select_stmt: IF exp block {$$=new condition_Statement($2,$3);} // |IF exp block ELSE block ; wait_stmt:WAIT numeric {$$=new Wait_Statement($2,true);} |WAIT exp {$$=new Wait_Statement($2,false);} ; repeat_stmt:REPEAT numeric block { $$= new Repeat_Statement(*((Integer*)$2),$3); } ; stage_stmt:STAGE_Label {//printf ( "阶段 %s\n",yytext ); $$=new STAGE($1); } %% int yywrap() { return 1; } void yyerror(const char* msg) { printf("Error: %s \n", msg); } #ifndef INTERPERTER_H #define INTERPERTER_H #include <string> #include <vector> #include "global.h" using namespace std; typedef enum { BOOLEAN_VALUE=1, INT_VALUE, FLOAT_VALUE, STRING_VALUE, NULL_VALUE, }value_type; typedef struct { value_type type; union { bool boolean_value; int int_value; float float_value; string* string_value; void* void_pointer; }u; }Eval_Value; class AST { public: string name; int type; virtual ~AST(); virtual Eval_Value eval(); }; class Expression:public AST { public: Eval_Value value; virtual ~Expression(); virtual Eval_Value eval(); }; class Statement:public AST { public: virtual ~Statement(); virtual Eval_Value eval(); }; typedef std::vector <Statement*> StatementList; class Integer:public Expression { public: Integer(int value); virtual Eval_Value eval(); }; class Float:public Expression { public: Float(float value); virtual Eval_Value eval(); }; class Identifier:public Expression { public: Identifier(string name,float &value); Identifier(string name,int &value); virtual Eval_Value eval(); void operator = (Eval_Value value); }; class Assign:public Statement { public: Identifier* variable; Expression* exp; Assign(Identifier* variable,Expression* exp); virtual Eval_Value eval(); }; class Arithmetic:public Expression { public: Expression* operand1; Expression* operand2; int operater; Arithmetic(Expression* operand1,int operater,Expression* operand2); virtual Eval_Value eval(); }; class Action:public Statement { public: int action_num; Action(int num); virtual Eval_Value eval(); }; class STAGE:public Statement { public: int stage_num; string text; STAGE(string text); virtual Eval_Value eval(); }; class Statement_Block:public Statement { public: StatementList stmtlist; Statement_Block(); virtual Eval_Value eval(); }; class Expression_Statement:public Statement { public: Expression& expression; Expression_Statement(Expression& expression); virtual Eval_Value eval(); }; class condition_Statement:public Statement { public: Expression* condition_expression; Statement_Block* block; condition_Statement(Expression* condition_expression,Statement_Block* block); virtual Eval_Value eval(); }; class Repeat_Statement:public Statement { public: int loop_times; Statement_Block* block; Repeat_Statement(Integer loop_times,Statement_Block* block); virtual Eval_Value eval(); }; class Wait_Statement:public Statement { public: int time; Expression* condition; bool iscountdown; //Statement_Block* block; Wait_Statement(Expression* condition,bool iscountdown); virtual Eval_Value eval(); }; #endif // INTERPERTER_H using namespace std; #include <string> #include <iostream> #include <vector> #include <algorithm> #include "interperter.h" #include <unistd.h> #include <typeinfo> #define msleep(t) usleep(1000*t) #define INSERT_PROBE //cout << typeid( this ).name() << endl; extern int PSU; extern float TEM; extern float DTEM; extern Identifier* psu; extern Identifier* tem; extern Identifier* dtem; AST::~AST(){} Eval_Value AST::eval(){} Expression::~Expression(){} Eval_Value Expression::eval(){} Statement::~Statement(){} Eval_Value Statement::eval() { INSERT_PROBE } Integer::Integer(int value) { this->value.type= INT_VALUE; this->value.u.int_value=value; } Eval_Value Integer::eval() { INSERT_PROBE return this->value; } Float::Float(float value) { this->value.type= FLOAT_VALUE; this->value.u.float_value=value; } Eval_Value Float::eval() { INSERT_PROBE return this->value; } Identifier::Identifier(string name,float &value) { this->value.u.float_value=value;} Identifier::Identifier(string name,int &value) {this->value.u.int_value=value; } Eval_Value Identifier::eval(){return value;} void Identifier::operator = (Eval_Value value) { if(this->value.type==INT_VALUE && value.type==INT_VALUE) { this->value.u.int_value=value.u.int_value; #ifdef DEBUG cout <<"赋值语句" <<this->value.u.int_value << "<="<< value.u.int_value <<endl; #endif } else if(this->value.type==INT_VALUE && value.type==FLOAT_VALUE) { this->value.u.int_value=value.u.float_value; } else if(this->value.type==FLOAT_VALUE && value.type==INT_VALUE) { this->value.u.float_value=value.u.int_value; } else if(this->value.type==FLOAT_VALUE && value.type==FLOAT_VALUE) { this->value.u.float_value=value.u.float_value; } } Assign::Assign(Identifier* variable,Expression* exp):variable(variable),exp(exp){} Eval_Value Assign::eval() { INSERT_PROBE variable->operator =(exp->eval()); if(variable==psu) { PSU= variable->eval().u.int_value; #ifdef DEBUG cout <<"PSU=" << PSU <<endl; #endif } else if(variable==tem) { TEM= variable->eval().u.float_value; #ifdef DEBUG cout <<"TEM=" << TEM <<endl; #endif } else if(variable==dtem) { DTEM= variable->eval().u.float_value; #ifdef DEBUG cout <<"DTEM=" << DTEM <<endl; #endif } } Arithmetic::Arithmetic(Expression* operand1,int operater,Expression* operand2) :operand1(operand1),operand2(operand2),operater(operater) {} Eval_Value Arithmetic:: eval() { bool isGT=false; INSERT_PROBE if(operand1->eval().type==INT_VALUE && operand2->eval().type==INT_VALUE ) { switch(operater) { case '+': value.u.int_value=operand1->eval().u.int_value + operand2->eval().u.int_value; value.type=INT_VALUE; break; case '-': value.u.int_value=operand1->eval().u.int_value - operand2->eval().u.int_value; value.type=INT_VALUE; break; LT_LABEL: case '<': value.u.boolean_value=operand1->eval().u.int_value < operand2->eval().u.int_value; value.type=BOOLEAN_VALUE; if(isGT) {value.u.boolean_value=!value.u.boolean_value;isGT=false;} break; case '>': isGT=true; goto LT_LABEL; break; default: goto error; break; } } else if(operand1->eval().type==INT_VALUE && operand2->eval().type==FLOAT_VALUE ) { switch(operater) { case '+': value.u.float_value=operand1->eval().u.int_value + operand2->eval().u.float_value; value.type=FLOAT_VALUE; break; case '-': value.u.float_value=operand1->eval().u.int_value - operand2->eval().u.float_value; value.type=FLOAT_VALUE; break; case '<': value.u.boolean_value=operand1->eval().u.int_value < operand2->eval().u.float_value; value.type=BOOLEAN_VALUE; break; case '>': value.u.boolean_value=operand1->eval().u.int_value > operand2->eval().u.float_value; value.type=BOOLEAN_VALUE; break; default: goto error; break; } } else if(operand1->eval().type==FLOAT_VALUE && operand2->eval().type==INT_VALUE ) { switch(operater) { case '+': value.u.float_value=operand1->eval().u.float_value + operand2->eval().u.int_value; value.type=FLOAT_VALUE; break; case '-': value.u.float_value=operand1->eval().u.float_value - operand2->eval().u.int_value; value.type=FLOAT_VALUE; break; case '<': value.u.boolean_value=operand1->eval().u.float_value < operand2->eval().u.int_value; value.type=BOOLEAN_VALUE; break; case '>': value.u.boolean_value=operand1->eval().u.float_value > operand2->eval().u.int_value; value.type=BOOLEAN_VALUE; break; default: goto error; break; } } else if(operand1->eval().type==FLOAT_VALUE && operand2->eval().type==FLOAT_VALUE ) { switch(operater) { case '+': value.u.float_value=operand1->eval().u.float_value + operand2->eval().u.float_value; value.type=FLOAT_VALUE; break; case '-': value.u.float_value=operand1->eval().u.float_value - operand2->eval().u.float_value; value.type=FLOAT_VALUE; break; case '<': value.u.boolean_value=operand1->eval().u.float_value < operand2->eval().u.float_value; value.type=BOOLEAN_VALUE; break; case '>': value.u.boolean_value=operand1->eval().u.float_value > operand2->eval().u.float_value; value.type=BOOLEAN_VALUE; break; default: goto error; break; } } return value; error:cout << "非法的操作符 %d\n"<< operater; } Action::Action(int num):action_num(num){} Eval_Value Action::eval() { cout<< "action"<< action_num<< endl; } STAGE::STAGE(string text):text(text){} Eval_Value STAGE::eval(){ cout<< text << endl;} void eveval(Statement* elem ) { elem->eval(); } Expression_Statement::Expression_Statement(Expression& expression) :expression(expression) { } Eval_Value Expression_Statement::eval(){ return expression.eval();} Statement_Block::Statement_Block(){} Eval_Value Statement_Block::eval() { cout <<"语法树构建完毕,开始执行程序!\n\n\n" <<endl; for_each( stmtlist.begin(),stmtlist.end(), eveval ); } condition_Statement::condition_Statement(Expression* condition_expression,Statement_Block* block): condition_expression(condition_expression),block(block){} Eval_Value condition_Statement::eval() { if(condition_expression->eval().u.boolean_value ) {block->eval();INSERT_PROBE} } Wait_Statement::Wait_Statement(Expression* condition,bool iscountdown): condition(condition),iscountdown(iscountdown) {if(iscountdown) this->time= condition->eval().u.int_value;} Eval_Value Wait_Statement::eval() { if(iscountdown) { while(time-- > 0 ) { sleep(1);cout <<"等待" << time <<endl;}} else { while(!condition->eval().u.boolean_value) {msleep(500); cout <<"等待条件" <<endl;}} } Repeat_Statement::Repeat_Statement(Integer loop_times,Statement_Block* block): loop_times(loop_times.eval().u.int_value),block(block){} Eval_Value Repeat_Statement::eval() { while(loop_times--) {cout <<"重复" << loop_times <<endl; block->eval();} } #include <iostream> #include "yac.tab.cpp" #include "global.h" using namespace std; int main(int argc, char *argv[]) { // cout << "Hello World!" << endl; yyparse(); programBlock->eval(); return 0; } |
|