sub_attributes ::= '{' (','? attribute)* '}'
| 2711 | |
| 2712 | // sub_attributes ::= '{' (','? attribute)* '}' |
| 2713 | bool HloParserImpl::ParseSubAttributes( |
| 2714 | const absl::flat_hash_map<std::string, AttrConfig>& attrs) { |
| 2715 | LocTy loc = lexer_.GetLoc(); |
| 2716 | if (!ParseToken(TokKind::kLbrace, "expects '{' to start sub attributes")) { |
| 2717 | return false; |
| 2718 | } |
| 2719 | absl::flat_hash_set<std::string> seen_attrs; |
| 2720 | if (lexer_.GetKind() == TokKind::kRbrace) { |
| 2721 | // empty |
| 2722 | } else { |
| 2723 | do { |
| 2724 | EatIfPresent(TokKind::kComma); |
| 2725 | if (!ParseAttributeHelper(attrs, &seen_attrs)) { |
| 2726 | return false; |
| 2727 | } |
| 2728 | } while (lexer_.GetKind() != TokKind::kRbrace); |
| 2729 | } |
| 2730 | // Check that all required attrs were seen. |
| 2731 | for (const auto& attr_it : attrs) { |
| 2732 | if (attr_it.second.required && |
| 2733 | seen_attrs.find(attr_it.first) == seen_attrs.end()) { |
| 2734 | return Error(loc, StrFormat("sub-attribute %s is expected but not seen", |
| 2735 | attr_it.first)); |
| 2736 | } |
| 2737 | } |
| 2738 | return ParseToken(TokKind::kRbrace, "expects '}' to end sub attributes"); |
| 2739 | } |
| 2740 | |
| 2741 | // attributes ::= (',' attribute)* |
| 2742 | bool HloParserImpl::ParseAttributes( |