I am trying to model mqsi commands, using ANTLR and have come across the following problem. The documents for mqsicreateconfigurableservice say for the queuePrefix : "The prefix can contain any characters that are valid in a WebSphere® MQ queue name, but must be no longer than eight characters and must not begin or end with a period (.). For example, SET.1 is valid, but .SET1 and SET1. are invalid. Multiple configurable services can use the same queue prefix."
I've used the following, as a stopgap but this technique implies I must have a minimum of a two character name and seems a very wasteful and non-scalable solution. Is there a better method?
See 'queuePrefixValue', below...
Thanks :o)
parser grammar mqsicreateconfigurableservice;
mqsicreateconfigurableservice
: 'mqsicreateconfigurableservice' ' '+ params
;
params : (broker ' '+ switches+)
;
broker : validChar+
;
switches
: AggregationConfigurableService
;
AggregationConfigurableService
: (objectName ' '+ AggregationNameValuePropertyPair)
;
objectName
: (' '+ '-o' ' '+ validChar+)
;
AggregationNameValuePropertyPair
: (' '+ '-n' ' '+ 'queuePrefix' ' '+ '-v' ' '+ queuePrefixValue)?
(' '+ '-n' ' '+ 'timeoutSeconds' ' '+ '-v' ' '+ timeoutSecondsValue)?
;
// I'm not satisfied with this rule as it means at least two digits are mandatory
//Couldn't see how to use regex or semantic predicates which appear to offer a solution
queuePrefixValue
: validChar (validChar | '.')? (validChar | '.')? (validChar | '.')? (validChar | '.')? (validChar | '.')? (validChar | '.')? validChar
;
timeoutSecondsValue //a positive integer
: ('0'..'9')+
;
//This char list is just a temporary subset which eventually needs to reflect all the WebSphere acceptable characters, apart from the dot '.'
validChar
: (('a'..'z')|('A'..'Z')|('0'..'9'))
;
You're using parser rules where you should be using lexer rules instead 1. The
.
(the dot meta-char) and..
(the range meta-char) behave differently in parser rules as they do in lexer rules. In parser rules,.
matches any token (in lexer rules they match any character) and..
will match token-ranges, not character ranges as you're expecting them to match!So, make
queuePrefixValue
a lexer rule (let it start with an upper case letter:QueuePrefixValue
), and usefragment
rules 2 where appropriate. YourQueuePrefixValue
could look like this:So, that more or less answers your question: no, there is no short way to restrict a token to have a certain amount of characters without a language-specific predicate. Note that my suggestion above is not ambiguous (your
QueuePrefixValue
is ambiguous) and mine also accepts single character values.HTH
1 Practical difference between parser rules and lexer rules in ANTLR?
2 What does "fragment" mean in ANTLR?