/*!@file \brief lexical analyzer implementation for APC \details The lexer manages two FIFO stacks. One for maintaining tokens, the other for maintaining a list of files to be scanned. During execution, the lexer will return a token from its token queue if any are present. If not, the lexer will will pop an element from its file queue to 'scanner' to be tokenized. If the file queue is empty, the lexer will instead call 'parsedir' to traverse the directory tree and tokenize the results. If 'parsedir' does not generate any new tokens, we are done. \author Jordan Lavatai \date Aug 2016 ----------------------------------------------------------------------------*/ /* Standard */ #include #include #include #include /* Posix */ #include #include #include #include #include #include #include #include /* Local */ #include "apc.h" #include "parser.tab.h" /* Public */ int lexer_lexfile(uint8_t const*); /* Private */ extern //lexer.rl int lexer_lexstring(uint8_t const*, int); extern //scanner.c yypstate* apc_pstate; extern //scanner.c yycstate* apc_cstate; #define PUSHTOK(T,L) yypush_parse(apc_pstate, T, L, apc_cstate) /* Lexical analysis of a file Strips a filename to its base name, then sends it to lexer_lexstring before pushing a PATH token with the filename Returns the number of tokens pushed to the parser. */ int lexer_lexfile ( uint8_t const* filename ) { uint8_t const* last_period,* iter; int ntok; last_period = NULL; for (iter = filename; *iter; iter++) if (*iter == '.') last_period = iter; if (last_period) { ntok = lexer_lexstring(filename, (int)(last_period - filename)); PUSHTOK(PATH,filename); return ntok + 1; } return lexer_lexstring(filename, (int)(iter - filename)); }