def nestedExpr(opener='(', closer=')', content=None, ignoreExpr=quotedString):
 if (opener == closer):
  raise ValueError('opening and closing strings cannot be the same')
 if (content is None):
  if (isinstance(opener, __BASE_STRING__) and isinstance(closer, __BASE_STRING__)):
   content = (empty + CharsNotIn(((opener + closer) + ParserElement.DEFAULT_WHITE_CHARS)).setParseAction((lambda t: t[0].strip())))
  else:
   raise ValueError('opening and closing arguments must be strings if no content expression is given')
 ret = Forward()
 if (ignoreExpr is not None):
  (ret << Group(((Suppress(opener) + ZeroOrMore(((ignoreExpr | ret) | content))) + Suppress(closer))))
 else:
  (ret << Group(((Suppress(opener) + ZeroOrMore((ret | content))) + Suppress(closer))))
 return ret

def nestedExpr ( opener = '(' , closer = ')' , content = None , ignoreExpr = quotedString ) : if ( opener == closer ) : raise ValueError ( 'opening and closing strings cannot be the same' ) if ( content is None ) : if ( isinstance ( opener , __BASE_STRING__ ) and isinstance ( closer , __BASE_STRING__ ) ) : content = ( empty + CharsNotIn ( ( ( opener + closer ) + ParserElement . DEFAULT_WHITE_CHARS ) ) . setParseAction ( ( lambda t : t [ 0 ] . strip ( ) ) ) ) else : raise ValueError ( 'opening and closing arguments must be strings if no content expression is given' ) ret = Forward ( ) if ( ignoreExpr is not None ) : ( ret << Group ( ( ( Suppress ( opener ) + ZeroOrMore ( ( ( ignoreExpr | ret ) | content ) ) ) + Suppress ( closer ) ) ) ) else : ( ret << Group ( ( ( Suppress ( opener ) + ZeroOrMore ( ( ret | content ) ) ) + Suppress ( closer ) ) ) ) return ret
helper method for defining nested lists enclosed in opening and closing delimiters ("" are the default) .