Last active
July 31, 2019 21:11
-
-
Save DreamVB/9679543de25e08fda522423e6f0be706 to your computer and use it in GitHub Desktop.
Simple Quick Recursive Descent Parser
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| 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