Improving out-of-distribution generalization in graphs via hierarchical semantic environments