alpag.net manual
Parser / Programing interface / Basic operation
< Programing interface | Resetting >

Basic operation

Default parser constructor takes no parameters:

MyParser parser = new MyParser()

Generated parser must have access to a source of tokens, which usually is a lexer. User must attach this source manually. This can be done after parser creation or in custom user-defined constructor.

Parser can be used in two modes:

Pull mode is default.

Fig. 15 Pull and push operation

Parser mode can be changed using Parser.PullPush option.

In pull mode parser is invoked using method:

int Parse()

This method is called only once for entire parsing session. It returns EOF to indicate success or error code.

In push mode parser is invoked using method:

int Parse( nextSymbol, nextSymbolData )

Each time method is called user should provide next input symbol. Parser processes this symbol and returns NEED_MORE_SYMBOLS to indicate that next symbol is required. It is legal to invoke parser with nextSymbol set to zero. This means that user does not have next symbol at the moment but asks parser to do as much as possible.

When end of input stream is reached and parser asks for more symbols, method should be invoked with EOF as nextSymbol.

It is potentially possible that user passes next symbol but parser does not need one. In such case does not consume this symbol, and SYMBOL_ALREADY_PRESENT is returned. User should reinvoke parser with nextSymbol set to zero, wait until parser processes data it already has, and after that invoke it again passing his symbol.

Below is an outline of code for invoking parser in push mode:

int nextToken = 0; // zero stands for no symbol
int tokenToPass = 0; // nextToken or 0 if parser wants no input
ValueData tokenData = new ValueData();
for(;;)
{
int status = myParser.Parse( tokenToPass, tokenData );
if( status == NEED_MORE_SYMBOLS )
{
if( tokenToPass == 0 && nextToken > 0 )
tokenToPass = nextToken; // use cached token
else {
if( !Read_Next_Symbol_From_Lexer_unless_EOF(
out nextToken, out tokenData
) )
{
nextToken = EOF;
}
tokenToPass = nextToken; // pass it in next call
}
} else if( status == EOF ) {
break; // done with success
} else if( status == SYMBOL_ALREADY_PRESENT ) {
tokenToPass = 0; // pass zero in next call
} else {
break; // error
}
}

Normally parser continues processing until recently passed symbol is consumed, so it never needs to report SYMBOL_ALREADY_PRESENT. Handling SYMBOL_ALREADY_PRESENT may be necessary only if some custom code placed by user inside Parse() returns before symbol has been processed. Only in such scenario parser can be left with unprocessed symbol stuck inside.

User can extend prototype of Parse() method by defining own custom parameters using Parser.Code.ParseFuncArgsCustom option.

< Programing interface | Resetting >
Alpag Manual