glpmpl01.c

来自「著名的大规模线性规划求解器源码GLPK.C语言版本,可以修剪.内有详细帮助文档.」· C语言 代码 · 共 1,797 行 · 第 1/5 页

C
1,797
字号
/* glpmpl01.c *//************************************************************************  This code is part of GLPK (GNU Linear Programming Kit).**  Copyright (C) 2000,01,02,03,04,05,06,07,08,2009 Andrew Makhorin,*  Department for Applied Informatics, Moscow Aviation Institute,*  Moscow, Russia. All rights reserved. E-mail: <mao@mai2.rcnet.ru>.**  GLPK is free software: you can redistribute it and/or modify it*  under the terms of the GNU General Public License as published by*  the Free Software Foundation, either version 3 of the License, or*  (at your option) any later version.**  GLPK 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 General Public*  License for more details.**  You should have received a copy of the GNU General Public License*  along with GLPK. If not, see <http://www.gnu.org/licenses/>.***********************************************************************/#define _GLPSTD_STDIO#include "glpmpl.h"#define dmp_get_atomv dmp_get_atom/**********************************************************************//* * *                  PROCESSING MODEL SECTION                  * * *//**********************************************************************//*------------------------------------------------------------------------ enter_context - enter current token into context queue.---- This routine enters the current token into the context queue. */void enter_context(MPL *mpl){     char *image, *s;      if (mpl->token == T_EOF)         image = "_|_";      else if (mpl->token == T_STRING)         image = "'...'";      else         image = mpl->image;      xassert(0 <= mpl->c_ptr && mpl->c_ptr < CONTEXT_SIZE);      mpl->context[mpl->c_ptr++] = ' ';      if (mpl->c_ptr == CONTEXT_SIZE) mpl->c_ptr = 0;      for (s = image; *s != '\0'; s++)      {  mpl->context[mpl->c_ptr++] = *s;         if (mpl->c_ptr == CONTEXT_SIZE) mpl->c_ptr = 0;      }      return;}/*------------------------------------------------------------------------ print_context - print current content of context queue.---- This routine prints current content of the context queue. */void print_context(MPL *mpl){     int c;      while (mpl->c_ptr > 0)      {  mpl->c_ptr--;         c = mpl->context[0];         memmove(mpl->context, mpl->context+1, CONTEXT_SIZE-1);         mpl->context[CONTEXT_SIZE-1] = (char)c;      }      xprintf("Context: %s%.*s\n", mpl->context[0] == ' ' ? "" : "...",         CONTEXT_SIZE, mpl->context);      return;}/*------------------------------------------------------------------------ get_char - scan next character from input text file.---- This routine scans a next ASCII character from the input text file.-- In case of end-of-file, the character is assigned EOF. */void get_char(MPL *mpl){     int c;      if (mpl->c == EOF) goto done;      if (mpl->c == '\n') mpl->line++;      c = read_char(mpl);      if (c == EOF)      {  if (mpl->c == '\n')            mpl->line--;         else            warning(mpl, "final NL missing before end of file");      }      else if (c == '\n')         ;      else if (isspace(c))         c = ' ';      else if (iscntrl(c))      {  enter_context(mpl);         error(mpl, "control character 0x%02X not allowed", c);      }      mpl->c = c;done: return;}/*------------------------------------------------------------------------ append_char - append character to current token.---- This routine appends the current character to the current token and-- then scans a next character. */void append_char(MPL *mpl){     xassert(0 <= mpl->imlen && mpl->imlen <= MAX_LENGTH);      if (mpl->imlen == MAX_LENGTH)      {  switch (mpl->token)         {  case T_NAME:               enter_context(mpl);               error(mpl, "symbolic name %s... too long", mpl->image);            case T_SYMBOL:               enter_context(mpl);               error(mpl, "symbol %s... too long", mpl->image);            case T_NUMBER:               enter_context(mpl);               error(mpl, "numeric literal %s... too long", mpl->image);            case T_STRING:               enter_context(mpl);               error(mpl, "string literal too long");            default:               xassert(mpl != mpl);         }      }      mpl->image[mpl->imlen++] = (char)mpl->c;      mpl->image[mpl->imlen] = '\0';      get_char(mpl);      return;}/*------------------------------------------------------------------------ get_token - scan next token from input text file.---- This routine scans a next token from the input text file using the-- standard finite automation technique. */void get_token(MPL *mpl){     /* save the current token */      mpl->b_token = mpl->token;      mpl->b_imlen = mpl->imlen;      strcpy(mpl->b_image, mpl->image);      mpl->b_value = mpl->value;      /* if the next token is already scanned, make it current */      if (mpl->f_scan)      {  mpl->f_scan = 0;         mpl->token = mpl->f_token;         mpl->imlen = mpl->f_imlen;         strcpy(mpl->image, mpl->f_image);         mpl->value = mpl->f_value;         goto done;      }loop: /* nothing has been scanned so far */      mpl->token = 0;      mpl->imlen = 0;      mpl->image[0] = '\0';      mpl->value = 0.0;      /* skip any uninteresting characters */      while (mpl->c == ' ' || mpl->c == '\n') get_char(mpl);      /* recognize and construct the token */      if (mpl->c == EOF)      {  /* end-of-file reached */         mpl->token = T_EOF;      }      else if (mpl->c == '#')      {  /* comment; skip anything until end-of-line */         while (mpl->c != '\n' && mpl->c != EOF) get_char(mpl);         goto loop;      }      else if (!mpl->flag_d && (isalpha(mpl->c) || mpl->c == '_'))      {  /* symbolic name or reserved keyword */         mpl->token = T_NAME;         while (isalnum(mpl->c) || mpl->c == '_') append_char(mpl);         if (strcmp(mpl->image, "and") == 0)            mpl->token = T_AND;         else if (strcmp(mpl->image, "by") == 0)            mpl->token = T_BY;         else if (strcmp(mpl->image, "cross") == 0)            mpl->token = T_CROSS;         else if (strcmp(mpl->image, "diff") == 0)            mpl->token = T_DIFF;         else if (strcmp(mpl->image, "div") == 0)            mpl->token = T_DIV;         else if (strcmp(mpl->image, "else") == 0)            mpl->token = T_ELSE;         else if (strcmp(mpl->image, "if") == 0)            mpl->token = T_IF;         else if (strcmp(mpl->image, "in") == 0)            mpl->token = T_IN;#if 1 /* 21/VII-2006 */         else if (strcmp(mpl->image, "Infinity") == 0)            mpl->token = T_INFINITY;#endif         else if (strcmp(mpl->image, "inter") == 0)            mpl->token = T_INTER;         else if (strcmp(mpl->image, "less") == 0)            mpl->token = T_LESS;         else if (strcmp(mpl->image, "mod") == 0)            mpl->token = T_MOD;         else if (strcmp(mpl->image, "not") == 0)            mpl->token = T_NOT;         else if (strcmp(mpl->image, "or") == 0)            mpl->token = T_OR;         else if (strcmp(mpl->image, "s") == 0 && mpl->c == '.')         {  mpl->token = T_SPTP;            append_char(mpl);            if (mpl->c != 't')sptp:       {  enter_context(mpl);               error(mpl, "keyword s.t. incomplete");            }            append_char(mpl);            if (mpl->c != '.') goto sptp;            append_char(mpl);         }         else if (strcmp(mpl->image, "symdiff") == 0)            mpl->token = T_SYMDIFF;         else if (strcmp(mpl->image, "then") == 0)            mpl->token = T_THEN;         else if (strcmp(mpl->image, "union") == 0)            mpl->token = T_UNION;         else if (strcmp(mpl->image, "within") == 0)            mpl->token = T_WITHIN;      }      else if (!mpl->flag_d && isdigit(mpl->c))      {  /* numeric literal */         mpl->token = T_NUMBER;         /* scan integer part */         while (isdigit(mpl->c)) append_char(mpl);         /* scan optional fractional part */         if (mpl->c == '.')         {  append_char(mpl);            if (mpl->c == '.')            {  /* hmm, it is not the fractional part, it is dots that                  follow the integer part */               mpl->imlen--;               mpl->image[mpl->imlen] = '\0';               mpl->f_dots = 1;               goto conv;            }frac:       while (isdigit(mpl->c)) append_char(mpl);         }         /* scan optional decimal exponent */         if (mpl->c == 'e' || mpl->c == 'E')         {  append_char(mpl);            if (mpl->c == '+' || mpl->c == '-') append_char(mpl);            if (!isdigit(mpl->c))            {  enter_context(mpl);               error(mpl, "numeric literal %s incomplete", mpl->image);            }            while (isdigit(mpl->c)) append_char(mpl);         }         /* there must be no letter following the numeric literal */         if (isalpha(mpl->c) || mpl->c == '_')         {  enter_context(mpl);            error(mpl, "symbol %s%c... should be enclosed in quotes",               mpl->image, mpl->c);         }conv:    /* convert numeric literal to floating-point */         if (str2num(mpl->image, &mpl->value))err:     {  enter_context(mpl);            error(mpl, "cannot convert numeric literal %s to floating-p"               "oint number", mpl->image);         }      }      else if (mpl->c == '\'' || mpl->c == '"')      {  /* character string */         int quote = mpl->c;         mpl->token = T_STRING;         get_char(mpl);         for (;;)         {  if (mpl->c == '\n' || mpl->c == EOF)            {  enter_context(mpl);               error(mpl, "unexpected end of line; string literal incom"                  "plete");            }            if (mpl->c == quote)            {  get_char(mpl);               if (mpl->c != quote) break;            }            append_char(mpl);         }      }      else if (!mpl->flag_d && mpl->c == '+')         mpl->token = T_PLUS, append_char(mpl);      else if (!mpl->flag_d && mpl->c == '-')         mpl->token = T_MINUS, append_char(mpl);      else if (mpl->c == '*')      {  mpl->token = T_ASTERISK, append_char(mpl);         if (mpl->c == '*')            mpl->token = T_POWER, append_char(mpl);      }      else if (mpl->c == '/')      {  mpl->token = T_SLASH, append_char(mpl);         if (mpl->c == '*')         {  /* comment sequence */            get_char(mpl);            for (;;)            {  if (mpl->c == EOF)               {  /* do not call enter_context at this point */                  error(mpl, "unexpected end of file; comment sequence "                     "incomplete");               }               else if (mpl->c == '*')               {  get_char(mpl);                  if (mpl->c == '/') break;               }               else                  get_char(mpl);            }            get_char(mpl);            goto loop;         }      }      else if (mpl->c == '^')         mpl->token = T_POWER, append_char(mpl);      else if (mpl->c == '<')      {  mpl->token = T_LT, append_char(mpl);         if (mpl->c == '=')            mpl->token = T_LE, append_char(mpl);         else if (mpl->c == '>')            mpl->token = T_NE, append_char(mpl);#if 1 /* 11/II-2008 */         else if (mpl->c == '-')            mpl->token = T_INPUT, append_char(mpl);#endif      }      else if (mpl->c == '=')      {  mpl->token = T_EQ, append_char(mpl);         if (mpl->c == '=') append_char(mpl);      }      else if (mpl->c == '>')      {  mpl->token = T_GT, append_char(mpl);         if (mpl->c == '=')            mpl->token = T_GE, append_char(mpl);#if 1 /* 14/VII-2006 */         else if (mpl->c == '>')            mpl->token = T_APPEND, append_char(mpl);#endif      }      else if (mpl->c == '!')      {  mpl->token = T_NOT, append_char(mpl);         if (mpl->c == '=')            mpl->token = T_NE, append_char(mpl);      }      else if (mpl->c == '&')      {  mpl->token = T_CONCAT, append_char(mpl);         if (mpl->c == '&')            mpl->token = T_AND, append_char(mpl);      }      else if (mpl->c == '|')      {  mpl->token = T_BAR, append_char(mpl);         if (mpl->c == '|')            mpl->token = T_OR, append_char(mpl);      }      else if (!mpl->flag_d && mpl->c == '.')      {  mpl->token = T_POINT, append_char(mpl);         if (mpl->f_dots)         {  /* dots; the first dot was read on the previous call to the

⌨️ 快捷键说明

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