You can use your lex routines in the same ways you use routines in other programming languages. Action code used for several rules can be written once and called when needed. As with definitions, this simplifies program writing and reading.
The put_in_tabl() function, discussed in the "Using lex and yacc Together" section, fits well in the user routines section of a lex specification.
Another reason to place a routine in this section is to highlight some code of interest or to simplify the rules section, even if the code is to be used for one rule only. As an example, consider the following routine to ignore comments in a language like C where comments occur between /* and */:
%{ static skipcmnts(); %} %% "/*" skipcmnts(); ... ... /* rest of rules */ %% static skipcmnts() { for(;;) { while (input() != '*') ; if (input() != '/') unput(yytext[yyleng-1]) else return; } }
There are three points of interest in this example.
First, the unput(c)
macro puts back the last character that was read to avoid missing the final / if the comment ends unusually with a **/.
In this case, after the scanner reads an *, it finds that the next character is not the terminal / and it continues reading.
Second, the expression yytext[yyleng-1] picks the last character read.