Секция подпрограмм
Смысл применения подпрограмм при использовании lex'а тот же, что и в случае других языков программирования. Действия, которые должны встречаться в нескольких правилах, можно записать один раз и вызывать там, где требуется. Подпрограммы, как и сокращения, облегчают написание и чтение программ. Например, функция put_in_tabl(), обсуждаемая в следующем о разделе, - достойный кандидат в подпрограммы.
Иногда подпрограмму помещают в эту секцию по методологическим соображениям - чтобы выделить некоторую часть действий или упростить секцию правил, даже если данное действие используется только в одном правиле. В качестве примера рассмотрим следующую подпрограмму, которая пропускает комментарии в языке, подобном C, где комментарии выделяются символами /* и */:
"/*" skipcmnts(); . . . /* Остальные правила */ %% skipcmnts () { for (;;) { while (input () != '*') ; if (input () != '/') { unput (yytext [yyleng-1]); } else return; } }
В этом примере затронуты три интересных вопроса. Во-первых, функция unput(c) (возвратить последний прочитанный символ) нужна, чтобы правильно обработать комментарии, заканчивающиеся комбинацией символов **/. Во-вторых, выражение yytext [yyleng-1] используется для выборки последнего прочитанного символа. В-третьих, в рассматриваемой подпрограмме предполагается, что комментарии не могут быть вложены. (Для языка C это действительно так.) Если, в отличие от C, в исходном тексте комментарии вложены, после распознавания цепочки */, закрывающей внутренний комментарий, сгенерированная программа будет продолжать чтение оставшейся части комментариев, как если бы это была часть текста, которую надо распознавать.
Другими примерами подпрограмм могут служить заданные программистом варианты обсуждавшихся выше функций ввода/вывода input(), unput() и output(). Подобные функции могут использоваться во многих программах, поэтому, вероятно, лучше всего было бы поместить их в отдельный файл или библиотеку и вызывать по мере необходимости. При этом в секцию определений следовало бы поместить соответствующие операторы #include.