Let me put in a plug for “extended DCGs” in pack(edcg)
… these allow multiple accumulators and the accumulators can do custom things, such as symbol tables.
Speaking of symbol tables, I use rbtrees, which have O(log N) performance and they’re not a significant performance issue, even when the symbol tables are quite large (more than 10,000 entries).
So, for storing your list of lines, rbtrees might work well.