Как правило, вы будете использовать два (как минимум) типа инструментов при создании вашего парсера.
Первая часть - это лексический анализ - разделение символов на токены и фильтрация комментариев и пробелов. Эта часть обычно выполняется с помощью регулярных выражений. Что ж, это еще более типично делается с помощью генератора сканера, который преобразует набор пар регулярных выражений и кода в программу, которая выполняет соответствующий код, когда распознает регулярные выражения. Это оказывается более эффективным, чем тестирование каждого регулярного выражения каждый раз, и это также работает лучше по ряду других причин. FLEX является распространенным инструментом для этого в C.
Вторая часть вашего парсера - это грамматика. Наиболее типичным инструментом для этого является другой генератор программ, который принимает не зависящую от контекста грамматику (CFG), аннотированную правилами интерпретации составляющих «частей речи». CFG может выражать такие вещи, как сбалансированные круглые скобки, чего не может регулярное выражение (если оно не было расширено с помощью функций CF, что делает его не совсем «регулярным» в математическом смысле). Но CFG с правилами очень хорош, потому что вы можете придать смысловой смысл структуре слов вашего языка. ЗУБР является распространенным инструментом для этой части в C.
Но я на самом деле сказал тебе небольшую ложь. Видите ли, у каждого реального языка программирования есть части, которые не могут быть выражены в контексте без контекста. Например, вам нужно связать определение переменной с ее использованием, чтобы вы знали, какие инструкции нужно сгенерировать, а также, если операция над ней является допустимой. Обычно это рассматривается вне рамок синтаксического анализа, но есть такие вещи, как «грамматики атрибутов», которые похожи на CFG, расширенные функциями, которые могут значительно облегчить кодирование и работу даже с этими зависимостями контекста.
Теперь нет правила, согласно которому вы ДОЛЖНЫ использовать такие инструменты. Многие простые грамматики достаточно легко обрабатываются с помощью рукописных инструментов. Например, S-выражения LISP можно просто отсканировать как:
Если оно начинается с цифры, прочитайте число.
Если это начинается с буквы, прочитайте символ.
Если это пробел, пропустите его.
Если это открытый парен, то пропустите его, повторите эту процедуру для значения и ожидайте близкого парена.
Ну, есть еще несколько сложностей для строк и что с тобой, но это основная идея. Разбор FORTH еще проще, потому что он не создает рекурсивную структуру данных.
Во всяком случае, это должно помочь вам в работе над вашим проектом.