fe4eff780294cd215d7880b23c867e0cdbc3b441
[henge/apc.git] / src / lexer.c
1 /*!@file
2 \brief lexical analyzer implementation for APC
3 \details The lexer manages two FIFO stacks. One for maintaining tokens, the
4 other for maintaining a list of files to be scanned. During
5 execution, the lexer will return a token from its token queue if any
6 are present. If not, the lexer will will pop an element from its
7 file queue to 'scanner' to be tokenized. If the file queue is empty,
8 the lexer will instead call 'parsedir' to traverse the directory tree
9 and tokenize the results. If 'parsedir' does not generate any new
10 tokens, we are done.
11 \author Jordan Lavatai
12 \date Aug 2016
13 ----------------------------------------------------------------------------*/
14 /* Standard */
15 #include <stdio.h>
16 #include <string.h>
17 #include <stdint.h>
18 #include <errno.h>
19 /* Posix */
20 #include <unistd.h>
21 #include <unitypes.h>
22 #include <unistr.h>
23 #include <uniconv.h>
24 #include <uniname.h>
25 #include <unistdio.h>
26 #include <stdlib.h>
27 #include <dirent.h>
28 /* Local */
29 #include "apc.h"
30 #include "parser.tab.h"
31 /* Public */
32 int lexer_lexfile(uint8_t const*);
33 /* Private */
34 extern //lexer.rl
35 int lexer_lexstring(uint8_t const*, int);
36 extern //scanner.c
37 yypstate* apc_pstate;
38 extern //scanner.c
39 yycstate* apc_cstate;
40 #define PUSHTOK(T,L) yypush_parse(apc_pstate, T, L, apc_cstate)
41
42 /* Lexical analysis of a file
43 Strips a filename to its base name, then sends it to lexer_lexstring before
44 pushing a PATH token with the filename
45 Returns the number of tokens pushed to the parser.
46 */
47 int lexer_lexfile
48 ( uint8_t const* filename )
49 { uint8_t const* last_period,* iter;
50 int ntok;
51 union YYSTYPE tok_val;
52 last_period = NULL;
53 for (iter = filename; *iter; iter++)
54 if (*iter == '.')
55 last_period = iter;
56 if (last_period)
57 { ntok = lexer_lexstring(filename, (int)(last_period - filename));
58 tok_val.str = filename;
59 PUSHTOK(PATH,&tok_val);
60 return ntok + 1;
61 }
62 return lexer_lexstring(filename, (int)(iter - filename));
63 }