⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 arithm_eval.c

📁 电路仿真程序 Classic Ladder is coded 100% in C.It can be used for educational purposes or anything you wan
💻 C
字号:
/* Classic Ladder Project *//* Copyright (C) 2001 Marc Le Douarain *//* mavati@club-internet.fr *//* http://www.multimania.com/mavati/classicladder *//* October 2001 *//* Last update : 26 January 2002 *//* ------------------------------- *//* Arithmetic expression evaluator *//* ------------------------------- *//* This library is free software; you can redistribute it and/or *//* modify it under the terms of the GNU Lesser General Public *//* License as published by the Free Software Foundation; either *//* version 2.1 of the License, or (at your option) any later version. *//* This library is distributed in the hope that it will be useful, *//* but WITHOUT ANY WARRANTY; without even the implied warranty of *//* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU *//* Lesser General Public License for more details. *//* You should have received a copy of the GNU Lesser General Public *//* License along with this library; if not, write to the Free Software *//* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <math.h>#include "classicladder.h"#include "global.h"#include "vars_access.h"#include "arithm_eval.h"#ifdef __RTL__#include <rtl_printf.h>#endifchar * Expr;char * ErrorDesc;char * VerifyErrorDesc;int UnderVerify;/* for RTLinux module */#ifdef __RTL__int atoi(const char *p){    int n=0;    while(*p>='0' && *p<='9')        n = n*10 + *p++-'0';    return n;}#endifint pow_int(int a,int b){    int x;    for (x=1;x<=b;x++)        a = a*a;    return a;}void SyntaxError(void){    if (UnderVerify)        VerifyErrorDesc = ErrorDesc;    else        debug_printf("Syntax error : '%s' , at %s !!!!!\n",ErrorDesc,Expr);}arithmtype Constant(void){    arithmtype Res = 0;    while(*Expr>='0' && *Expr<='9')    {        Res = 10*Res + (*Expr-'0');        Expr++;    }    return Res;}/* return TRUE if okay */int IdentifyVariable(char *StartExpr,int * ResType,int * ResOffset){    int VarType,VarOffset;    char * SearchSep = StartExpr;    StartExpr++;    do    {        SearchSep++;    }    while( (*SearchSep!='/') && (*SearchSep!='\0') );    if (*SearchSep=='/')    {        VarType = atoi(StartExpr);        SearchSep++;        StartExpr = SearchSep;           /* ???????? */        do        {            StartExpr++;        }        while( (*StartExpr!='@') && (*StartExpr!='\0') );        if (*StartExpr=='@')        {            VarOffset = atoi(SearchSep);            *ResType = VarType;            *ResOffset = VarOffset;            return TRUE;        }        else        {            ErrorDesc = "Bad var coding 1, should be @xx/yy@";            SyntaxError();        }    }    else    {        ErrorDesc = "Bad var coding 2, should be @xx/yy@";        SyntaxError();    }    return FALSE;}arithmtype Variable(void){    int VarType,VarOffset;    if (IdentifyVariable(Expr,&VarType,&VarOffset))    {        /* flush var found */        Expr++;        do        {            Expr++;        }        while( (*Expr!='@') && (*Expr!='\0') );        Expr++;        /* return var value */        return (arithmtype)ReadVar(VarType,VarOffset);    }    else    {        return 0;    }}arithmtype Term(void){    if (*Expr=='(')    {        arithmtype Res;        Expr++;        Res = AddSub();        if (*Expr!=')')        {            ErrorDesc = "Missing parenthesis";            SyntaxError();        }        Expr++;        return Res;    }    else    if (*Expr>='0' && *Expr<='9')        return Constant();    else    if (*Expr=='@')    {        return Variable();    }    else    {        ErrorDesc = "Unknown term";        SyntaxError();    }    return 0;}arithmtype Pow(void){    arithmtype Q,Res = Term();    while(*Expr=='^')    {        Expr++;        Q = Pow();        Res = pow_int(Res,Q);    }    return Res;}arithmtype MulDivMod(void){    arithmtype Res = Pow();    while(1)    {        if (*Expr=='*')        {            Expr++;            Res = Res * Pow();        }        else        if (*Expr=='/')        {            Expr++;            Res = Res / Pow();        }        else        if (*Expr=='%')        {            Expr++;            Res = fmod(Res,Pow());        }        else        {            break;        }    }    return Res;}arithmtype AddSub(void){    arithmtype Res = MulDivMod();    while(1)    {        if (*Expr=='+')        {            Expr++;            Res = Res + MulDivMod();        }        else        if (*Expr=='-')        {            Expr++;            Res = Res - MulDivMod();        }        else        {            break;        }    }    return Res;}arithmtype EvalExpression(char * ExprString){    arithmtype Res;    Expr = ExprString;    Res = AddSub();    return Res;}/* Result of the comparison of 2 arithmetics expressions : *//* Expr1 ... Expr2 where ... can be : < , > , = , <= , >= , <> */int EvalCompare(char * CompareString){    char * FirstExpr,* SecondExpr = NULL;    char StrCopy[ARITHM_EXPR_SIZE+1]; /* used for putting null char after first expr */    char * SearchSep;    char * CutFirst;    int Found = FALSE;    int BoolRes = 0;    /* null expression ? */    if (*CompareString=='\0')        return BoolRes;    strcpy(StrCopy,CompareString);    /* search for '>' or '<' or '=' or '>=' or '<=' */    CutFirst = FirstExpr = StrCopy;    SearchSep = CompareString;    do    {        if ( (*SearchSep=='>') || (*SearchSep=='<') || (*SearchSep=='=') )        {            Found = TRUE;            *CutFirst = '\0';            CutFirst++;            SecondExpr = CutFirst;            /* 2 chars if '>=' or '<=' or '<>' */            if ( *CutFirst=='=' || *CutFirst=='>')            {                CutFirst++;                SecondExpr = CutFirst;            }        }        else        {            SearchSep++;            CutFirst++;        }    }    while (*SearchSep!='\0' && !Found);    if (Found)    {        arithmtype EvalFirst,EvalSecond;//printf("EvalCompare FirstString=%s , SecondString=%s\n",FirstExpr,SecondExpr);        EvalFirst = EvalExpression(FirstExpr);        EvalSecond = EvalExpression(SecondExpr);//printf("EvalCompare ResultFirst=%d , ResultSecond=%d\n",EvalFirst,EvalSecond);        /* verify if compare is true */        if ( *SearchSep=='>' && EvalFirst>EvalSecond )            BoolRes = 1;        if ( *SearchSep=='<' && *(SearchSep+1)!='>' && EvalFirst<EvalSecond )            BoolRes = 1;        if ( *SearchSep=='<' && *(SearchSep+1)=='>' && EvalFirst!=EvalSecond )            BoolRes = 1;        if ( (*SearchSep=='=' || *(SearchSep+1)=='=') && EvalFirst==EvalSecond )            BoolRes = 1;    }    else    {        ErrorDesc = "Missing < or > or = or ... to make comparison";        SyntaxError();    }//printf("Eval FinalBoolResult = %d\n",BoolRes);    return BoolRes;}/* Calc the new value of a variable from an arithmetic expression : *//* VarDest := ArithmExpr */void MakeCalc(char * CalcString,int VerifyMode){    char StrCopy[ARITHM_EXPR_SIZE+1]; /* used for putting null char after first expr */    int VarType,VarOffset;    int  Found = FALSE;    /* null expression ? */    if (*CalcString=='\0')        return;    strcpy(StrCopy,CalcString);    Expr = StrCopy;    if (IdentifyVariable(Expr,&VarType,&VarOffset))    {        /* flush var found */        Expr++;        do        {            Expr++;        }        while( (*Expr!='@') && (*Expr!='\0') );        Expr++;        /* verify if there is the '=' or ':=' */        do        {            if (*Expr==':')                Expr++;            if (*Expr=='=')            {                Found = TRUE;                Expr++;            }            if (*Expr==' ')                Expr++;        }        while( !Found && *Expr!='\0' );        while( *Expr==' ')            Expr++;        if (Found)        {            arithmtype EvalExpr;//printf("Calc - Eval String=%s\n",Expr);            EvalExpr = EvalExpression(Expr);//printf("Calc - Result=%d\n",EvalExpr);            if (!VerifyMode)                WriteVar(VarType,VarOffset,(int)EvalExpr);        }        else        {            ErrorDesc = "Missing := to make operate";            SyntaxError();        }    }}/* Used one time after user input to verify syntax only *//* return NULL if ok, else pointer on error description */char * VerifySyntaxForEvalCompare(char * StringToVerify){    UnderVerify = TRUE;    VerifyErrorDesc = NULL;    EvalCompare(StringToVerify);    UnderVerify = FALSE;    return VerifyErrorDesc;}/* Used one time after user input to verify syntax only *//* return NULL if ok, else pointer on error description */char * VerifySyntaxForMakeCalc(char * StringToVerify){    UnderVerify = TRUE;    VerifyErrorDesc = NULL;    MakeCalc(StringToVerify,TRUE /* verify mode */);    UnderVerify = FALSE;    return VerifyErrorDesc;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -