X-Git-Url: https://www.kengrimes.com/gitweb/?p=henge%2Fwebcc.git;a=blobdiff_plain;f=src%2Fapc%2Flexer.c;fp=src%2Fapc%2Flexer.c;h=0d408b9daff8ee3af471912436fbb34d6ffb3d22;hp=0000000000000000000000000000000000000000;hb=c6658233045b0039b328394f38b3297501df0c30;hpb=cc8aed5b4a92dcd55e376e263090e0640b049351 diff --git a/src/apc/lexer.c b/src/apc/lexer.c new file mode 100644 index 0000000..0d408b9 --- /dev/null +++ b/src/apc/lexer.c @@ -0,0 +1,92 @@ +/*!@file + \brief lexical analyzer implementation for APC + \details this lexer scans a root directory given from the command line + for subdirectories and files structured for the APC grammar. + \author Jordan Lavatai + \date Aug 2016 + ----------------------------------------------------------------------------*/ +//stdc +#include +#include +#include +//posix +#include +#include +//bison +#include "fileparser.tab.h" +#define TOKEN_BUF_SIZE 1024 +#define DIRP_STACK_SIZE 512 + +int lexer_init(void); +int lexer(void); + +static +int lexer_scan(void); + +static +int token_buf[TOKEN_BUF_SIZE], *tbp, *tbx; +static +DIR* dirp_stack[DIRP_STACK_SIZE], *dsp; + +/* Initialize pointers */ +int +lexer_init() +{ tbp = tbx = token_buf; + dsp = dirp_stack; + return 0; +} + +/* Returns a token identifier and sets yylval */ +int +lexer() +{ if (lexer_scan() == 0) + return 0; + yylval = *tbp++; + return *tbp++; +} + +/* Scanner + Scans a filename from its alphabetically ordered list of file elements + and tokenizes the result. If the file list is empty, then the stack of + directory elements will be popped and processed as they are encountered. + + Returns the number of tokens generated. +*/ +#define MAX_ENTITIES 256 +static +int lexer_scan() +{ static struct dirent* entity; + static struct dirent* files[MAX_ENTITIES]; + static struct dirent* dirs = files + MAX_ENTITIES - 1; + static int num_files = 0; + static int num_dirs = 0; + + //sort out files and directories, grow directories from bottom up + while ((entity = readdir(dirp)) != NULL) + { switch (entity->d_type) + { case DT_LNK: + case DT_REG: + files[num_files++] = entity; + break; + case DT_DIR: + *(dirs - num_dirs++) = entity; + break; + case DT_UNKNOWN: + default: + printf("Ignoring unknown file: %s\n", entity->d_name); + break; + } + } + if (errno) + perror("readdir"); + qsort(&files[0], num_files, sizeof struct dirent*, qalpha); + num_ents = scandirat(dirfd, ".", &namelist, scanfilter, scancompar); + if (num_ents < 0) + { perror("scandirat"); + return -1; + } + //process files + + //recurse into directories + +}