Skip to content

Instantly share code, notes, and snippets.

@DreamVB
Last active July 31, 2019 21:11
Show Gist options
  • Select an option

  • Save DreamVB/9679543de25e08fda522423e6f0be706 to your computer and use it in GitHub Desktop.

Select an option

Save DreamVB/9679543de25e08fda522423e6f0be706 to your computer and use it in GitHub Desktop.
Simple Quick Recursive Descent Parser
/*
Recursive Descent Parser
by DreamVB
*/
#include <stdio.h>
#include <stdlib.h>
#define MAX_TOKEN 255
char *src;
char ch = '\0';
char token[MAX_TOKEN];
int pi = 0;
int ti = 0;
enum T_TOKEN{
DIGIT = 1,
ALPHA,
QSTRING,
SYMBOL,
EOP
}token_type;
int buffer_size = 0;
int get_filesize(char *Filename){
FILE *fp = NULL;
int f_size = 0;
fp = fopen(Filename,"rb");
//Move to end of file
fseek(fp,0,SEEK_END);
//Get the size of the file
f_size = ftell(fp);
//Close file
fclose(fp);
//Return file length
return f_size;
}
void _GetProgramData(char * Filename){
FILE *fp = NULL;
int ti = 0;
char ch = '\0';
//Open source file
fp = fopen(Filename,"rb");
//While not end of file read data.
while(!feof(fp)){
if(!feof(fp)){
//Read char
ch = fgetc(fp);
src[ti] = ch;
//INC ti
ti++;
}
}
fclose(fp);
src[ti - 1] = '\0';
}
int IsSym(char c){
if(c == '+' || c == '-' || c == '*'
|| c == '/' || c == '='
|| c == '<' || c == '>' || c == '%'
|| c == '^' || c == '$' || c == '&'
|| c == '(' || c == ')'){
return 1;
}else{
return 0;
}
}
void CheckEOP(){
if(pi >= buffer_size){
token_type = EOP;
}
}
void get_token(){
ti = 0;
CheckEOP();
//Skip spaces
while(isspace(src[pi]) && (pi < buffer_size)){
pi++;
}
//Check for alpha
if(isalpha(src[pi])){
while(isalpha(src[pi])){
token[ti] = src[pi];
ti++;
pi++;
}
token[ti] = '\0';
token_type = ALPHA;
//Check for quotes strings eg "hello world"
}else if(src[pi] == '\"'){
pi++;
while(src[pi] != '\"'){
token[ti] = src[pi];
ti++;
pi++;
}
token[ti] = '\0';
token_type = QSTRING;
pi++;
//Check for digits
}else if(isdigit(src[pi])){
while(isdigit(src[pi])){
token[ti] = src[pi];
ti++;
pi++;
}
token[ti] = '\0';
token_type = DIGIT;
}
//Check for symbols
else if(IsSym(src[pi])){
while(IsSym(src[pi])){
token[ti] = src[pi];
pi++;
ti++;
}
token[ti] = '\0';
token_type = SYMBOL;
}else{
//Check if we have not hit the end of the code.
CheckEOP();
}
}
int main(int argc, char**argv)
{
if(argc == 1){
printf("TokenScan.exe program_name.bat\n");
return 0;
}
//Get size of file.
buffer_size = get_filesize(argv[1]);
//Check we have a vaild length
if(buffer_size == 0){
printf("Program Data Not Found.\n");
return 0;
}
//Resize program data array
src = malloc(buffer_size);
//Get program file data.
_GetProgramData(argv[1]);
//Get first token
get_token();
//While we are not at the end of the program code
while(token_type != EOP){
//Print token and token type
printf("Token : %s\nType : %d\n\n",token,token_type);
//Get next token.
get_token();
}
//Cleat up.
free(src);
free(token);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment