Difference between revisions of "V4 DB Record Instance Syntax"
Line 1: | Line 1: | ||
: '''This page still being | : '''This page still being worked on...''' | ||
The syntax used for record instances has to change in EPICS V4, since we now have to support structured data. While it would have been possible to modify the V3 syntax to allow for this, a complete redesign of the syntax has been done to help improve parsing, and to provide commonality between the syntax of a DB file and the string representation of structured data values passed through Channel Access. | The syntax used for record instances has to change in EPICS V4, since we now have to support structured data. While it would have been possible to modify the V3 syntax to allow for this, a complete redesign of the syntax has been done to help improve parsing, and to provide commonality between the syntax of a DB file and the string representation of structured data values passed through Channel Access. | ||
Line 5: | Line 5: | ||
This syntax is presented below in the form of a grammar. The conventions I'm using are as follows: | This syntax is presented below in the form of a grammar. The conventions I'm using are as follows: | ||
;''symbolBeingDefined'' | ;''symbolBeingDefined:'' | ||
: ''otherSymbol'' | : ''otherSymbol'' | ||
: ''alternateSymbol'' | : ''alternateSymbol'' <tt>literal</tt> | ||
= General Symbols = | = General Symbols = | ||
Line 13: | Line 13: | ||
These symbols are used but not defined in the grammar: | These symbols are used but not defined in the grammar: | ||
;''integerConstant'' | ;''integerConstant:'' | ||
;''floatingConstant | ;''floatingConstant:'' | ||
: Standard format numbers | |||
: | |||
: | |||
;''escapeSequence'' | ;''identifier:'' | ||
: A legal C99 identifier. Note that C99 permits implementations to allow extended characters to be used in identifiers, but does not require it, so the use of extended characters may reduce portability and is not recommended. | |||
;''stringConstant:'' | |||
: <tt>"</tt> ''escapedCharacterList'' <tt>"</tt> | |||
;''escapedCharacterList:'' | |||
: A series of characters, using the C99 ''escapeSequence'' syntax defined below: | |||
;''escapeSequence:'' | |||
: ''simpleEscapeSequence'' | : ''simpleEscapeSequence'' | ||
: ''octalEscapeSequence'' | : ''octalEscapeSequence'' | ||
Line 26: | Line 32: | ||
: ''universalCharacterName'' | : ''universalCharacterName'' | ||
;''simpleEscapeSequence'' | ;''simpleEscapeSequence:'' | ||
: ''one of:'' \ | : ''one of:'' <tt>\ \" \? \\ \a \b \f \n \r \t \v</tt> | ||
;''octalEscapeSequence:'' | |||
: <tt>\</tt> ''octalDigit'' | |||
: <tt>\</tt> ''octalDigit'' ''octalDigit'' | |||
: <tt>\</tt> ''octalDigit'' ''octalDigit'' ''octalDigit'' | |||
;''octalDigit:'' | |||
: ''one of:'' <tt>0 1 2 3 4 5 6 7</tt> | |||
;''hexadecimalEscapeSequence:'' | |||
: <tt>\x</tt> ''hexDigit'' | |||
: ''hexadecimalEscapeSequence'' ''hexDigit'' | |||
;'' | ;''hexDigit:'' | ||
: | : ''one of:'' <tt>0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F</tt> | ||
: | |||
: | |||
;'' | ;''universalCharacterName:'' | ||
: \ | : <tt>\u</tt> ''hexQuad'' | ||
: <tt>\U</tt> ''hexQuad'' ''hexQuad'' | |||
;'' | ;''hexQuad:'' | ||
: | : ''hexDigit'' ''hexDigit'' ''hexDigit'' ''hexDigit'' | ||
The following symbols are like identifier, but may have a different set of legal characters TBD (but which cannot include space). | The following symbols are like identifier, but may have a different set of legal characters TBD (but which cannot include space). | ||
;''recordName'' | ;''recordName:'' | ||
: '''Currently record names may contain <tt>A-Z a-z _ - ; : < > [ ]</tt>. We should probably | : '''Currently record names may contain <tt>A-Z a-z _ - ; : < > [ ]</tt>. We should probably allow non-ASCII Unicode/UTF-8 characters, but no new ASCII characters.''' | ||
;''linkType:'' | |||
;''deviceType:'' | |||
: '''I'd like these two to have to be valid C99 identifiers, but we could probably add some other ASCII characters if desired. No spaces, brackets or braces, for syntax reasons.''' | |||
;''booleanConstant'' | We could afford to be generous in what we accept as a boolean value: | ||
;''booleanConstant:'' | |||
: ''booleanTrue'' | : ''booleanTrue'' | ||
: | : <tt>"</tt> ''booleanTrue'' <tt>"</tt> | ||
: ''booleanFalse'' | : ''booleanFalse'' | ||
: | : <tt>"</tt> ''booleanFalse'' <tt>"</tt> | ||
;''booleanTrue'' | |||
: '' | ;''booleanTrue:'' | ||
: ''one of:'' <tt>1 T TRUE True t true Y YES Yes y yes</tt> | |||
: '' | |||
;''booleanFalse:'' | |||
: ''one of:'' <tt>0 F FALSE False f false N NO No n no</tt> | |||
Line 75: | Line 92: | ||
= Record Instances = | = Record Instances = | ||
;''recordDefinition'' | ;''recordDefinition:'' | ||
: ''recordType'' ''recordName'' | : ''recordType'' ''recordName'' <tt>= {</tt> ''recordBody'' <tt>}</tt> | ||
;''recordType'' | ;''recordType:'' | ||
: ''identifier'' | : ''identifier'' | ||
;''recordBody'' | ;''recordBody:'' | ||
: ''recordBodyItem'' | : ''recordBodyItem'' | ||
: ''recordBody'' ''recordBodyItem'' | : ''recordBody'' ''recordBodyItem'' | ||
Line 93: | Line 110: | ||
Inside the body of the record definition, there are three possible kinds of statements, similar to a C assignment statement. Note these statements must all be terminated with a semi-colon (which is different from inside a struct). | Inside the body of the record definition, there are three possible kinds of statements, similar to a C assignment statement. Note these statements must all be terminated with a semi-colon (which is different from inside a struct). | ||
;''recordBodyItem'' | ;''recordBodyItem:'' | ||
: | : <tt>info</tt> ''infoName'' <tt>=</tt> ''stringConstant'' <tt>;</tt> | ||
: ''fieldName'' | : ''fieldName'' <tt>=</tt> ''initializer'' <tt>;</tt> | ||
: ''extraField'' | : ''extraField'' <tt>=</tt> ''extraInitializer'' <tt>;</tt> | ||
;''infoName'' | ;''infoName:'' | ||
: ''identifier'' | : ''identifier'' | ||
: ''stringConstant'' | : ''stringConstant'' | ||
Line 108: | Line 125: | ||
info "my favourite things" = "raindrops on roses"; | info "my favourite things" = "raindrops on roses"; | ||
;''fieldName'' | ;''fieldName:'' | ||
: ''identifier'' | : ''identifier'' | ||
;''initializer'' | ;''initializer:'' | ||
: ''constant'' | : ''constant'' | ||
: | : <tt>{</tt> ''structAssignmentList'' <tt>}</tt> | ||
: | : <tt>{</tt> ''arrayAssignmentList'' <tt>}</tt> | ||
: ''arrayType'' | : ''arrayType'' <tt>{</tt> ''arrayAssignmentList'' <tt>}</tt> | ||
: | : <tt>[</tt> ''arrayCapacity'' <tt>] {</tt> ''arrayAssignmentList'' <tt>}</tt> | ||
: ''arrayType'' | : ''arrayType'' <tt>[</tt> ''arrayCapacity'' <tt>] {</tt> ''arrayAssignmentList'' <tt>}</tt> | ||
: ''linkType'' | : ''linkType'' <tt>{</tt> ''structAssignmentList'' <tt>}</tt> | ||
: ''deviceType'' | : ''deviceType'' <tt>{</tt> ''structAssignmentList'' <tt>}</tt> | ||
;''constant'' | ;''constant:'' | ||
: ''booleanConstant'' | : ''booleanConstant'' | ||
: ''integerConstant'' | : ''integerConstant'' | ||
Line 136: | Line 153: | ||
} | } | ||
;''structAssignmentList'' | ;''structAssignmentList:'' | ||
: ''initializerList'' | : ''initializerList'' | ||
: ''fieldName'' | : ''fieldName'' <tt>=</tt> ''initializerList'' | ||
: ''structAssignmentList'' | : ''structAssignmentList'' <tt>;</tt> ''fieldName'' <tt>=</tt> ''initializerList'' | ||
;''initializerList'' | ;''initializerList:'' | ||
: ''initializer'' | : ''initializer'' | ||
: ''initializerList'' | : ''initializerList'' <tt>,</tt> ''initializer'' | ||
Initializers for a structure field look similar to a nested record body, but the rules are slightly different: | Initializers for a structure field look similar to a nested record body, but the rules are slightly different: | ||
Line 161: | Line 178: | ||
;''arrayAssignmentList'' | ;''arrayAssignmentList:'' | ||
: ''initializerList'' | : ''initializerList'' | ||
: | : <tt>[</tt> ''integerConstant'' <tt>] =</tt> ''initializerList'' | ||
: ''arrayAssignmentList'' | : ''arrayAssignmentList'' <tt>; [</tt> ''integerConstant'' <tt>] =</tt> ''initializerList'' | ||
;''arrayType'' | ;''arrayType:'' | ||
: | : <tt>bool</tt> | ||
: | : <tt>int16</tt> | ||
: | : <tt>uint16</tt> | ||
: | : <tt>int32</tt> | ||
: | : <tt>uint32</tt> | ||
: | : <tt>float32</tt> | ||
: | : <tt>float64</tt> | ||
: | : <tt>octet</tt> | ||
: | : <tt>string</tt> | ||
;''arrayCapacity'' | ;''arrayCapacity:'' | ||
: ''integerConstant'' | : ''integerConstant'' | ||
: ''integerConstant'' | : ''integerConstant'' <tt>,</tt> ''arrayCapacity'' |
Revision as of 18:35, 20 May 2005
- This page still being worked on...
The syntax used for record instances has to change in EPICS V4, since we now have to support structured data. While it would have been possible to modify the V3 syntax to allow for this, a complete redesign of the syntax has been done to help improve parsing, and to provide commonality between the syntax of a DB file and the string representation of structured data values passed through Channel Access.
This syntax is presented below in the form of a grammar. The conventions I'm using are as follows:
- symbolBeingDefined:
- otherSymbol
- alternateSymbol literal
General Symbols
These symbols are used but not defined in the grammar:
- integerConstant:
- floatingConstant:
- Standard format numbers
- identifier:
- A legal C99 identifier. Note that C99 permits implementations to allow extended characters to be used in identifiers, but does not require it, so the use of extended characters may reduce portability and is not recommended.
- stringConstant:
- " escapedCharacterList "
- escapedCharacterList:
- A series of characters, using the C99 escapeSequence syntax defined below:
- escapeSequence:
- simpleEscapeSequence
- octalEscapeSequence
- hexadecimalEscapeSequence
- universalCharacterName
- simpleEscapeSequence:
- one of: \ \" \? \\ \a \b \f \n \r \t \v
- octalEscapeSequence:
- \ octalDigit
- \ octalDigit octalDigit
- \ octalDigit octalDigit octalDigit
- octalDigit:
- one of: 0 1 2 3 4 5 6 7
- hexadecimalEscapeSequence:
- \x hexDigit
- hexadecimalEscapeSequence hexDigit
- hexDigit:
- one of: 0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F
- universalCharacterName:
- \u hexQuad
- \U hexQuad hexQuad
- hexQuad:
- hexDigit hexDigit hexDigit hexDigit
The following symbols are like identifier, but may have a different set of legal characters TBD (but which cannot include space).
- recordName:
- Currently record names may contain A-Z a-z _ - ; : < > [ ]. We should probably allow non-ASCII Unicode/UTF-8 characters, but no new ASCII characters.
- linkType:
- deviceType:
- I'd like these two to have to be valid C99 identifiers, but we could probably add some other ASCII characters if desired. No spaces, brackets or braces, for syntax reasons.
We could afford to be generous in what we accept as a boolean value:
- booleanConstant:
- booleanTrue
- " booleanTrue "
- booleanFalse
- " booleanFalse "
- booleanTrue:
- one of: 1 T TRUE True t true Y YES Yes y yes
- booleanFalse:
- one of: 0 F FALSE False f false N NO No n no
Database File
I need to define these, which are really preprocessor objects:
- comments
- substitution macros
- templates and ports
Record Instances
- recordDefinition:
- recordType recordName = { recordBody }
- recordType:
- identifier
- recordBody:
- recordBodyItem
- recordBody recordBodyItem
Record definitions will look very similar to a C99 structure definition with initialization in EPICS V4. For example:
ai foo:bar:temperature = { ... }
Inside the body of the record definition, there are three possible kinds of statements, similar to a C assignment statement. Note these statements must all be terminated with a semi-colon (which is different from inside a struct).
- recordBodyItem:
- info infoName = stringConstant ;
- fieldName = initializer ;
- extraField = extraInitializer ;
- infoName:
- identifier
- stringConstant
Info items provide additional configuration data about this record that can be accessed by other software running on the IOC.
info savePeriod = "30.0"; info restorePhase = "1"; info "my favourite things" = "raindrops on roses";
- fieldName:
- identifier
- initializer:
- constant
- { structAssignmentList }
- { arrayAssignmentList }
- arrayType { arrayAssignmentList }
- [ arrayCapacity ] { arrayAssignmentList }
- arrayType [ arrayCapacity ] { arrayAssignmentList }
- linkType { structAssignmentList }
- deviceType { structAssignmentList }
- constant:
- booleanConstant
- integerConstant
- floatingConstant
- stringConstant
The syntax for setting field values depends on the data type represented by fieldName. Basic types (numeric or string) should need no comment other than to note that numeric values should not be given inside quotes:
ai foo:bar:temperature = { inputSmoothing = 0.98; invalidValue = 1000; units = "Celcius"; ... }
- structAssignmentList:
- initializerList
- fieldName = initializerList
- structAssignmentList ; fieldName = initializerList
- initializerList:
- initializer
- initializerList , initializer
Initializers for a structure field look similar to a nested record body, but the rules are slightly different:
- You can give a series of values for adjacent items using a simple comma-separated list (for a record body, you must name each field)
- Semi-colons are required between a value and a following named item.
For example:
ai foo:bar:temperature = { linearConvert = { mode = "Linear"; low = -12.5, 133.5 }; displayLimit = { 0, 100 }; ... }
- arrayAssignmentList:
- initializerList
- [ integerConstant ] = initializerList
- arrayAssignmentList ; [ integerConstant ] = initializerList
- arrayType:
- bool
- int16
- uint16
- int32
- uint32
- float32
- float64
- octet
- string
- arrayCapacity:
- integerConstant
- integerConstant , arrayCapacity