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

📄 t_parse.c

📁 The source code of Doom legacy for windows
💻 C
📖 第 1 页 / 共 2 页
字号:
// Emacs style mode select -*- C++ -*-//----------------------------------------------------------------------------//// $Id: t_parse.c,v 1.4 2001/05/03 21:22:25 hurdler Exp $//// Copyright(C) 2000 Simon Howard//// This program 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 2 of the License, or// (at your option) any later version.// // This program 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 this program; if not, write to the Free Software// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA//// $Log: t_parse.c,v $// Revision 1.4  2001/05/03 21:22:25  hurdler// remove some warnings//// Revision 1.3  2000/11/04 16:23:44  bpereira// no message//// Revision 1.2  2000/11/03 11:48:40  hurdler// Fix compiling problem under win32 with 3D-Floors and FragglScript (to verify!)//// Revision 1.1  2000/11/02 17:57:28  stroggonmeth// FraggleScript files...//////--------------------------------------------------------------------------//// Parsing.//// Takes lines of code, or groups of lines and runs them.// The main core of FraggleScript//// By Simon Howard////----------------------------------------------------------------------------/* includes ************************/#include <stdio.h>#include <stdarg.h>#include "command.h"#include "doomtype.h"#include "doomdef.h"#include "doomstat.h"#include "s_sound.h"#include "w_wad.h"#include "z_zone.h"#include "t_parse.h"#include "t_prepro.h"#include "t_spec.h"#include "t_oper.h"#include "t_vari.h"#include "t_func.h"void parse_script();void parse_data(char *data, char *end);svalue_t evaluate_expression(int start, int stop);mobj_t *trigger_obj;            // object which triggered scriptchar *tokens[T_MAXTOKENS];tokentype_t tokentype[T_MAXTOKENS];int num_tokens = 0;int script_debug = false;script_t *current_script;       // the current scriptsvalue_t nullvar = { svt_int,  {0} };      // null var for empty returnint killscript;         // when set to true, stop the script quicklysection_t *prev_section;       // the section from the previous statement/************ Divide into tokens **************/char *linestart;        // start of linechar *rover;            // current point reached in script        // inline for speed#define isnum(c) ( ((c)>='0' && (c)<='9') || (c)=='.' )        // isop: is an 'operator' character, eg '=', '%'#define isop(c)   !( ( (c)<='Z' && (c)>='A') || ( (c)<='z' && (c)>='a') || \                     ( (c)<='9' && (c)>='0') || ( (c)=='_') )        // for simplicity:#define tt (tokentype[num_tokens-1])#define tok (tokens[num_tokens-1])section_t *current_section; // the section (if any) found in parsing the lineint bracetype;              // bracket_open or bracket_closestatic void add_char(char c);// next_token: end this token, go onto the nextstatic void next_token(){  if(tok[0] || tt==string)    {      num_tokens++;      tokens[num_tokens-1] = tokens[num_tokens-2]        + strlen(tokens[num_tokens-2]) + 1;      tok[0] = 0;    }    // get to the next token, ignoring spaces, newlines,  // useless chars, comments etc    while(1)    {      // empty whitespace      if(*rover && (*rover==' ' || *rover<32))        {          while((*rover==' ' || *rover<32) && *rover) rover++;        }      // end-of-script?      if(!*rover)        {          if(tokens[0][0])            {              CONS_Printf("%s %i %i\n", tokens[0],                       rover-current_script->data, current_script->len);              // line contains text, but no semicolon: an error              script_error("missing ';'\n");            }          // empty line, end of command-list          return;        }      // 11/8 comments moved to new preprocessor            break;  // otherwise    }  if(num_tokens>1 && *rover == '(' && tokentype[num_tokens-2] == name)    tokentype[num_tokens-2] = function;    if(*rover == '{' || *rover == '}')    {      if(*rover == '{')        {          bracetype = bracket_open;          current_section = find_section_start(rover);        }      else            // closing brace        {          bracetype = bracket_close;          current_section = find_section_end(rover);        }      if(!current_section)        {          script_error("section not found!\n");          return;        }    }  else if(*rover == ':')  // label    {      // ignore the label : reset      num_tokens = 1;      tokens[0][0] = 0; tt = name;      rover++;        // ignore    }  else if(*rover == '\"')    {      tt = string;      if(tokentype[num_tokens-2] == string)        num_tokens--;   // join strings      rover++;    }  else    {      tt = isop(*rover) ? operator :        isnum(*rover) ? number : name;    }}// return an escape sequence (prefixed by a '\')// do not use all C escape sequencesstatic char escape_sequence(char c){  if(c == 'n') return '\n';  if(c == '\\') return '\\';  if(c == '"') return '"';  if(c == '?') return '?';  if(c == 'a') return '\a';         // alert beep  if(c == 't') return '\t';         //tab//  if(c == 'z') return *FC_TRANS;    // translucent toggle    // font colours  if(c >= '0' && c <= '9') return 128 + (c-'0');    return c;}// add_char: add one character to the current tokenstatic void add_char(char c){  char *out = tok + strlen(tok);    *out++ = c;  *out = 0;}// get_tokens.// Take a string, break it into tokens.// individual tokens are stored inside the tokens[] array// tokentype is also used to hold the type for each token://   name: a piece of text which starts with an alphabet letter.//         probably a variable name. Some are converted into//         function types later on in find_brackets//   number: a number. like '12' or '1337'//   operator: an operator such as '&&' or '+'. All FraggleScript//             operators are either one character, or two character//             (if 2 character, 2 of the same char or ending in '=')//   string: a text string that was enclosed in quote "" marks in//           the original text//   unset: shouldn't ever end up being set really.//   function: a function name (found in second stage parsing)void get_tokens(char *s){  rover = s;  num_tokens = 1;  tokens[0][0] = 0; tt = name;    current_section = NULL;   // default to no section found    next_token();  linestart = rover;      // save the start    if(*rover)    while(1)      {        if(killscript) return;        if(current_section)          {            // a { or } section brace has been found            break;        // stop parsing now          }        else if(tt != string)          {            if(*rover == ';') break;     // check for end of command ';'          }                switch(tt)          {          case unset:          case string:            while(*rover != '\"')     // dedicated loop for speed              {                if(*rover == '\\')       // escape sequences                  {                    rover++;                    add_char(escape_sequence(*rover));                  }                else                  add_char(*rover);                rover++;              }            rover++;            next_token();       // end of this token            continue;                      case operator:            // all 2-character operators either end in '=' or            // are 2 of the same character            // do not allow 2-characters for brackets '(' ')'            // which are still being considered as operators                        // operators are only 2-char max, do not need            // a seperate loop                        if((*tok && *rover != '=' && *rover!=*tok) ||               *tok == '(' || *tok == ')')              {                // end of operator                next_token();                continue;              }            add_char(*rover);            break;                      case number:            // add while number chars are read            while(isnum(*rover))       // dedicated loop              add_char(*rover++);            next_token();            continue;          case name:            // add the chars            while(!isop(*rover))        // dedicated loop              add_char(*rover++);            next_token();            continue;                      default: break; // shut up compiler          }        rover++;      }    // check for empty last token  if(!tok[0])    {      num_tokens = num_tokens - 1;    }    rover++;}void print_tokens()     // DEBUG{  int i;  for(i=0; i<num_tokens; i++)    {      CONS_Printf("\n'%s' \t\t --", tokens[i]);      switch(tokentype[i])        {        case string: CONS_Printf("string");        break;        case operator: CONS_Printf("operator");    break;        case name: CONS_Printf("name");            break;        case number: CONS_Printf("number");        break;        case unset : CONS_Printf("duh");           break;        case function: CONS_Printf("function name"); break;        }    }  CONS_Printf("\n");  if(current_section)    CONS_Printf("current section: offset %i\n",             (int)(current_section->start-current_script->data) );}// run_script//// the function called by t_script.cvoid run_script(script_t *script){  // set current script  current_script = script;    // start at the beginning of the script  rover = current_script->data;  current_script->lastiftrue = false;    parse_script(); // run it}void continue_script(script_t *script, char *continue_point){  current_script = script;    // continue from place specified  rover = continue_point;    parse_script(); // run }void parse_script(){  // check for valid rover  if(rover < current_script->data ||      rover > current_script->data+current_script->len)    {      script_error("parse_script: trying to continue from point"                   "outside script!\n");      return;    }    trigger_obj = current_script->trigger;  // set trigger    parse_data(current_script->data,             current_script->data+current_script->len);    // dont clear global vars!  if(current_script->scriptnum != -1)    clear_variables(current_script);        // free variables  current_script->lastiftrue = false;}

⌨️ 快捷键说明

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