/**
 * Formats the given ASTNode as an SBML L3 token and appends the result to
 * the given StringBuffer.
 */
void
L3FormulaFormatter_format (StringBuffer_t *sb, const ASTNode_t *node, const L3ParserSettings_t *settings)
{
  if (sb == NULL) return;
  if (L3FormulaFormatter_isFunction(node, settings))
  {
    L3FormulaFormatter_formatFunction(sb, node, settings);
  }
  else if (ASTNode_isOperator(node) || ASTNode_getType(node) == AST_FUNCTION_POWER)
  {
    L3FormulaFormatter_formatOperator(sb, node);
  }
  else if (ASTNode_isLogical(node) || ASTNode_isRelational(node))
  {
    L3FormulaFormatter_formatLogicalRelational(sb, node);
  }
  else if (ASTNode_isRational(node))
  {
    L3FormulaFormatter_formatRational(sb, node, settings);
  }
  else if (ASTNode_isInteger(node))
  {
    L3FormulaFormatter_formatReal(sb, node, settings);
  }
  else if (ASTNode_isReal(node))
  {
    L3FormulaFormatter_formatReal(sb, node, settings);
  }
  else if ( !ASTNode_isUnknown(node) )
  {
    StringBuffer_append(sb, ASTNode_getName(node));
  }
}
/**
 * @return true (non-zero) if the given child ASTNode should be grouped
 * (with parenthesis), false (0) otherwise.
 *
 * A node should be group if it is not an argument to a function and
 * either:
 *
 *   - The parent node has higher precedence than the child, or
 *
 *   - If parent node has equal precedence with the child and the child is
 *     to the right.  In this case, operator associativity and right-most
 *     AST derivation enforce the grouping.
 */
int
L3FormulaFormatter_isGrouped (const ASTNode_t *parent, const ASTNode_t *child, const L3ParserSettings_t *settings)
{
  int pp, cp;
  int pt, ct;
  int group = 0;
  int parentmodulo = 0;


  if (parent != NULL)
  {
    parentmodulo = isTranslatedModulo(parent);
    if (parentmodulo || !L3FormulaFormatter_isFunction(parent, settings))
    {
      group = 1;
      pp = getL3Precedence(parent);
      cp = getL3Precedence(child);

      if (pp < cp)
      {
        group = 0;
      }
      else if (pp == cp)
      {
        if (parentmodulo) {
          //Always group:  x * y % z -> (x * y) % z
          group = 1;
        }
        /**
         * Don't group only if i) child is the first on the list and ii) both parent and
         * child are the same type, or if they
         * should be associative operators (i.e. not AST_MINUS or
         * AST_DIVIDE).  That is, do not group a parent and left child
         * that are either both AST_PLUS or both AST_TIMES operators, nor the logical operators
         * that have the same precedence.
         */
        if (ASTNode_getLeftChild(parent) == child)
        {
          pt = ASTNode_getType(parent);
          ct = ASTNode_getType(child);
          if (ASTNode_isLogical(parent) || ASTNode_isRelational(parent)) {
            group = !(pt == ct);
          }
          else {
            group = !((pt == ct) || (pt == AST_PLUS || pt == AST_TIMES));
          }
        }
      }
      else if (pp==7 && cp==6) {
        //If the parent is 'power' and the child is 'unary not' or 'unary minus', we only need
        // to group if the child is the *left* child:  '(-x)^y', but 'x^-y'.
        if (!(ASTNode_getLeftChild(parent) == child)) { 
          group = 0;
        }
      }
    }
  }

  return group;
}
Example #3
0
/**
 * @return true (non-zero) if the given ASTNode is to formatted as a
 * function.
 */
int
FormulaGraphvizFormatter_isFunction (const ASTNode_t *node)
{
  return
    ASTNode_isFunction  (node) ||
    ASTNode_isLambda    (node) ||
    ASTNode_isLogical   (node) ||
    ASTNode_isRelational(node);
}