// ENUM_BODY -> [ ENUN_VALUE {, ENUM_VALUE} [,] ] // ENUM_VALUE -> [ATTRIBUTES] name [equals ENUM_VAL_INITIALIZER] func (p *Parser) parseEnumBody(mojomEnum *mojom.MojomEnum) bool { if !p.OK() { return p.OK() } p.pushChildNode("enumBody") defer p.popNode() // The enum body forms a new scope in which it's enun values are defined. p.pushScope(mojomEnum.InitAsScope(p.currentScope)) defer p.popScope() rbraceFound := false trailingCommaFound := false firstValue := true for attributes := p.parseAttributes(); !rbraceFound; attributes = p.parseAttributes() { if !p.OK() { return false } nextToken := p.peekNextToken("I was parsing an enum body.") var duplicateNameError error = nil switch nextToken.Kind { case lexer.Name: if !firstValue && !trailingCommaFound { message := fmt.Sprintf("Expecting a comma after %s before "+ "the next value %s at %s. ", p.lastConsumed, nextToken, nextToken.LongLocationString()) p.err = &ParseError{ParserErrorCodeUnexpectedToken, message} return false } firstValue = false name := p.readName() p.attachToken() nameToken := p.lastConsumed var valueRef mojom.ValueRef if p.tryMatch(lexer.Equals) { valueRef = p.parseEnumValueInitializer(mojomEnum) } declData := p.DeclData(name, nameToken, attributes) duplicateNameError = mojomEnum.AddEnumValue(declData, valueRef) trailingCommaFound = p.tryMatch(lexer.Comma) case lexer.RBrace: rbraceFound = true if attributes != nil { message := "Enum body ends with extraneouss attributes." p.err = &ParseError{ParserErrorCodeBadAttributeLocation, message} } break case lexer.Comma: break default: p.unexpectedTokenError(nextToken, "either another enum value or }") return false } if p.OK() && duplicateNameError != nil { p.err = &ParseError{ParserErrorCodeDuplicateDeclaration, duplicateNameError.Error()} return false } } return p.OK() }
// ENUM_BODY -> [ ENUN_VALUE {, ENUM_VALUE} [,] ] // ENUM_VALUE -> [ATTRIBUTES] name [equals ENUM_VAL_INITIALIZER] func (p *Parser) parseEnumBody(mojomEnum *mojom.MojomEnum) bool { if !p.OK() { return p.OK() } p.pushChildNode("enumBody") defer p.popNode() // The enum body forms a new scope in which it's enun values are defined. p.pushScope(mojomEnum.InitAsScope(p.currentScope)) defer p.popScope() rbraceFound := false trailingCommaFound := false firstValue := true for attributes := p.parseAttributes(); !rbraceFound; attributes = p.parseAttributes() { if !p.OK() { return false } nextToken := p.peekNextToken("I was parsing an enum body.") dupeMessage := "" switch nextToken.Kind { case lexer.NAME: if !firstValue && !trailingCommaFound { message := fmt.Sprintf("Expecting a comma after %s before "+ "the next value %s at %s. ", p.lastConsumed, nextToken, nextToken.LongLocationString()) p.err = &ParseError{E_UNEXPECTED_TOKEN, message} return false } firstValue = false name := p.readName() p.attachToken() nameToken := p.lastConsumed var valueRef mojom.ValueRef if p.tryMatch(lexer.EQUALS) { valueRef = p.parseEnumValueInitializer(mojomEnum) } dupeMessage = p.duplicateNameMessage( mojomEnum.AddEnumValue(name, valueRef, attributes), nameToken) trailingCommaFound = p.tryMatch(lexer.COMMA) case lexer.RBRACE: rbraceFound = true if attributes != nil { message := "Enum body ends with extranesous attributes." p.err = &ParseError{E_BAD_ATTRIBUTE_LOCATION, message} } break case lexer.COMMA: break default: p.unexpectedTokenError(nextToken, "either another enum value or }") return false } if p.OK() && len(dupeMessage) > 0 { p.err = &ParseError{E_DUPLICATE_DECLARATION, dupeMessage} return false } } if p.OK() { mojomEnum.ComputeEnumValues() } return p.OK() }