📄 arithm_eval.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 + -