APC main driver
[henge/webcc.git] / src / apc / lexer.c
1 /*!@file
2 \brief lexical analyzer implementation for APC
3 \details this lexer scans a root directory given from the command line
4 for subdirectories and files structured for the APC grammar.
5 \author Jordan Lavatai
6 \date Aug 2016
7 ----------------------------------------------------------------------------*/
8 //stdc
9 #include <stdio.h>
10 #include <string.h>
11 #include <errno.h>
12 //posix
13 #include <unistd.h>
14 #include <stdlib.h>
15 //bison
16 #include "fileparser.tab.h"
17 #define TOKEN_BUF_SIZE 1024
18 #define DIRP_STACK_SIZE 512
19
20 int lexer_init(void);
21 int lexer(void);
22
23 static
24 int lexer_scan(void);
25
26 static
27 int token_buf[TOKEN_BUF_SIZE], *tbp, *tbx;
28 static
29 DIR* dirp_stack[DIRP_STACK_SIZE], *dsp;
30
31 /* Initialize pointers */
32 int
33 lexer_init()
34 { tbp = tbx = token_buf;
35 dsp = dirp_stack;
36 return 0;
37 }
38
39 /* Returns a token identifier and sets yylval */
40 int
41 lexer()
42 { if (lexer_scan() == 0)
43 return 0;
44 yylval = *tbp++;
45 return *tbp++;
46 }
47
48 /* Scanner
49 Scans a filename from its alphabetically ordered list of file elements
50 and tokenizes the result. If the file list is empty, then the stack of
51 directory elements will be popped and processed as they are encountered.
52
53 Returns the number of tokens generated.
54 */
55 #define MAX_ENTITIES 256
56 static
57 int lexer_scan()
58 { static struct dirent* entity;
59 static struct dirent* files[MAX_ENTITIES];
60 static struct dirent* dirs = files + MAX_ENTITIES - 1;
61 static int num_files = 0;
62 static int num_dirs = 0;
63
64 //sort out files and directories, grow directories from bottom up
65 while ((entity = readdir(dirp)) != NULL)
66 { switch (entity->d_type)
67 { case DT_LNK:
68 case DT_REG:
69 files[num_files++] = entity;
70 break;
71 case DT_DIR:
72 *(dirs - num_dirs++) = entity;
73 break;
74 case DT_UNKNOWN:
75 default:
76 printf("Ignoring unknown file: %s\n", entity->d_name);
77 break;
78 }
79 }
80 if (errno)
81 perror("readdir");
82 qsort(&files[0], num_files, sizeof struct dirent*, qalpha);
83 num_ents = scandirat(dirfd, ".", &namelist, scanfilter, scancompar);
84 if (num_ents < 0)
85 { perror("scandirat");
86 return -1;
87 }
88 //process files
89
90 //recurse into directories
91
92 }