github.com/jordan-bonecutter/can-go@v0.0.0-20230901155856-d83995b18e50/pkg/dbc/def.go (about)

     1  package dbc
     2  
     3  import (
     4  	"strconv"
     5  	"text/scanner"
     6  )
     7  
     8  // Def represents a single definition within a DBC file.
     9  type Def interface {
    10  	// Position of the definition.
    11  	Position() scanner.Position
    12  
    13  	// parseFrom parses the definition from a parser.
    14  	parseFrom(*Parser)
    15  }
    16  
    17  // VersionDef defines the version of a DBC file.
    18  type VersionDef struct {
    19  	Pos     scanner.Position
    20  	Version string
    21  }
    22  
    23  var _ Def = &VersionDef{}
    24  
    25  func (d *VersionDef) parseFrom(p *Parser) {
    26  	d.Pos = p.keyword(KeywordVersion).pos
    27  	d.Version = p.string()
    28  }
    29  
    30  // Position returns the position of the definition.
    31  func (d *VersionDef) Position() scanner.Position {
    32  	return d.Pos
    33  }
    34  
    35  // NewSymbolsDef defines new symbol entries in a DBC file.
    36  type NewSymbolsDef struct {
    37  	Pos     scanner.Position
    38  	Symbols []Keyword
    39  }
    40  
    41  var _ Def = &NewSymbolsDef{}
    42  
    43  func (d *NewSymbolsDef) parseFrom(p *Parser) {
    44  	p.useWhitespace(significantTab)
    45  	defer p.useWhitespace(defaultWhitespace)
    46  	d.Pos = p.keyword(KeywordNewSymbols).pos
    47  	p.token(':')
    48  	for p.peekToken().typ == '\t' {
    49  		p.token('\t')
    50  		d.Symbols = append(d.Symbols, Keyword(p.identifier()))
    51  	}
    52  }
    53  
    54  // Position returns the position of the definition.
    55  func (d *NewSymbolsDef) Position() scanner.Position {
    56  	return d.Pos
    57  }
    58  
    59  // BitTimingDef defines the baud rate and the settings of the BTR registers of a CAN network.
    60  //
    61  // This definition is obsolete and not used anymore.
    62  type BitTimingDef struct {
    63  	Pos      scanner.Position
    64  	BaudRate uint64
    65  	BTR1     uint64
    66  	BTR2     uint64
    67  }
    68  
    69  var _ Def = &BitTimingDef{}
    70  
    71  func (d *BitTimingDef) parseFrom(p *Parser) {
    72  	d.Pos = p.keyword(KeywordBitTiming).pos
    73  	p.token(':')
    74  	d.BaudRate = p.optionalUint()
    75  	if p.peekToken().typ == ':' {
    76  		d.BTR1 = p.optionalUint()
    77  	}
    78  	if p.peekToken().typ == ',' {
    79  		d.BTR2 = p.optionalUint()
    80  	}
    81  }
    82  
    83  // Position returns the position of the definition.
    84  func (d *BitTimingDef) Position() scanner.Position {
    85  	return d.Pos
    86  }
    87  
    88  // NodesDef defines the names of all nodes participating in the network.
    89  //
    90  // This definition is required in every DBC file.
    91  //
    92  // All node names must be unique.
    93  type NodesDef struct {
    94  	Pos       scanner.Position
    95  	NodeNames []Identifier
    96  }
    97  
    98  var _ Def = &NodesDef{}
    99  
   100  func (d *NodesDef) parseFrom(p *Parser) {
   101  	p.useWhitespace(significantNewline)
   102  	defer p.useWhitespace(defaultWhitespace)
   103  	d.Pos = p.keyword(KeywordNodes).pos
   104  	p.token(':')
   105  	for p.peekToken().typ == scanner.Ident {
   106  		d.NodeNames = append(d.NodeNames, p.identifier())
   107  	}
   108  	if p.peekToken().typ != scanner.EOF {
   109  		p.token('\n')
   110  	}
   111  }
   112  
   113  // Position returns the position of the definition.
   114  func (d *NodesDef) Position() scanner.Position {
   115  	return d.Pos
   116  }
   117  
   118  // ValueDescriptionDef defines a textual description for a single signal value.
   119  //
   120  // The value may either be a signal raw value transferred on the bus or the value of an environment variable in a
   121  // remaining bus simulation.
   122  type ValueDescriptionDef struct {
   123  	Pos         scanner.Position
   124  	Value       float64
   125  	Description string
   126  }
   127  
   128  var _ Def = &ValueDescriptionDef{}
   129  
   130  func (d *ValueDescriptionDef) parseFrom(p *Parser) {
   131  	d.Pos = p.peekToken().pos
   132  	d.Value = p.float()
   133  	d.Description = p.string()
   134  }
   135  
   136  // Position returns the position of the definition.
   137  func (d *ValueDescriptionDef) Position() scanner.Position {
   138  	return d.Pos
   139  }
   140  
   141  // ValueTableDef defines a global value table.
   142  //
   143  // The value descriptions in value tables define value encodings for signal raw values.
   144  //
   145  // In commonly used DBC files, the global value tables aren't used, but the value descriptions are defined for each
   146  // signal independently.
   147  type ValueTableDef struct {
   148  	Pos               scanner.Position
   149  	TableName         Identifier
   150  	ValueDescriptions []ValueDescriptionDef
   151  }
   152  
   153  var _ Def = &ValueTableDef{}
   154  
   155  func (d *ValueTableDef) parseFrom(p *Parser) {
   156  	d.Pos = p.keyword(KeywordValueTable).pos
   157  	d.TableName = p.identifier()
   158  	for p.peekToken().typ != ';' {
   159  		valueDescriptionDef := ValueDescriptionDef{}
   160  		valueDescriptionDef.parseFrom(p)
   161  		d.ValueDescriptions = append(d.ValueDescriptions, valueDescriptionDef)
   162  	}
   163  	p.token(';')
   164  }
   165  
   166  // Position returns the position of the definition.
   167  func (d *ValueTableDef) Position() scanner.Position {
   168  	return d.Pos
   169  }
   170  
   171  // MessageDef defines a frame in the network.
   172  //
   173  // The definition includes the name of a frame as well as its properties and the signals transferred.
   174  type MessageDef struct {
   175  	// Pos is the position of the message definition.
   176  	Pos scanner.Position
   177  
   178  	// MessageID contains the message CAN ID.
   179  	//
   180  	// The CAN ID has to be unique within the DBC file.
   181  	//
   182  	// If the most significant bit of the message ID is set, the ID is an extended CAN ID. The extended CAN ID can be
   183  	// determined by masking out the most significant bit with the mask 0xCFFFFFFF.
   184  	MessageID MessageID
   185  
   186  	// Name is the name of the message.
   187  	//
   188  	// The message name has to be unique within the DBC file.
   189  	Name Identifier
   190  
   191  	// Size specifies the size of the message in bytes.
   192  	Size uint64
   193  
   194  	// Transmitter specifies the name of the node transmitting the message.
   195  	//
   196  	// The transmitter has to be defined in the set of node names in the nodes definition.
   197  	//
   198  	// If the message has no transmitter, the string 'Vector__XXX' has to be given here.
   199  	Transmitter Identifier
   200  
   201  	// Signals specifies the signals of the message.
   202  	Signals []SignalDef
   203  }
   204  
   205  var _ Def = &MessageDef{}
   206  
   207  func (d *MessageDef) parseFrom(p *Parser) {
   208  	d.Pos = p.keyword(KeywordMessage).pos
   209  	d.MessageID = p.messageID()
   210  	d.Name = p.identifier()
   211  	p.token(':')
   212  	d.Size = p.uint()
   213  	d.Transmitter = p.identifier()
   214  	for p.peekToken().typ != scanner.EOF && p.peekKeyword() == KeywordSignal {
   215  		signalDef := SignalDef{}
   216  		signalDef.parseFrom(p)
   217  		d.Signals = append(d.Signals, signalDef)
   218  	}
   219  }
   220  
   221  // Position returns the position of the definition.
   222  func (d *MessageDef) Position() scanner.Position {
   223  	return d.Pos
   224  }
   225  
   226  // SignalDef defines a signal within a message.
   227  type SignalDef struct {
   228  	// Pos is the position of the definition.
   229  	Pos scanner.Position
   230  
   231  	// Name of the signal.
   232  	//
   233  	// Has to be unique for all signals within the same message.
   234  	Name Identifier
   235  
   236  	// StartBit specifies the position of the signal within the data field of the frame.
   237  	//
   238  	// For signals with byte order Intel (little-endian) the position of the least-significant bit is given.
   239  	//
   240  	// For signals with byte order Motorola (big-endian) the position of the most significant bit is given.
   241  	//
   242  	// The bits are counted in a saw-tooth manner.
   243  	//
   244  	// The start bit has to be in the range of [0 ,8*message_size-1].
   245  	StartBit uint64
   246  
   247  	// Size specifies the size of the signal in bits.
   248  	Size uint64
   249  
   250  	// IsBigEndian is true if the signal's byte order is Motorola (big-endian).
   251  	IsBigEndian bool
   252  
   253  	// IsSigned is true if the signal is signed.
   254  	IsSigned bool
   255  
   256  	// IsMultiplexerSwitch is true if the signal is a multiplexer switch.
   257  	//
   258  	// A multiplexer indicator of 'M' defines the signal as the multiplexer switch.
   259  	// Only one signal within a single message can be the multiplexer switch.
   260  	IsMultiplexerSwitch bool
   261  
   262  	// IsMultiplexed is true if the signal is multiplexed by the message's multiplexer switch.
   263  	IsMultiplexed bool
   264  
   265  	// MultiplexerSwitch is the multiplexer switch value of the signal.
   266  	//
   267  	// The multiplexed signal is transferred in the message if the switch value of the multiplexer signal is equal to
   268  	// its multiplexer switch value.
   269  	MultiplexerSwitch uint64
   270  
   271  	// Offset is the signals physical value offset.
   272  	//
   273  	// Together with the factor, the offset defines the linear conversion rule to convert the signal's raw value into
   274  	// the signal's physical value and vice versa.
   275  	//
   276  	//  physical_value = raw_value * factor + offset
   277  	//  raw_value      = (physical_value - offset) / factor
   278  	Offset float64
   279  
   280  	// Factor is the signal's physical value factor.
   281  	//
   282  	// See: Offset.
   283  	Factor float64
   284  
   285  	// Minimum defines the signal's minimum physical value.
   286  	Minimum float64
   287  
   288  	// Maximum defines the signal's maximum physical value.
   289  	Maximum float64
   290  
   291  	// Unit defines the unit of the signal's physical value.
   292  	Unit string
   293  
   294  	// Receivers specifies the nodes receiving the signal.
   295  	//
   296  	// If the signal has no receiver, the string 'Vector__XXX' has to be given here.
   297  	Receivers []Identifier
   298  }
   299  
   300  var _ Def = &SignalDef{}
   301  
   302  func (d *SignalDef) parseFrom(p *Parser) {
   303  	d.Pos = p.keyword(KeywordSignal).pos
   304  	d.Name = p.identifier()
   305  	// Parse: Multiplexing
   306  	if p.peekToken().typ != ':' {
   307  		tok := p.nextToken()
   308  		if tok.typ != scanner.Ident {
   309  			p.failf(tok.pos, "expected ident")
   310  		}
   311  		switch {
   312  		case tok.txt == "M":
   313  			d.IsMultiplexerSwitch = true
   314  		case tok.txt[0] == 'm' && len(tok.txt) > 1:
   315  			d.IsMultiplexed = true
   316  			i, err := strconv.Atoi(tok.txt[1:])
   317  			if err != nil || i < 0 {
   318  				p.failf(tok.pos, "invalid multiplexer value")
   319  			}
   320  			d.MultiplexerSwitch = uint64(i)
   321  		default:
   322  			p.failf(tok.pos, "expected multiplexer")
   323  		}
   324  	}
   325  	p.token(':')
   326  	d.StartBit = p.uint()
   327  	p.token('|')
   328  	d.Size = p.uint()
   329  	p.token('@')
   330  	d.IsBigEndian = p.intInRange(0, 1) == 0
   331  	d.IsSigned = p.anyOf('-', '+') == '-'
   332  	p.token('(')
   333  	d.Factor = p.float()
   334  	p.token(',')
   335  	d.Offset = p.float()
   336  	p.token(')')
   337  	p.token('[')
   338  	d.Minimum = p.float()
   339  	p.token('|')
   340  	d.Maximum = p.float()
   341  	p.token(']')
   342  	d.Unit = p.string()
   343  	// Parse: Receivers
   344  	d.Receivers = append(d.Receivers, p.identifier())
   345  	for p.peekToken().typ == ',' {
   346  		p.token(',')
   347  		d.Receivers = append(d.Receivers, p.identifier())
   348  	}
   349  }
   350  
   351  // Position returns the position of the definition.
   352  func (d *SignalDef) Position() scanner.Position {
   353  	return d.Pos
   354  }
   355  
   356  // SignalValueTypeDef defines an extended type definition for a signal.
   357  type SignalValueTypeDef struct {
   358  	Pos             scanner.Position
   359  	MessageID       MessageID
   360  	SignalName      Identifier
   361  	SignalValueType SignalValueType
   362  }
   363  
   364  var _ Def = &SignalValueTypeDef{}
   365  
   366  func (d *SignalValueTypeDef) parseFrom(p *Parser) {
   367  	d.Pos = p.keyword(KeywordSignalValueType).pos
   368  	d.MessageID = p.messageID()
   369  	d.SignalName = p.identifier()
   370  	p.optionalToken(':') // SPECIAL-CASE: colon not part of spec, but encountered in the wild
   371  	d.SignalValueType = p.signalValueType()
   372  	p.token(';')
   373  }
   374  
   375  // Position returns the position of the definition.
   376  func (d *SignalValueTypeDef) Position() scanner.Position {
   377  	return d.Pos
   378  }
   379  
   380  // MessageTransmittersDef defines multiple transmitter nodes of a single message.
   381  //
   382  // This definition is used to describe communication data for higher layer protocols.
   383  //
   384  // This is not used to define CAN layer-2 communication.
   385  type MessageTransmittersDef struct {
   386  	Pos          scanner.Position
   387  	MessageID    MessageID
   388  	Transmitters []Identifier
   389  }
   390  
   391  var _ Def = &MessageTransmittersDef{}
   392  
   393  func (d *MessageTransmittersDef) parseFrom(p *Parser) {
   394  	d.Pos = p.keyword(KeywordMessageTransmitters).pos
   395  	d.MessageID = p.messageID()
   396  	p.token(':')
   397  	for p.peekToken().typ != ';' {
   398  		d.Transmitters = append(d.Transmitters, p.identifier())
   399  		// SPECIAL-CASE: Comma not included in spec, but encountered in the wild
   400  		p.optionalToken(',')
   401  	}
   402  	p.token(';')
   403  }
   404  
   405  // Position returns the position of the definition.
   406  func (d *MessageTransmittersDef) Position() scanner.Position {
   407  	return d.Pos
   408  }
   409  
   410  // ValueDescriptionsDef defines inline descriptions for specific raw signal values.
   411  type ValueDescriptionsDef struct {
   412  	Pos                     scanner.Position
   413  	ObjectType              ObjectType
   414  	MessageID               MessageID
   415  	SignalName              Identifier
   416  	EnvironmentVariableName Identifier
   417  	ValueDescriptions       []ValueDescriptionDef
   418  }
   419  
   420  var _ Def = &ValueDescriptionsDef{}
   421  
   422  func (d *ValueDescriptionsDef) parseFrom(p *Parser) {
   423  	d.Pos = p.keyword(KeywordValueDescriptions).pos
   424  	if p.peekToken().typ == scanner.Ident {
   425  		d.ObjectType = ObjectTypeEnvironmentVariable
   426  		d.EnvironmentVariableName = p.identifier()
   427  	} else {
   428  		d.ObjectType = ObjectTypeSignal
   429  		d.MessageID = p.messageID()
   430  		d.SignalName = p.identifier()
   431  	}
   432  	for p.peekToken().typ != ';' {
   433  		valueDescriptionDef := ValueDescriptionDef{}
   434  		valueDescriptionDef.parseFrom(p)
   435  		d.ValueDescriptions = append(d.ValueDescriptions, valueDescriptionDef)
   436  	}
   437  	p.token(';')
   438  }
   439  
   440  // Position returns the position of the definition.
   441  func (d *ValueDescriptionsDef) Position() scanner.Position {
   442  	return d.Pos
   443  }
   444  
   445  // EnvironmentVariableDef defines an environment variable.
   446  //
   447  // DBC files that describe the CAN communication and don't define any additional data for system or remaining bus
   448  // simulations don't include environment variables.
   449  type EnvironmentVariableDef struct {
   450  	Pos          scanner.Position
   451  	Name         Identifier
   452  	Type         EnvironmentVariableType
   453  	Minimum      float64
   454  	Maximum      float64
   455  	Unit         string
   456  	InitialValue float64
   457  	ID           uint64
   458  	AccessType   AccessType
   459  	AccessNodes  []Identifier
   460  }
   461  
   462  var _ Def = &EnvironmentVariableDef{}
   463  
   464  func (d *EnvironmentVariableDef) parseFrom(p *Parser) {
   465  	d.Pos = p.keyword(KeywordEnvironmentVariable).pos
   466  	d.Name = p.identifier()
   467  	p.token(':')
   468  	d.Type = p.environmentVariableType()
   469  	p.token('[')
   470  	d.Minimum = p.float()
   471  	p.token('|')
   472  	d.Maximum = p.float()
   473  	p.token(']')
   474  	d.Unit = p.string()
   475  	d.InitialValue = p.float()
   476  	d.ID = p.uint()
   477  	d.AccessType = p.accessType()
   478  	d.AccessNodes = append(d.AccessNodes, p.identifier())
   479  	for p.peekToken().typ == ',' {
   480  		p.token(',')
   481  		d.AccessNodes = append(d.AccessNodes, p.identifier())
   482  	}
   483  	p.token(';')
   484  }
   485  
   486  // Position returns the position of the definition.
   487  func (d *EnvironmentVariableDef) Position() scanner.Position {
   488  	return d.Pos
   489  }
   490  
   491  // EnvironmentVariableDataDef defines an environment variable as being of type "data".
   492  //
   493  // Environment variables of this type can store an arbitrary binary data of the given length.
   494  // The length is given in bytes.
   495  type EnvironmentVariableDataDef struct {
   496  	Pos scanner.Position
   497  	// EnvironmentVariableName is the name of the environment variable.
   498  	EnvironmentVariableName Identifier
   499  	// DataSize is the size of the environment variable data in bytes.
   500  	DataSize uint64
   501  }
   502  
   503  var _ Def = &EnvironmentVariableDataDef{}
   504  
   505  func (d *EnvironmentVariableDataDef) parseFrom(p *Parser) {
   506  	d.Pos = p.keyword(KeywordEnvironmentVariableData).pos
   507  	d.EnvironmentVariableName = p.identifier()
   508  	p.token(':')
   509  	d.DataSize = p.uint()
   510  	p.token(';')
   511  }
   512  
   513  // Position returns the position of the definition.
   514  func (d *EnvironmentVariableDataDef) Position() scanner.Position {
   515  	return d.Pos
   516  }
   517  
   518  // CommentDef defines a comment.
   519  type CommentDef struct {
   520  	Pos                     scanner.Position
   521  	ObjectType              ObjectType
   522  	NodeName                Identifier
   523  	MessageID               MessageID
   524  	SignalName              Identifier
   525  	EnvironmentVariableName Identifier
   526  	Comment                 string
   527  }
   528  
   529  var _ Def = &CommentDef{}
   530  
   531  func (d *CommentDef) parseFrom(p *Parser) {
   532  	d.Pos = p.keyword(KeywordComment).pos
   533  	d.ObjectType = p.optionalObjectType()
   534  	switch d.ObjectType {
   535  	case ObjectTypeNetworkNode:
   536  		d.NodeName = p.identifier()
   537  	case ObjectTypeMessage:
   538  		d.MessageID = p.messageID()
   539  	case ObjectTypeSignal:
   540  		d.MessageID = p.messageID()
   541  		d.SignalName = p.identifier()
   542  	case ObjectTypeEnvironmentVariable:
   543  		d.EnvironmentVariableName = p.identifier()
   544  	}
   545  	d.Comment = p.string()
   546  	p.token(';')
   547  }
   548  
   549  // Position returns the position of the definition.
   550  func (d *CommentDef) Position() scanner.Position {
   551  	return d.Pos
   552  }
   553  
   554  // AttributeDef defines a user-defined attribute.
   555  //
   556  // User-defined attributes are a means to extend the object properties of the DBC file.
   557  //
   558  // These additional attributes have to be defined using an attribute definition with an attribute default value.
   559  //
   560  // For each object having a value defined for the attribute, an attribute value entry has to be defined.
   561  //
   562  // If no attribute value entry is defined for an object, the value of the object's attribute is the attribute's default.
   563  type AttributeDef struct {
   564  	Pos          scanner.Position
   565  	ObjectType   ObjectType
   566  	Name         Identifier
   567  	Type         AttributeValueType
   568  	MinimumInt   int64
   569  	MaximumInt   int64
   570  	MinimumFloat float64
   571  	MaximumFloat float64
   572  	EnumValues   []string
   573  }
   574  
   575  var _ Def = &AttributeDef{}
   576  
   577  func (d *AttributeDef) parseFrom(p *Parser) {
   578  	d.Pos = p.keyword(KeywordAttribute).pos
   579  	d.ObjectType = p.optionalObjectType()
   580  	d.Name = p.stringIdentifier()
   581  	d.Type = p.attributeValueType()
   582  	switch d.Type {
   583  	case AttributeValueTypeInt, AttributeValueTypeHex:
   584  		if p.peekToken().typ != ';' {
   585  			d.MinimumInt = p.int()
   586  			d.MaximumInt = p.int()
   587  		}
   588  	case AttributeValueTypeFloat:
   589  		if p.peekToken().typ != ';' {
   590  			// SPECIAL CASE: Support attributes without min/max
   591  			d.MinimumFloat = p.float()
   592  			d.MaximumFloat = p.float()
   593  		}
   594  	case AttributeValueTypeEnum:
   595  		d.EnumValues = append(d.EnumValues, p.string())
   596  		for p.peekToken().typ == ',' {
   597  			p.token(',')
   598  			d.EnumValues = append(d.EnumValues, p.string())
   599  		}
   600  	}
   601  	p.token(';')
   602  }
   603  
   604  // Position returns the position of the definition.
   605  func (d *AttributeDef) Position() scanner.Position {
   606  	return d.Pos
   607  }
   608  
   609  // AttributeDefaultValueDef defines the default value for an attribute.
   610  type AttributeDefaultValueDef struct {
   611  	Pos                scanner.Position
   612  	AttributeName      Identifier
   613  	DefaultIntValue    int64
   614  	DefaultFloatValue  float64
   615  	DefaultStringValue string
   616  }
   617  
   618  var _ Def = &AttributeDefaultValueDef{}
   619  
   620  func (d *AttributeDefaultValueDef) parseFrom(p *Parser) {
   621  	d.Pos = p.keyword(KeywordAttributeDefault).pos
   622  	d.AttributeName = Identifier(p.string())
   623  	// look up attribute type
   624  	for _, prevDef := range p.defs {
   625  		if attributeDef, ok := prevDef.(*AttributeDef); ok && attributeDef.Name == d.AttributeName {
   626  			switch attributeDef.Type {
   627  			case AttributeValueTypeInt, AttributeValueTypeHex:
   628  				d.DefaultIntValue = p.int()
   629  			case AttributeValueTypeFloat:
   630  				d.DefaultFloatValue = p.float()
   631  			case AttributeValueTypeString:
   632  				d.DefaultStringValue = p.string()
   633  			case AttributeValueTypeEnum:
   634  				d.DefaultStringValue = p.enumValue(attributeDef.EnumValues)
   635  			}
   636  			break
   637  		}
   638  	}
   639  	p.token(';')
   640  }
   641  
   642  // Position returns the position of the definition.
   643  func (d *AttributeDefaultValueDef) Position() scanner.Position {
   644  	return d.Pos
   645  }
   646  
   647  // AttributeValueForObjectDef defines a value for an attribute and an object.
   648  type AttributeValueForObjectDef struct {
   649  	Pos                     scanner.Position
   650  	AttributeName           Identifier
   651  	ObjectType              ObjectType
   652  	MessageID               MessageID
   653  	SignalName              Identifier
   654  	NodeName                Identifier
   655  	EnvironmentVariableName Identifier
   656  	IntValue                int64
   657  	FloatValue              float64
   658  	StringValue             string
   659  }
   660  
   661  var _ Def = &AttributeValueForObjectDef{}
   662  
   663  func (d *AttributeValueForObjectDef) parseFrom(p *Parser) {
   664  	d.Pos = p.keyword(KeywordAttributeValue).pos
   665  	d.AttributeName = Identifier(p.string())
   666  	d.ObjectType = p.optionalObjectType()
   667  	switch d.ObjectType {
   668  	case ObjectTypeMessage:
   669  		d.MessageID = p.messageID()
   670  	case ObjectTypeSignal:
   671  		d.MessageID = p.messageID()
   672  		d.SignalName = p.identifier()
   673  	case ObjectTypeNetworkNode:
   674  		d.NodeName = p.identifier()
   675  	case ObjectTypeEnvironmentVariable:
   676  		d.EnvironmentVariableName = p.identifier()
   677  	}
   678  	// look up attribute type
   679  	for _, prevDef := range p.defs {
   680  		if attributeDef, ok := prevDef.(*AttributeDef); ok && attributeDef.Name == d.AttributeName {
   681  			switch attributeDef.Type {
   682  			case AttributeValueTypeInt, AttributeValueTypeHex:
   683  				d.IntValue = p.int()
   684  			case AttributeValueTypeFloat:
   685  				d.FloatValue = p.float()
   686  			case AttributeValueTypeString:
   687  				d.StringValue = p.string()
   688  			case AttributeValueTypeEnum:
   689  				d.StringValue = p.enumValue(attributeDef.EnumValues)
   690  			}
   691  			break
   692  		}
   693  	}
   694  	p.token(';')
   695  }
   696  
   697  // Position returns the position of the definition.
   698  func (d *AttributeValueForObjectDef) Position() scanner.Position {
   699  	return d.Pos
   700  }
   701  
   702  // UnknownDef represents an unknown or unsupported DBC definition.
   703  type UnknownDef struct {
   704  	Pos     scanner.Position
   705  	Keyword Keyword
   706  }
   707  
   708  var _ Def = &UnknownDef{}
   709  
   710  func (d *UnknownDef) parseFrom(p *Parser) {
   711  	tok := p.peekToken()
   712  	d.Pos = tok.pos
   713  	d.Keyword = Keyword(tok.txt)
   714  	p.discardLine()
   715  }
   716  
   717  // Position returns the position of the definition.
   718  func (d *UnknownDef) Position() scanner.Position {
   719  	return d.Pos
   720  }