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

📄 matchexp.c

📁 gcc-fortran,linux使用fortran的编译软件。很好用的。
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Expression parser.   Copyright (C) 2000, 2001, 2002, 2004, 2005 Free Software Foundation, Inc.   Contributed by Andy VaughtThis file is part of GCC.GCC is free software; you can redistribute it and/or modify it underthe terms of the GNU General Public License as published by the FreeSoftware Foundation; either version 2, or (at your option) any laterversion.GCC is distributed in the hope that it will be useful, but WITHOUT ANYWARRANTY; without even the implied warranty of MERCHANTABILITY orFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public Licensefor more details.You should have received a copy of the GNU General Public Licensealong with GCC; see the file COPYING.  If not, write to the FreeSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA02110-1301, USA.  */#include "config.h"#include "system.h"#include "gfortran.h"#include "arith.h"#include "match.h"static char expression_syntax[] = N_("Syntax error in expression at %C");/* Match a user-defined operator name.  This is a normal name with a   few restrictions.  The error_flag controls whether an error is   raised if 'true' or 'false' are used or not.  */matchgfc_match_defined_op_name (char *result, int error_flag){  static const char * const badops[] = {    "and", "or", "not", "eqv", "neqv", "eq", "ne", "ge", "le", "lt", "gt",      NULL  };  char name[GFC_MAX_SYMBOL_LEN + 1];  locus old_loc;  match m;  int i;  old_loc = gfc_current_locus;  m = gfc_match (" . %n .", name);  if (m != MATCH_YES)    return m;  /* .true. and .false. have interpretations as constants.  Trying to     use these as operators will fail at a later time.  */  if (strcmp (name, "true") == 0 || strcmp (name, "false") == 0)    {      if (error_flag)	goto error;      gfc_current_locus = old_loc;      return MATCH_NO;    }  for (i = 0; badops[i]; i++)    if (strcmp (badops[i], name) == 0)      goto error;  for (i = 0; name[i]; i++)    if (!ISALPHA (name[i]))      {	gfc_error ("Bad character '%c' in OPERATOR name at %C", name[i]);	return MATCH_ERROR;      }  strcpy (result, name);  return MATCH_YES;error:  gfc_error ("The name '%s' cannot be used as a defined operator at %C",	     name);  gfc_current_locus = old_loc;  return MATCH_ERROR;}/* Match a user defined operator.  The symbol found must be an   operator already.  */static matchmatch_defined_operator (gfc_user_op ** result){  char name[GFC_MAX_SYMBOL_LEN + 1];  match m;  m = gfc_match_defined_op_name (name, 0);  if (m != MATCH_YES)    return m;  *result = gfc_get_uop (name);  return MATCH_YES;}/* Check to see if the given operator is next on the input.  If this   is not the case, the parse pointer remains where it was.  */static intnext_operator (gfc_intrinsic_op t){  gfc_intrinsic_op u;  locus old_loc;  old_loc = gfc_current_locus;  if (gfc_match_intrinsic_op (&u) == MATCH_YES && t == u)    return 1;  gfc_current_locus = old_loc;  return 0;}/* Match a primary expression.  */static matchmatch_primary (gfc_expr ** result){  match m;  gfc_expr *e;  locus where;  m = gfc_match_literal_constant (result, 0);  if (m != MATCH_NO)    return m;  m = gfc_match_array_constructor (result);  if (m != MATCH_NO)    return m;  m = gfc_match_rvalue (result);  if (m != MATCH_NO)    return m;  /* Match an expression in parentheses.  */  where = gfc_current_locus;  if (gfc_match_char ('(') != MATCH_YES)    return MATCH_NO;  m = gfc_match_expr (&e);  if (m == MATCH_NO)    goto syntax;  if (m == MATCH_ERROR)    return m;  m = gfc_match_char (')');  if (m == MATCH_NO)    gfc_error ("Expected a right parenthesis in expression at %C");  /* Now we have the expression inside the parentheses, build the     expression pointing to it. By 7.1.7.2 the integrity of     parentheses is only conserved in numerical calculations, so we     don't bother to keep the parentheses otherwise.  */  if(!gfc_numeric_ts(&e->ts))    *result = e;  else    {      gfc_expr *e2 = gfc_get_expr();      e2->expr_type = EXPR_OP;      e2->ts = e->ts;      e2->rank = e->rank;      e2->where = where;      e2->value.op.operator = INTRINSIC_PARENTHESES;      e2->value.op.op1 = e;      e2->value.op.op2 = NULL;      *result = e2;    }  if (m != MATCH_YES)    {      gfc_free_expr (*result);      return MATCH_ERROR;    }  return MATCH_YES;syntax:  gfc_error (expression_syntax);  return MATCH_ERROR;}/* Build an operator expression node.  */static gfc_expr *build_node (gfc_intrinsic_op operator, locus * where,	    gfc_expr * op1, gfc_expr * op2){  gfc_expr *new;  new = gfc_get_expr ();  new->expr_type = EXPR_OP;  new->value.op.operator = operator;  new->where = *where;  new->value.op.op1 = op1;  new->value.op.op2 = op2;  return new;}/* Match a level 1 expression.  */static matchmatch_level_1 (gfc_expr ** result){  gfc_user_op *uop;  gfc_expr *e, *f;  locus where;  match m;  where = gfc_current_locus;  uop = NULL;  m = match_defined_operator (&uop);  if (m == MATCH_ERROR)    return m;  m = match_primary (&e);  if (m != MATCH_YES)    return m;  if (uop == NULL)    *result = e;  else    {      f = build_node (INTRINSIC_USER, &where, e, NULL);      f->value.op.uop = uop;      *result = f;    }  return MATCH_YES;}/* As a GNU extension we support an expanded level-2 expression syntax.   Via this extension we support (arbitrary) nesting of unary plus and   minus operations following unary and binary operators, such as **.   The grammar of section 7.1.1.3 is effectively rewitten as:	R704  mult-operand     is level-1-expr [ power-op ext-mult-operand ]	R704' ext-mult-operand is add-op ext-mult-operand			       or mult-operand	R705  add-operand      is add-operand mult-op ext-mult-operand			       or mult-operand	R705' ext-add-operand  is add-op ext-add-operand			       or add-operand	R706  level-2-expr     is [ level-2-expr ] add-op ext-add-operand			       or add-operand */static match match_ext_mult_operand (gfc_expr ** result);static match match_ext_add_operand (gfc_expr ** result);static intmatch_add_op (void){  if (next_operator (INTRINSIC_MINUS))    return -1;  if (next_operator (INTRINSIC_PLUS))    return 1;  return 0;}static matchmatch_mult_operand (gfc_expr ** result){  gfc_expr *e, *exp, *r;  locus where;  match m;  m = match_level_1 (&e);  if (m != MATCH_YES)    return m;  if (!next_operator (INTRINSIC_POWER))    {      *result = e;      return MATCH_YES;    }  where = gfc_current_locus;  m = match_ext_mult_operand (&exp);  if (m == MATCH_NO)    gfc_error ("Expected exponent in expression at %C");  if (m != MATCH_YES)    {      gfc_free_expr (e);      return MATCH_ERROR;    }  r = gfc_power (e, exp);  if (r == NULL)    {      gfc_free_expr (e);      gfc_free_expr (exp);      return MATCH_ERROR;    }  r->where = where;  *result = r;  return MATCH_YES;}static matchmatch_ext_mult_operand (gfc_expr ** result){  gfc_expr *all, *e;  locus where;  match m;  int i;  where = gfc_current_locus;  i = match_add_op ();  if (i == 0)    return match_mult_operand (result);  if (gfc_notify_std (GFC_STD_GNU, "Extension: Unary operator following"		      " arithmetic operator (use parentheses) at %C")      == FAILURE)    return MATCH_ERROR;  m = match_ext_mult_operand (&e);  if (m != MATCH_YES)    return m;  if (i == -1)    all = gfc_uminus (e);  else    all = gfc_uplus (e);  if (all == NULL)    {      gfc_free_expr (e);      return MATCH_ERROR;    }  all->where = where;  *result = all;  return MATCH_YES;}static matchmatch_add_operand (gfc_expr ** result){  gfc_expr *all, *e, *total;  locus where, old_loc;  match m;  gfc_intrinsic_op i;  m = match_mult_operand (&all);  if (m != MATCH_YES)    return m;  for (;;)    {      /* Build up a string of products or quotients.  */      old_loc = gfc_current_locus;      if (next_operator (INTRINSIC_TIMES))	i = INTRINSIC_TIMES;      else	{	  if (next_operator (INTRINSIC_DIVIDE))	    i = INTRINSIC_DIVIDE;	  else	    break;	}      where = gfc_current_locus;      m = match_ext_mult_operand (&e);      if (m == MATCH_NO)	{	  gfc_current_locus = old_loc;	  break;	}      if (m == MATCH_ERROR)	{	  gfc_free_expr (all);	  return MATCH_ERROR;	}      if (i == INTRINSIC_TIMES)	total = gfc_multiply (all, e);      else	total = gfc_divide (all, e);      if (total == NULL)	{	  gfc_free_expr (all);	  gfc_free_expr (e);	  return MATCH_ERROR;	}      all = total;      all->where = where;    }  *result = all;  return MATCH_YES;}static matchmatch_ext_add_operand (gfc_expr ** result){  gfc_expr *all, *e;  locus where;  match m;  int i;  where = gfc_current_locus;  i = match_add_op ();  if (i == 0)    return match_add_operand (result);  if (gfc_notify_std (GFC_STD_GNU, "Extension: Unary operator following"		      " arithmetic operator (use parentheses) at %C")      == FAILURE)    return MATCH_ERROR;  m = match_ext_add_operand (&e);  if (m != MATCH_YES)    return m;  if (i == -1)    all = gfc_uminus (e);  else    all = gfc_uplus (e);

⌨️ 快捷键说明

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