I have a good experience with AT commands: I am working for a company that is specialized in modems, and I wrote myself 2 or 3 AT command parsers in the past.
A good starting point is the ITU-T "V.250 : Serial asynchronous automatic dialling and control" recommendation. It is freely available directly from the ITU website:https://www.itu.int/rec/T-REC-V.250-200307-I/en
Regarding the code structure, the first idea is to implement the ultra-simple lexical parser for both basic and extended command sets, which behavior is accurately described in the linked document.
From experience, I can say that mapping directly an AT command to a function call is not very efficient, as this will result in a poorly efficient code due to the number of function entry/exit code overhead. A much more efficient method is to map an AT command to a token that will be used into a "switch/case" structure to eliminate to function overhead completely.
Thus, the lexical parser's job would be to transform the characters making up a command and its arguments into command tokens and an "argc/argv"-like array of arguments, if possible already transformed into the proper binary format in a single place, so that the conversion does not have to be repeated for each individual command.
What is remarkable when you look at the available AT commands is that beyond the required basic AT command set, all the AT commands can be grouped into a set of related AT command (GSM, Ethernet, WiFi, GPIOs, etc.) quite nicely, and these sets form entities similar to OOP objects with members (AT "S-parameters") and methods (AT "actions").
Thus, a plugin mechanism is desirable, that enables implementing these sets of related AT commands in a modular way, each plugin providing an extension to the basic AT command set, with its own look-up table, execution mapping function and utility functions (open/close, start/stop, constructor/destructor...).
The resulting code size is quite small, and suitable for both small 8-bit or larger 32-bit MCUs, usually in the 2~3KB range for the basic AT command set.