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

📄 parser.c

📁 video linux conference
💻 C
📖 第 1 页 / 共 5 页
字号:
/***************************************************************************** * parser.c: ***************************************************************************** * Copyright (C) 2004 VideoLAN * $Id: parser.c 10101 2005-03-02 16:47:31Z robux4 $ * * Authors: Cyril Deguet <asmax@videolan.org> *          code from projectM http://xmms-projectm.sourceforge.net * * 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, USA. *****************************************************************************//* parser.c */#include <stdio.h>#include <string.h>#include <stdlib.h>#include "common.h"#include "fatal.h"#include "splaytree_types.h"#include "splaytree.h"#include "tree_types.h"#include "expr_types.h"#include "eval.h"#include "param_types.h"#include "param.h"#include "func_types.h"#include "func.h"#include "preset_types.h"#include "builtin_funcs.h"#include "per_pixel_eqn_types.h"#include "per_pixel_eqn.h"#include "init_cond_types.h"#include "init_cond.h"#include "per_frame_eqn_types.h"#include "per_frame_eqn.h"#include "parser.h"#include "engine_vars.h"#include "custom_wave_types.h"#include "custom_wave.h"#include "custom_shape_types.h"#include "custom_shape.h"/* Strings that prefix (and denote the type of) equations */#define PER_FRAME_STRING "per_frame_"#define PER_FRAME_STRING_LENGTH 10#define PER_PIXEL_STRING "per_pixel_"#define PER_PIXEL_STRING_LENGTH 10#define PER_FRAME_INIT_STRING "per_frame_init_"#define PER_FRAME_INIT_STRING_LENGTH 15#define WAVECODE_STRING "wavecode_"#define WAVECODE_STRING_LENGTH 9#define WAVE_STRING "wave_"#define WAVE_STRING_LENGTH 5#define PER_POINT_STRING "per_point"#define PER_POINT_STRING_LENGTH 9#define PER_FRAME_STRING_NO_UNDERSCORE "per_frame"#define PER_FRAME_STRING_NO_UNDERSCORE_LENGTH 9#define SHAPECODE_STRING "shapecode_"#define SHAPECODE_STRING_LENGTH 10#define SHAPE_STRING "shape_"#define SHAPE_STRING_LENGTH 6#define SHAPE_INIT_STRING "init"#define SHAPE_INIT_STRING_LENGTH 4#define WAVE_INIT_STRING "init"#define WAVE_INIT_STRING_LENGTH 4/* Stores a line of a file as its being parsed */char string_line_buffer[STRING_LINE_SIZE]; /* The current position of the string line buffer (see above) */int string_line_buffer_index = 0;/* All infix operators (except '=') are prototyped here */extern infix_op_t * infix_add, * infix_minus, * infix_div, * infix_mult,  * infix_or, * infix_and, * infix_mod, * infix_positive, * infix_negative;/* If the parser reads a line with a custom wave, this pointer is set to   the custom wave of concern */custom_wave_t * current_wave = NULL;custom_shape_t * current_shape = NULL;/* Counts the number of lines parsed */unsigned int line_count = 1;int per_frame_eqn_count  = 0;int per_frame_init_eqn_count = 0;typedef enum {  NORMAL_LINE_MODE,  PER_FRAME_LINE_MODE,  PER_PIXEL_LINE_MODE,  INIT_COND_LINE_MODE,  CUSTOM_WAVE_PER_POINT_LINE_MODE,  CUSTOM_WAVE_PER_FRAME_LINE_MODE,  CUSTOM_WAVE_WAVECODE_LINE_MODE,  CUSTOM_SHAPE_SHAPECODE_LINE_MODE,} line_mode_t;line_mode_t line_mode = NORMAL_LINE_MODE;/* Token enumeration type */typedef enum {  tEOL,   /* end of a line, usually a '/n' or '/r' */  tEOF,   /* end of file */  tLPr,   /* ( */  tRPr,   /* ) */  tLBr,   /* [ */  tRBr,   /* ] */  tEq,    /* = */  tPlus,  /* + */  tMinus, /* - */  tMult,  /* * */  tMod,   /* % */  tDiv,   /* / */  tOr,    /* | */  tAnd,   /* & */  tComma, /* , */  tPositive, /* + as a prefix operator */  tNegative, /* - as a prefix operator */  tSemiColon, /* ; */  tStringTooLong, /* special token to indicate an invalid string length */  tStringBufferFilled /* the string buffer for this line is maxed out */} token_t;int get_string_prefix_len(char * string);tree_expr_t * insert_gen_expr(gen_expr_t * gen_expr, tree_expr_t ** root);tree_expr_t * insert_infix_op(infix_op_t * infix_op, tree_expr_t ** root);token_t parseToken(FILE * fs, char * string);gen_expr_t ** parse_prefix_args(FILE * fs, int num_args, struct PRESET_T * preset);gen_expr_t * parse_infix_op(FILE * fs, token_t token, tree_expr_t * tree_expr, struct PRESET_T * preset);gen_expr_t * parse_sign_arg(FILE * fs);int parse_float(FILE * fs, double * float_ptr);int parse_int(FILE * fs, int * int_ptr);int insert_gen_rec(gen_expr_t * gen_expr, tree_expr_t * root);int insert_infix_rec(infix_op_t * infix_op, tree_expr_t * root);gen_expr_t * parse_gen_expr(FILE * fs, tree_expr_t * tree_expr, struct PRESET_T * preset);per_frame_eqn_t * parse_implicit_per_frame_eqn(FILE * fs, char * param_string, int index, struct PRESET_T * preset);init_cond_t * parse_per_frame_init_eqn(FILE * fs, struct PRESET_T * preset, splaytree_t * database);int parse_wavecode_prefix(char * token, int * id, char ** var_string);int parse_wavecode(char * token, FILE * fs, preset_t * preset);int parse_wave_prefix(char * token, int * id, char ** eqn_string);int parse_shapecode(char * eqn_string, FILE * fs, preset_t * preset);int parse_shapecode_prefix(char * token, int * id, char ** var_string);int parse_wave(char * eqn_string, FILE * fs, preset_t * preset);int parse_shape(char * eqn_string, FILE * fs, preset_t * preset);int parse_shape_prefix(char * token, int * id, char ** eqn_string);int update_string_buffer(char * buffer, int * index);int string_to_float(char * string, double * float_ptr);/* Grabs the next token from the file. The second argument points   to the raw string */token_t parseToken(FILE * fs, char * string) {    char c;  int i;    if (string != NULL)    memset(string, 0, MAX_TOKEN_SIZE);    /* Loop until a delimiter is found, or the maximum string size is found */  for (i = 0; i < MAX_TOKEN_SIZE;i++) {    c = fgetc(fs);        /* If the string line buffer is full, quit */    if (string_line_buffer_index == (STRING_LINE_SIZE - 1))      return tStringBufferFilled;        /* Otherwise add this character to the string line buffer */    string_line_buffer[string_line_buffer_index++] = c;    /* Now interpret the character */    switch (c) {          case '+':      return tPlus;     case '-':      return tMinus;    case '%':      return tMod;    case '/':            /* check for line comment here */      if ((c = fgetc(fs)) == '/') {	while(1) {	  c = fgetc(fs);	  if (c == EOF) {	    line_mode = NORMAL_LINE_MODE;	    return tEOF;					  }	  if (c == '\n') {	    line_mode = NORMAL_LINE_MODE;	    return tEOL;	  }	}	      }            /* Otherwise, just a regular division operator */      ungetc(c, fs);      return tDiv;          case '*':      return tMult;    case '|':      return tOr;    case '&':      return tAnd;    case '(':       return tLPr;    case ')':      return tRPr;    case '[':       return tLBr;    case ']':      return tRBr;    case '=':       return tEq;      //    case '\r':      //break;    case '\n':      line_count++;      line_mode = NORMAL_LINE_MODE;      return tEOL;    case ',':      return tComma;    case ';':      return tSemiColon;    case ' ': /* space, skip the character */      i--;      break;    case EOF:      line_count = 1;      line_mode = NORMAL_LINE_MODE;      return tEOF;          default:       if (string != NULL)	string[i] = c;    }       }   /* String reached maximum length, return special token error */   return tStringTooLong;  }/* Parse input in the form of "exp, exp, exp, ...)"    Returns a general expression list */gen_expr_t ** parse_prefix_args(FILE * fs, int num_args, struct PRESET_T * preset) {  int i, j;  gen_expr_t ** expr_list; /* List of arguments to function */  gen_expr_t * gen_expr;    /* Malloc the expression list */  expr_list =  (gen_expr_t**)malloc(sizeof(gen_expr_t*)*num_args);    /* Malloc failed */  if (expr_list == NULL)    return NULL;      i = 0;  while (i < num_args) {    //if (PARSE_DEBUG) printf("parse_prefix_args: parsing argument %d...\n", i+1);    /* Parse the ith expression in the list */    if ((gen_expr = parse_gen_expr(fs, NULL, preset)) == NULL) {      //if (PARSE_DEBUG) printf("parse_prefix_args: failed to get parameter # %d for function (LINE %d)\n", i+1, line_count);      for (j = 0; j < i; j++) 	free_gen_expr(expr_list[j]);      free(expr_list);      return NULL;    }    /* Assign entry in expression list */    expr_list[i++] = gen_expr;  }    //if (PARSE_DEBUG) printf("parse_prefix_args: finished parsing %d arguments (LINE %d)\n", num_args, line_count);	  /* Finally, return the resulting expression list */  return expr_list;  }/* Parses a comment at the top of the file. Stops when left bracket is found */int parse_top_comment(FILE * fs) {  char string[MAX_TOKEN_SIZE];  token_t token;	    /* Process tokens until left bracket is found */  while ((token = parseToken(fs, string)) != tLBr) {    if (token == tEOF)       return PARSE_ERROR;  } /* Done, return success */ return SUCCESS; }	/* Right Bracket is parsed by this function.   puts a new string into name */int parse_preset_name(FILE * fs, char * name) {  token_t token;  if (name == NULL)	return FAILURE;  if ((token = parseToken(fs, name)) != tRBr)    return PARSE_ERROR; 	  //if (PARSE_DEBUG) printf("parse_preset_name: parsed preset (name = \"%s\")\n", name);    return SUCCESS;}/* Parses per pixel equations */int parse_per_pixel_eqn(FILE * fs, preset_t * preset) {  char string[MAX_TOKEN_SIZE];  gen_expr_t * gen_expr;  if (PARSE_DEBUG) printf("parse_per_pixel: per_pixel equation parsing start...(LINE %d)\n", line_count);  if (parseToken(fs, string) != tEq) { /* parse per pixel operator  name */    if (PARSE_DEBUG) printf("parse_per_pixel: equal operator expected after per pixel operator \"%s\", but not found (LINE %d)\n",     			    string, line_count);    return PARSE_ERROR;  }    /* Parse right side of equation as an expression */  if ((gen_expr = parse_gen_expr(fs, NULL, preset)) == NULL) {    if (PARSE_DEBUG) printf("parse_per_pixel: equation evaluated to null? (LINE %d)\n", line_count);    return PARSE_ERROR;  }    /* Add the per pixel equation */  if (add_per_pixel_eqn(string, gen_expr, preset) < 0) {    free_gen_expr(gen_expr);    return PARSE_ERROR;  }  return SUCCESS;}/* Parses an equation line, this function is way too big, should add some helper functions */int parse_line(FILE * fs, struct PRESET_T * preset) {  char eqn_string[MAX_TOKEN_SIZE];  token_t token;  init_cond_t * init_cond;  per_frame_eqn_t * per_frame_eqn;    /* Clear the string line buffer */  memset(string_line_buffer, 0, STRING_LINE_SIZE);  string_line_buffer_index = 0;      switch (token = parseToken(fs, eqn_string)) {        /* Invalid Cases */  case tRBr:  case tLPr:  case tRPr:  case tComma:  case tLBr:  case tPlus:  case tMinus:  case tMod:  case tMult:  case tOr:  case tAnd:  case tDiv:        //    if (PARSE_DEBUG) printf("parse_line: invalid token found at start of line (LINE %d)\n", line_count);    /* Invalid token found, return a parse error */    return PARSE_ERROR;

⌨️ 快捷键说明

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