лексер просто маркирует поток, чтобы превратить поток символов в поток токенов (который будет проанализирован парсером позже для получения полного синтаксического дерева). Для вашего примера вы получите что-то вроде:
#include <stdio.h> (this is handled by preprocessor, not by lexer so it wouldn't exist)
int KEYWORD
main IDENTIFIER
( LPAR
) RPAR
{ LBRACE
int KEYWORD
a IDENT
, COMMA
b IDENT
; SEMICOL
a IDENT
= ASSIGN
a IDENT
+ PLUS
b IDENT
; SEMICOL
printf IDENT
( LPAR
"%d" STRING
, COMMA
a IDENT
) RPAR
; SEMICOL
return RETURN_KEYWORD
0 INTEGER
; SEMICOL
} RBRACE
Конечно, лексер сам по себе мало что может сделать, он может просто разбить источник на мельчайшие возможные элементы, проверяя синтаксические ошибки (например, ключевые слова с ошибками). Вам нужно что-то, что объединит их, чтобы придать им смысловой смысл.
Еще одно замечание: некоторые лексеры любят группировать подобные типы токенов только в один (например, токен KEYWORD
, содержащий все ключевые слова), используя связанный с ним параметр, в то время как другие имеют разные токены для каждого типа RETURN_KEYWORK
, IF_KEYWORD
и т. Д.