Я получаю, что flex
стек буфера или стек вообще любит соблюдать LIFO (Last In? First Out!).И я вижу в руководстве, что есть два «предполагаемых» способа выбора буфера: выделять и выбирать вручную и освобождать, или соблюдать поведение LIFO yypush_buffer_state()
и yypop_buffer_state()
.
Но мойреентерабельный лексер преуспел бы в yylex
его стеках в следующем порядке:
[3] pushed from [2] pushed from [1] pushed from [0]
[2]
[1]
[0]
[3] the same one from before...
[2]
[1]
[0]
[3]
[2]
[1]
[0]
(pop pop pop)
[0] which was [3] a moment ago.
Я думал, что я буду дерзким и просто yy_switch_to_buffer()
уменьшу буфер в стеке и использую существующую функцию pushдля автоматического распределения.Но оказывается, что внутренне функция ссылается на макрос YY_CURRENT_BUFFER
, который при наличии стека имеет вид:
((struct yyguts_t*)yyscanner)->yy_buffer_stack[
((struct yyguts_t*)yyscanner)->yy_buffer_stack_top]
И он будет сбит с толку, когда мы попытаемся переключиться на буферы меньшего размера в стеке, чем верхний,Я предполагаю, что это было очень строго сформулированное «предназначение»!
Я обнаружил, что уменьшение yy_buffer_stack_top
и затем выполнение yy_switch_to_buffer(((struct yyguts_t*)yyscanner)->yy_buffer_stack[((struct yyguts_t*)yyscanner)->yy_buffer_stack_top], yyscanner)
, кажется, работает.(Я бы использовал YY_CURRENT_BUFFER
, но на самом деле для этого требуется внутреннее определение yyg
.) Я даже могу увеличить вершину стека до максимального значения и вернуться к нетронутому буферу, который некоторое время оставался неподтвержденным.
Это плохой способ сделать это?Собираюсь ли я столкнуться с какими-либо проблемами, кроме: я не должен yypush_buffer_state()
или yypop_buffer_state()
без первой перезагрузки yy_buffer_stack_top
?Я могу справиться с этим ...