📄 edrateq.c
字号:
#include "copyleft.h"
/*
GEPASI - a simulator of metabolic pathways and other dynamical systems
Copyright (C) 1989, 1992 Pedro Mendes
*/
/*************************************/
/* */
/* GWTOP - Topology */
/* MS-WINDOWS front end */
/* */
/* User-defined kinetics */
/* */
/* QuickC/WIN 1.0 */
/* */
/* (include here compilers that */
/* compiled GWSIM successfully) */
/* */
/*************************************/
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "defines.h" /* symbols also used in .DLG files */
#include "globals.h" /* gepasi's own symbols */
#include "gwtop.h" /* macros, function prototypes, etc. */
#include "gep1.h" /* gepasi's variables */
#include "topgvar.h" /* global variables */
#include "strtbl.h" /* symbols for the string table */
#define YY_NULL 0
int rightprec( unsigned char nu );
int leftprec( unsigned char nu );
unsigned char parse_prim( void );
unsigned char parse_expr( int priority );
int lexic( char *line );
int point_error( char *b );
int yylex( void );
void yyreset( void );
void AddKLst( HWND hControl, int idx );
#pragma alloc_text( CODE1, rightprec, leftprec, parse_expr, parse_prim, lexic, point_error, EdRateq, EdRDet, EdNSub, AddKLst, EdUdkt)
int errfl, errnode;
extern char *yyin;
int rightprec( unsigned char nu )
{
int n;
n = (int) nu;
switch( tr.node[n].item )
{
case 'N':
case 'I': return 6;
case 'F': return 4;
}
switch( tr.node[n].val )
{
case '+':
case '-': return 2;
case '*':
case '/': return 4;
case ')': return 6;
case '^': return 4;
case '(':
case '%': return 0;
}
}
int leftprec( unsigned char nu )
{
int n;
n = (int) nu;
switch( tr.node[n].item )
{
case 'N':
case 'I':
case 'F': return 5;
}
switch( tr.node[n].val )
{
case '+':
case '-': return 1;
case '*':
case '/': return 3;
case '(': return 6;
case '^': return 5;
case ')':
case '%': return 0;
}
}
unsigned char parse_expr( int priority )
{
unsigned char lhs, rhs, op;
lhs = parse_prim();
if( lhs == (unsigned char) 255 ) return (unsigned char) 255;
for( ; tr.node[(int)lex].item=='O' && priority < leftprec( lex ); )
{
op = lex;
rhs = (unsigned char) 255;
++lex;
rhs = parse_expr( rightprec( op ) );
if( rhs == (unsigned char) 255 )
{
if( !errfl )
{
sprintf( errstr, "ERROR - unexpected operator" );
errnode = (int) op;
}
errfl++;
}
else
{
tr.node[(int)op].left = lhs;
tr.node[(int)op].right = rhs;
lhs = op ;
}
}
return lhs;
}
unsigned char parse_prim( void )
{
unsigned char nodep, op, primary;
char t;
nodep = (unsigned char) 255;
if( (tr.node[(int)lex].item=='N') || (tr.node[(int)lex].item=='I') ) t='K';
else t = tr.node[(int)lex].val;
switch( t )
{
case 'K': tr.node[(int)lex].left = tr.node[(int)lex].right = (unsigned char) 255;
nodep = lex;
++lex;
return nodep;
case '(': ++lex;
nodep = parse_expr( 0 );
if( (tr.node[(int)lex].item=='O') && (tr.node[(int)lex].val==')') )
{
++lex;
return nodep;
}
else
{
if( !errfl )
{
sprintf( errstr, "ERROR - right bracket missing" );
errnode = (int) lex;
}
errfl++;
}
case '+':
case '-':
case 'L':
case 'l':
case 'e':
case 'S':
case 'C': op = lex; primary = (unsigned char) 255;
++lex;
primary = parse_prim();
if( primary==(unsigned char)255 )
{
if( !errfl )
{
sprintf( errstr, "ERROR - missing operator" );
errnode = (int) op;
}
errfl++;
}
else
{
nodep = op;
tr.node[(int)op].item = 'F';
tr.node[(int)op].left = primary;
tr.node[(int)op].right = (unsigned char) 255;
return nodep;
}
default: return (unsigned char) 255;
}
if( (tr.node[(int)lex].item=='O') &&
(tr.node[(int)lex].val=='(')
)
{
++lex;
if( (tr.node[(int)lex].item=='O') &&
(tr.node[(int)lex].val==')')
)
{
tr.node[(int)lex].left = nodep;
tr.node[(int)lex].right = (unsigned char) 255;
return lex;
}
else parse_expr( 0 );
}
}
int lexic( char *line )
{
int i;
for( i=1; i<255; i++ )
tr.node[i].left = tr.node[i].right = 0;
tr.node[0].item='%';
tr.node[0].val='%';
tr.node[0].right=(unsigned char) 255;
yyreset();
tr.nnode = 1;
tr.nid = 0;
tr.nnum = 0;
yyin = line;
lex = 1;
for( errfl=0; ; )
{
if( tr.nnode==254 )
{
if( !errfl )
sprintf( errstr, "ERROR - expression too long" );
errfl++;
break;
}
if( yylex() == YY_NULL ) break;
}
if( !errfl ) tr.node[0].left = parse_expr( 0 );
if( (tr.node[tr.node[0].left].item == 'O') &&
(tr.node[tr.node[0].left].val == '(' )
)
{
sprintf( errstr, "ERROR - missing operand" );
errnode = tr.node[0].left - 1;
errfl++;
}
for( i=1; (i<tr.nnode)&&(!errfl); i++ )
{
switch( tr.node[i].item )
{
case 'O': if( ( tr.node[i].left == (unsigned char) 255 ) ||
( tr.node[i].right == (unsigned char) 255 ) ||
( tr.node[i].left == (unsigned char) 0 ) ||
( tr.node[i].right == (unsigned char) 0 )
)
if( (tr.node[i].val!='(') && (tr.node[i].val!=')') )
{
if( !errfl )
{
sprintf( errstr, "ERROR - incorrect number of operands" );
errnode = i;
}
errfl++;
}
if( !errfl )
{
if( (tr.node[tr.node[i].left].item == 'O') &&
(tr.node[tr.node[i].left].val == '(')
)
{
sprintf( errstr, "ERROR - missing operand" );
errnode = tr.node[i].left - 1;
errfl++;
}
if( (tr.node[tr.node[i].right].item == 'O') &&
(tr.node[tr.node[i].right].val == ')')
)
{
sprintf( errstr, "ERROR - missing operand" );
errnode = tr.node[i].right - 1;
errfl++;
}
}
break;
case 'I': if( ( tr.node[i].left == (unsigned char) 0 ) ||
( tr.node[i].right == (unsigned char) 0 )
)
{
if( !errfl )
{
sprintf( errstr, "ERROR - unexpected identifier" );
errnode = i-1;
}
errfl++;
}
break;
case 'N': if( ( tr.node[i].left == (unsigned char) 0 ) ||
( tr.node[i].right == (unsigned char) 0 ) )
{
if( !errfl )
{
sprintf( errstr, "ERROR - unexpected constant" );
errnode = i-1;
}
errfl++;
}
break;
}
}
return errfl;
}
int point_error( char *b )
{
int pt, i;
char astr[64];
pt = 0;
strcpy( b, "" );
for( i=1; i<tr.nnode; i++ )
{
switch( tr.node[i].item )
{
case 'N': sprintf( astr, "%g", tr.constant[(int)tr.node[i].val] ); break;
case 'I': sprintf( astr, "%s", tr.id[(int)tr.node[i].val] ); break;
case 'O': sprintf( astr, "%c", tr.node[i].val ); break;
case 'F': switch( tr.node[i].val )
{
case '+': sprintf( astr, "+" ); break;
case '-': sprintf( astr, "-" ); break;
case 'L': sprintf( astr, "log" ); break;
case 'l': sprintf( astr, "ln" ); break;
case 'e': sprintf( astr, "exp" ); break;
case 'S': sprintf( astr, "sin" ); break;
case 'C': sprintf( astr, "cos" ); break;
}
}
strcat( b, astr );
if( errfl && (errnode==i) ) pt = strlen( b );
}
if( pt==0 ) pt = strlen( b );
return pt;
}
BOOL FAR PASCAL EdRateq( HWND hDlg, WORD message, WORD wParam, LONG lParam )
{
static HWND hEdit;
char buff[2048];
int p;
switch( message )
{
case WM_INITDIALOG:
/* get the handle to the edit control */
hEdit = GetDlgItem( hDlg, IDE_M0 );
/* Limit the length of the equation to 2047 characters */
SendMessage( hEdit, EM_LIMITTEXT, (WORD) 2047, 0 );
/* if eqefl is set this is an edit of an existing kinetic type */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -