#include <ConfigParser.h>
A ConfigParser reads a Rulbus configuration file that specifies Rulbus devices and it creates these devices and makes them accessible via the Rulbus Device List.
The parser uses a lexical analyzer, or scanner to read the configuration file a token at a time and it uses a builder to create the Rulbus devices specified in this configuration file. Currently the context is not used. (In other language compilers it may contain information on the variables in the current scope.)
A parser can be used as follows.
ConfigScanner scanner( cin ); ConfigListBuilder builder; ConfigContext context; ConfigParser parser( scanner, builder, context ); parser.parse();
Here is a simple Rulbus configuration file.
# rulbus-small.conf - example rulbus device configuration file. rack "top" { address = 0 rb8509_adc12 "adc" rb8510_dac12 "dac-ch0" { address = 0xD0 } rb8510_dac12 "dac-ch1" { address = 0xD2; bipolar = false; volt_per_bit = 1.25m } } rack "bottom" { address = 1 // still empty }
And here is a longer example Rulbus configuration file.
The syntax recognized by the ConfigParser is specified by the following grammar.
Grammar (simplified) for Rulbus configuration file, 05-Feb-2004 program : rack-declaration-sequence? file-assignment? rack-declaration-sequence? file-assignment : 'file' optassign path optdelim rack-declaration-sequence : rack-declaration | rack-declaration-sequence rack-declaration rack-declaration : 'rack' identifier rack-initializer? optdelim rack-initializer : optassign '{' rack-initializer-list? '}' rack-initializer-list : address-initializer? card-declaration-sequence? card-declaration-sequence : card-declaration | card-declaration-sequence card-declaration card-declaration : card-type-specifier identifier card-initializer? optdelim card-initializer : optassign '{' property-initializer-list? optdelim '}' property-initializer-list : property-initializer | property-initializer-list optdelim property-initializer card-type-specifier : 'rb_generic' | 'rb8506_pia' | 'rb8506_sifu' | 'rb8506_via' | 'rb8509_adc12' | 'rb8510_dac12' | 'rb8513_timebase' | 'rb8514_delay' | 'rb8515_clock' | 'rb8905_adc12' | 'rb9005_amplifier' | 'rb9603_monochromator' address-initializer : 'address' optassign integer-literal optdelim property-initializer : property optassign literal property : 'address' ; takes integer-literal | 'bipolar' ; takes boolean literal | 'has_ext_trigger' ; takes boolean-literal | 'intr_delay' ; takes floating-literal, ; integer multiple of 10 ns | 'num_channels' ; takes integer-literal | 'volt_per_bit' ; takes floating-literal path : string-literal identifier : string-literal literal : boolean-literal | integer-literal | floating-literal | string-literal boolean-literal : 'true' | 'false' | 'yes' | 'no' | integer-literal ; zero: false, non-zero: true integer-literal : octal-literal suffix? | decimal-literal suffix? | hexadecimal-literal suffix? floating-literal : fraction exponent? suffix? | [0-9]+ exponent suffix? fraction : [0-9]* '.' [0-9]+ | [0-9]+ '.' exponent : [eE] [-+]? [0-9]+ string-literal : '\'' {printable} '\'' | '"' {printable} '"' octal-literal : '0' [0-7]* decimal-literal : [1-9][0-9]* hex-literal : '0' [xX] [0-9a-fA-F]+ suffix : [fpnumkMGT] ; femto..Tera multiplication factor optassign: [=:]? optdelim : [,;]?
Lexical behaviour of the Rulbus configuration file parser
There are three comment-variants:
#'
and '//'
/*'
... '*/'
,
no nestingSemantics of the Rulbus configuration file
Properties take different value-types. This is not specified by the grammar, but only indicated there with a comment.
It is allowed for a property of a card to be specified multiple times with the same value. It is an error though if the property of a card is specified with different values.
The list below gives the properties that each type accepts with their default values.
Public Member Functions | |
ConfigParser (ConfigScanner &scanner, ConfigBuilder &builder, ConfigContext &context) | |
constructor. | |
void | parse () |
get first token and parse the program. | |
Protected Member Functions | |
void | parseProgram () |
parse the complete program. | |
void | parseFileAssignment () |
parse and ignore the optional file entry. | |
void | parseRackDeclarationSequence () |
parse the rack sequence. | |
void | parseRackDeclaration () |
parse a rack entry. | |
void | parseRackInitializer () |
parse an optional rack initializer. | |
void | parseRackAddressAssignment () |
parse an optional rack address assignment. | |
void | parseCardDeclarationSequence () |
parse optional card declarations. | |
void | parseCardDeclaration () |
parse a card entry. | |
void | parseCardInitializer (ConfigToken::TokenCode card) |
parse an optional card initializer. | |
void | parseRB8509 (bool scanProperties=true) |
parse properties for RB8509 Adc12. | |
void | parseRB8510 (bool scanProperties=true) |
parse properties for RB8510 Dac12. | |
void | parseRB8514 (bool scanProperties=true) |
parse properties for RB8514 delay. | |
void | parseRB8905 (bool scanProperties=true) |
parse properties for RB8905 Adc12. | |
void | parseGenericCard (ConfigToken::TokenCode card, bool scanProperties=true) |
parse cards that only needs name, address and rack. | |
Int | parseAddress (ConfigToken::TokenCode token=ConfigToken::tcCARD) |
parse address property. | |
bool | parseHasExtTrigger () |
parse has_ext_trigger property. | |
Int | parseNumChannels () |
parse num_channels property. | |
bool | parseBipolar () |
parse bipolar property. | |
Real | parseVoltPerBit () |
parse volt_per_bit property. | |
Real | parseIntrDelay () |
parse intrinsic delay property. | |
bool | parseBooleanProperty (ConfigToken::TokenCode token) |
parse boolean property. | |
Int | parseIntegerProperty (ConfigToken::TokenCode token) |
parse integer property. | |
Real | parseRealProperty (ConfigToken::TokenCode token) |
parse real property. | |
Real | parseOptUnit (ConfigToken::TokenCode token) |
return factor for optional unit suffix. | |
void | parseOptDelimiter () |
parse optional delimiter. | |
void | parseOptAssignOp () |
parse optional assignment operator. | |
void | checkRackAllowed () |
check if no rack with address 0xF exists so that another rack may exist. | |
void | checkDuplicateRackName () |
check if rack name is already defined. | |
void | checkDuplicateCardName () |
check if card name is already defined. | |
void | checkRackDeclaration () |
check the rack declaration just parsed. | |
void | checkCardDeclarations () |
check the card declarations parsed thus far. | |
void | checkDuplicateRackAddr (bool withline=false) |
check if rack address is already use. | |
void | checkOverlapCardAddr (bool withline=false) |
check if card addresses overlap; traverses theCardList i.e. | |
void | addCard (RulbusDevicePtr card) |
add a new card toe the list of cards in a rack and to the list of all cards. | |
void | clearRackCardList () |
empty the list of cards in a rack. | |
void | updateRackCardList () |
update the rack address of the cards in a rack and offer the cards to theBuilder. | |
void | getToken () |
get the next token, unless end of file already reached. | |
bool | test (ConfigToken::TokenCode token, bool require=true) |
check for specified token; throws ParseError if require is true and the token is not there or on end of file. | |
void | expect (ConfigToken::TokenCode token, bool require=true) |
check for and consume specified token; throws ParseError if require is true and the token is not there. | |
Private Types | |
typedef std::vector< RulbusDevicePtr > | CardList |
list for RulbusDevicePtr-s | |
typedef std::vector< String > | NameList |
'set' for rack names or list for device names | |
typedef std::vector< bool > | AddrList |
'set' for rack addresses | |
typedef std::vector< int > | LineList |
'set' or list for declaration linenumbers | |
Private Attributes | |
ConfigToken::TokenCode | t |
the current token code | |
ConfigScanner * | theScanner |
the scanner | |
ConfigBuilder & | theBuilder |
the builder | |
ConfigContext & | theContext |
the context | |
ConfigToken * | theToken |
the current token | |
String | theRackName |
the current rack's name | |
Int | theRackAddress |
the current rack's address | |
Int | theRackLine |
the current rack's declaration linenumber | |
String | theCardName |
the current card's name | |
Int | theCardAddress |
the current card's address | |
CardList | theCardList |
temporary list of all cards | |
NameList | theCardNameList |
temporary list of all card names | |
LineList | theCardLineList |
card declarations linenumber | |
CardList | theRackCardList |
temporary list of cards in a rack | |
AddrList | theRackAddrSet |
rack addresses in use | |
NameList | theRackNameSet |
rack names in use | |
LineList | theRackLineSet |
rack declarations linenumber | |
Static Private Attributes | |
const int | DEF_CARDS = 32 |
const int | LIM_RACKS = 16 |
initial guess for number of cards | |
CharCptr | already_assigned = " already assigned a different value" |
optimaization. |
|
device must already have been created; based on code by Jens Thoms Törring. |