The next four variables define the parser callback functions for the rule name phrases we are interested in.
Callback functions are optional and can be defined for all or none of the rule names
defined by the SABNF grammar.
Normally, these will be defined in a module of their own to keep the flow of the application clean,
but are included here to keep things simple.
The callback function arguments are:
- result - communicates the parsing results to and from the callback functions
(see the
parser.parse()
function in apg-lib
for a complete description).
Here only result.state
and result.phraseLength
are of interest.
- chars - the array of character codes for the input string being parsed.
- phraseIndex - index to the first character in chars of the phrase the parser is attempting to match
- data - an optional user data object passed to
parser.parse()
by the user.
For callback function use only. The parser never modifies or uses this in any way.
For the phoneNumber()
function, a general case is displayed. In general,
a callback function may want to respond to all of the parser states.
- ACTIVE indicates that the parser is visiting this node on the way down the parse tree.
At this point there is no matched phrase - it is not even known whether a phrase will be matched or not.
- EMPTY indicates that the parser is visiting this node on the way up the parse tree and an empty phrase has been matched.
- MATCH indicates that the parser is visiting this node on the way up the parse tree
and a phrase of
result.phraseLength
(> 0) has been matched.
- NOMATCH indicates that the parser is visiting this node on the way up the parse tree
and the parser failed to match any phrase at all.
For these functions, it is assumed that data is an array that they will use to collect the matched phrases in.
(See let phoneParts
below.)
const phoneNumber = function (result, chars, phraseIndex, data) {
switch (result.state) {
case id.ACTIVE:
if (Array.isArray(data) === false) {
throw new Error("parser's user data must be an array");
}
data.length = 0;
break;
case id.EMPTY:
break;
case id.MATCH:
break;
case id.NOMATCH:
break;
default:
throw new Error('unrecognized state');
}
};
const areaCode = function (result, chars, phraseIndex, data) {
if (result.state === id.MATCH) {
data['area-code'] = utils.charsToString(chars, phraseIndex, result.phraseLength);
}
};
const office = function (result, chars, phraseIndex, data) {
if (result.state === id.MATCH) {
data.office = utils.charsToString(chars, phraseIndex, result.phraseLength);
}
};
const subscriber = function (result, chars, phraseIndex, data) {
if (result.state === id.MATCH) {
data.subscriber = utils.charsToString(chars, phraseIndex, result.phraseLength);
}
};