分享

自制领域特定语言20141110

 guitarhua 2014-11-10
设定温度=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;
}


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多