TheSaint Posted May 30, 2021 Posted May 30, 2021 5 hours ago, TheDcoder said: Sorry guys but it looks like I need a couple more days before I can start work on the parser. Don't worry bud, I have faith in you, and have already come to terms with the imminent release of EasyCodeIt, just after my demise, some time in the future (far hopefully), in the full knowledge you will dedicate it to my memory. TheDcoder 1 Make sure brain is in gear before opening mouth! Remember, what is not said, can be just as important as what is said. Spoiler What is the Secret Key? Life is like a Donut If I put effort into communication, I expect you to read properly & fully, or just not comment. Ignoring those who try to divert conversation with irrelevancies. If I'm intent on insulting you or being rude, I will be obvious, not ambiguous about it. I'm only big and bad, to those who have an over-active imagination. I may have the Artistic Liesense to disagree with you. TheSaint's Toolbox (be advised many downloads are not working due to ISP screwup with my storage)
TheDcoder Posted May 30, 2021 Author Posted May 30, 2021 No way! I promise to finish it before your time runs out... so that you can finally enjoy the fruits of Linux without any restrictions Disclaimer: The above mentioned text should not be, in any way, be constructed into a contract, promise, guarantee or any other type of bond with liability seadoggie01 and TheSaint 2 EasyCodeIt - A cross-platform AutoIt implementation - Fund the development! (GitHub will double your donations for a limited time) DcodingTheWeb Forum - Follow for updates and Join for discussion
TheSaint Posted May 30, 2021 Posted May 30, 2021 2 hours ago, TheDcoder said: so that you can finally enjoy the fruits of Linux without any restrictions Inherent restrictions of Linux aside. seadoggie01 and TheDcoder 1 1 Make sure brain is in gear before opening mouth! Remember, what is not said, can be just as important as what is said. Spoiler What is the Secret Key? Life is like a Donut If I put effort into communication, I expect you to read properly & fully, or just not comment. Ignoring those who try to divert conversation with irrelevancies. If I'm intent on insulting you or being rude, I will be obvious, not ambiguous about it. I'm only big and bad, to those who have an over-active imagination. I may have the Artistic Liesense to disagree with you. TheSaint's Toolbox (be advised many downloads are not working due to ISP screwup with my storage)
TheDcoder Posted May 30, 2021 Author Posted May 30, 2021 8 hours ago, TheSaint said: Inherent restrictions of Linux aside. Now you are just being delusional, there is no such thing Anything and everything is possible in Linux, unlike Windows where you are restricted to the capabilities it provides. Linux is more open and innovative, anyone can extended it to make it work however they like. You just need to know how things work in Linux, which is different from Windows obviously. seadoggie01 and TheSaint 1 1 EasyCodeIt - A cross-platform AutoIt implementation - Fund the development! (GitHub will double your donations for a limited time) DcodingTheWeb Forum - Follow for updates and Join for discussion
TheSaint Posted May 31, 2021 Posted May 31, 2021 Yeah yeah, believe what you want nerdy. seadoggie01 and TheDcoder 2 Make sure brain is in gear before opening mouth! Remember, what is not said, can be just as important as what is said. Spoiler What is the Secret Key? Life is like a Donut If I put effort into communication, I expect you to read properly & fully, or just not comment. Ignoring those who try to divert conversation with irrelevancies. If I'm intent on insulting you or being rude, I will be obvious, not ambiguous about it. I'm only big and bad, to those who have an over-active imagination. I may have the Artistic Liesense to disagree with you. TheSaint's Toolbox (be advised many downloads are not working due to ISP screwup with my storage)
Skysnake Posted June 9, 2021 Posted June 9, 2021 I cannot really develop, but I am willing to test. If you need anything. Skysnake argumentum and TheDcoder 2 Skysnake Why is the snake in the sky?
TheDcoder Posted June 10, 2021 Author Posted June 10, 2021 Thanks @Skysnake, any help is appreciated, I am working on the new parser right now and I will certainly need some testers in the coming weeks. Why not join the forum (link in signature) to keep up to date? I am planning to coordinate all testing and development there. EasyCodeIt - A cross-platform AutoIt implementation - Fund the development! (GitHub will double your donations for a limited time) DcodingTheWeb Forum - Follow for updates and Join for discussion
JockoDundee Posted June 10, 2021 Posted June 10, 2021 18 hours ago, Skysnake said: I cannot really develop, but I am willing to test. Now that’s impressive! Developers can be like electric guitar shredders, producing a dazzling but often ego-driven performance. And everyone wants to be one. Good QA people are like bassists, committed to the groove, listening to the other players. And so hard to find a good one! Skysnake and TheDcoder 1 1 Code hard, but don’t hard code...
TheDcoder Posted June 29, 2021 Author Posted June 29, 2021 Quote Damn, another month already? I got way too caught up with work and never found the time to actually start writing code... until today I started small, rewrote the OG version of the parser in flex: %{ #include <stdlib.h> #include <string.h> char *token_str = NULL; size_t token_len = 0; #define YY_USER_ACTION free(token_str); token_str = strndup(yytext, token_len = yyleng); enum { // Token Types UNKNOWN = 420, WS, COMMENT, DIRECTIVE, NUMBER, STRING, BOOL, WORD, MACRO, VARIABLE, OPERATOR, BRACKET, DOT, COMMA, }; %} WS [ \t\r\n]+ NL \r?\n? COD [;#][^\r\n]* %% {WS} ; [;#][^\r\n]* return *yytext == ';' ? COMMENT : DIRECTIVE; . return UNKNOWN; %% #include <stddef.h> #include <stdio.h> static void print_token(char *str, size_t len, int type) { puts("---### TOKEN ###---"); char *token_type; switch (type) { case UNKNOWN: token_type = "Unknown"; break; case WS: token_type = "Whitespace"; break; case COMMENT: token_type = "Comment"; break; case DIRECTIVE: token_type = "Directive"; break; case NUMBER: token_type = "Number"; break; case STRING: token_type = "String"; break; case WORD: token_type = "Word"; break; case MACRO: token_type = "Macro"; break; case VARIABLE: token_type = "Variable"; break; case OPERATOR: token_type = "Operator"; break; case BRACKET: token_type = "Bracket"; break; case DOT: token_type = "Dot"; break; case COMMA: token_type = "Comma"; break; default: token_type = "Unnamed"; break; } fputs("Type: ", stdout); puts(token_type); fputs("Data: ", stdout); puts(str); } int main(void) { int type; for (;;) { type = yylex(); if (!type) break; print_token(token_str, token_len, type); } return 0; } At the moment it only supports comments and directives (which are basically the same), I believe that this is exactly what I started with when I wrote the first parser. Will post updates as I expand on the parser, a grammar definition will come soon once I am satisfied with the amount of tokens I can scan, shouldn't be much effort since it is all just regex. Here is how it works: TheDcoder@arch /m/d/P/C/E/parser (master)> flex lexer.l && cc lex.yy.c -lfl TheDcoder@arch /m/d/P/C/E/parser (master)> cat /tmp/comments.au3 | ./a.out ---### TOKEN ###--- Type: Directive Data: #include <test> ---### TOKEN ###--- Type: Comment Data: ; comment ---### TOKEN ###--- Type: Comment Data: ; comment 2 First we call flex to generate the actual C program and then we call cc() C compiler) to compile the program, by default it reads from standard input so we pass the contents of our comments.au3 with a pipe. Cheers everyone! Source: https://forum.dtw.tools/d/26-easycodeit-update-our-hand-written-parser-is-going-away/8 EasyCodeIt - A cross-platform AutoIt implementation - Fund the development! (GitHub will double your donations for a limited time) DcodingTheWeb Forum - Follow for updates and Join for discussion
TheDcoder Posted June 30, 2021 Author Posted June 30, 2021 Hi everyone, I already posted an update yesterday where I mentioned that I have started work on the new parser which uses Flex and Bison to generate C code for parsing. So far the experience has been very nice, I am able to test and develop things very fast compared to doing it all on my own. I have completed the initial version of the tokenizer/scanner/lexer, it should be able to scan all tokens which could possibly occur in a valid script %option noyywrap nodefault %{ #include <stdlib.h> #include <string.h> char *token_str = NULL; size_t token_len = 0; size_t comment_level = 0; //#define YY_USER_ACTION free(token_str); token_str = strndup(yytext, token_len = yyleng); #define YY_USER_ACTION token_str = yytext; token_len = yyleng; enum { // Token Types UNKNOWN = 420, WS, COMMENT, DIRECTIVE, NUMBER, STRING, BOOL, WORD, MACRO, VARIABLE, OPERATOR, BRACKET, DOT, COMMA, }; %} %x ML_COMMENT WS [ \t\r\n]+ NL \r?\n? DIGIT [0-9] XDIGIT [0-9A-Fa-f] QUOTE [\'\"] %% /* Whitespace */ {WS} ; /* Comment */ <INITIAL,ML_COMMENT>"#cs"|"#comment-start"{WS} {BEGIN ML_COMMENT; ++comment_level;}; <ML_COMMENT>"#ce"|"#comment-end" if (--comment_level == 0) BEGIN INITIAL; <ML_COMMENT>(?s:.) ; [;#][^\r\n]* return *yytext == ';' ? COMMENT : DIRECTIVE; /* Number */ {DIGIT}+(\.{DIGIT}+(e{DIGIT}+)?)? return NUMBER; 0[xX]{XDIGIT}+ return NUMBER; /* String */ \"[^\n\"]*\" return STRING; \'[^\n\']*\' return STRING; /* Bool */ (?i:"True"|"False") return BOOL; /* Word */ [A-Za-z][A-Za-z0-9]* return WORD; /* Macro or Variable */ [@$][A-Za-z][A-Za-z0-9]* return *yytext == '@' ? MACRO : VARIABLE; /* Operator */ [+\-*/^&=<>?:] return OPERATOR; /* Misc */ [[\]()] return BRACKET; \. return DOT; \, return COMMA; /* Catch-all for everything else */ . return UNKNOWN; %% #include <stddef.h> #include <stdio.h> static void print_token(char *str, size_t len, int type) { puts("---### TOKEN ###---"); char *token_type; switch (type) { case UNKNOWN: token_type = "Unknown"; break; case WS: token_type = "Whitespace"; break; case COMMENT: token_type = "Comment"; break; case DIRECTIVE: token_type = "Directive"; break; case NUMBER: token_type = "Number"; break; case STRING: token_type = "String"; break; case BOOL: token_type = "Boolean"; break; case WORD: token_type = "Word"; break; case MACRO: token_type = "Macro"; break; case VARIABLE: token_type = "Variable"; break; case OPERATOR: token_type = "Operator"; break; case BRACKET: token_type = "Bracket"; break; case DOT: token_type = "Dot"; break; case COMMA: token_type = "Comma"; break; default: token_type = "Unnamed"; break; } fputs("Type: ", stdout); puts(token_type); fputs("Data: ", stdout); puts(str); } int main(void) { int type; for (;;) { type = yylex(); if (!type) break; print_token(token_str, token_len, type); } return 0; } I passed this "script" as the input: #cs #cs nested comment #ce #ce ; Calm Mints 42 0xDEADBEEF 3.14 6.02214076e23 "Hell'o World" '"To C or not to C"' True true fAlSe False tRUe @TheTruth $TheFact -((1 + 2) / 3) * 4 And here is the output: expandcollapse popup---### TOKEN ###--- Type: Comment Data: ; Calm Mints ---### TOKEN ###--- Type: Number Data: 42 ---### TOKEN ###--- Type: Number Data: 0xDEADBEEF ---### TOKEN ###--- Type: Number Data: 3.14 ---### TOKEN ###--- Type: Number Data: 6.02214076e23 ---### TOKEN ###--- Type: String Data: "Hell'o World" ---### TOKEN ###--- Type: String Data: '"To C or not to C"' ---### TOKEN ###--- Type: Boolean Data: True ---### TOKEN ###--- Type: Boolean Data: true ---### TOKEN ###--- Type: Boolean Data: fAlSe ---### TOKEN ###--- Type: Boolean Data: False ---### TOKEN ###--- Type: Boolean Data: tRUe ---### TOKEN ###--- Type: Macro Data: @TheTruth ---### TOKEN ###--- Type: Variable Data: $TheFact ---### TOKEN ###--- Type: Operator Data: - ---### TOKEN ###--- Type: Bracket Data: ( ---### TOKEN ###--- Type: Bracket Data: ( ---### TOKEN ###--- Type: Number Data: 1 ---### TOKEN ###--- Type: Operator Data: + ---### TOKEN ###--- Type: Number Data: 2 ---### TOKEN ###--- Type: Bracket Data: ) ---### TOKEN ###--- Type: Operator Data: / ---### TOKEN ###--- Type: Number Data: 3 ---### TOKEN ###--- Type: Bracket Data: ) ---### TOKEN ###--- Type: Operator Data: * ---### TOKEN ###--- Type: Number Data: 4 Which is very similar if not exactly the same as what our old parser would have produced The next step is to add support for including files (#include <...>) and then I will start work on the syntactic analysis, which is the actual "parsing" to convert list of words into actions. Hopefully I won't get held up by last time due to all the fatigue, using these tools should speed up the process significantly. Stay tuned for more updates this week! Source: https://forum.dtw.tools/d/28-easycodeit-update-flex-bison-parser TheSaint and JockoDundee 2 EasyCodeIt - A cross-platform AutoIt implementation - Fund the development! (GitHub will double your donations for a limited time) DcodingTheWeb Forum - Follow for updates and Join for discussion
JockoDundee Posted June 30, 2021 Posted June 30, 2021 (edited) Sorry for the reposting, but I wanted to see how well the C# highlighting did on a longer example. Edited June 30, 2021 by JockoDundee Deleted - no highlighting works or even helps. Code hard, but don’t hard code...
TheDcoder Posted July 17, 2021 Author Posted July 17, 2021 I got busy with work again, but luckily I didn't take another month long break I implemented support for #include and #include-once in the lexer, which means the lexer part is more or less done. Here is the new code: // lexer.l %option batch noyywrap nounput nodefault yylineno %{ /* * This file is part of EasyCodeIt. * * Copyright (C) 2021 TheDcoder <TheDcoder@protonmail.com> * * EasyCodeIt is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. */ #include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h> struct BufferStack { struct BufferStack *prev; char *code; YY_BUFFER_STATE state; size_t line; char *file; } *lex_buffer = NULL; static char *token_str = NULL; static size_t token_len = 0; static size_t comment_level = 0; #define YY_USER_ACTION token_str = yytext; token_len = yyleng; enum { // Token Types UNKNOWN = 420, WS, COMMENT, DIRECTIVE, NUMBER, STRING, BOOL, WORD, MACRO, VARIABLE, OPERATOR, BRACKET, DOT, COMMA, }; #include "parser.h" static source_reader read_file; static bool push_file(char *file); static bool pop_file(void); %} %x INCLUDE %x DIRECTIVE_LINE %x ML_COMMENT WS [ \t\r\n]+ NL \r?\n? DIGIT [0-9] XDIGIT [0-9A-Fa-f] QUOTE [\'\"] %% /* Include File */ /* TODO: #include-once */ ^"#include"{WS}[\"<] BEGIN INCLUDE; <INCLUDE>[^\n\">]+ { int c; while((c = input()) && c != '\n') /* Eat up any leftover junk in the include line */; ++yylineno; push_file(yytext); BEGIN INITIAL; } <INCLUDE>.|\n /* Ignore bad include line */; "#include-once" { /* Add current file to "include once" list*/ read_file(lex_buffer->file, NULL, true); } /* Whitespace */ {WS} ; /* Directive */ "#" {BEGIN DIRECTIVE_LINE; yymore();}; <DIRECTIVE_LINE>.+ {BEGIN INITIAL; return DIRECTIVE;}; /* Comment */ <INITIAL,ML_COMMENT>"#cs"|"#comment-start"{WS} {BEGIN ML_COMMENT; ++comment_level;}; <ML_COMMENT>"#ce"|"#comment-end" if (--comment_level == 0) BEGIN INITIAL; <ML_COMMENT>(?s:.) ; ;[^\r\n]* return COMMENT; /* Number */ {DIGIT}+(\.{DIGIT}+(e{DIGIT}+)?)? return NUMBER; 0[xX]{XDIGIT}+ return NUMBER; /* String */ \"[^\n\"]*\" return STRING; \'[^\n\']*\' return STRING; /* Bool */ (?i:"True"|"False") return BOOL; /* Word */ [A-Za-z][A-Za-z0-9]* return WORD; /* Macro or Variable */ [@$][A-Za-z][A-Za-z0-9]* return *yytext == '$' ? VARIABLE : MACRO; /* Operator */ /* IDEA: Make a parser mode where the character will be returned literally */ [+\-*/^&=<>?:] return OPERATOR; /* Misc */ [[\]()] return BRACKET; \. return DOT; \, return COMMA; /* Pop file and terminate if top-level */ <<EOF>> if(!pop_file()) yyterminate(); /* Catch-all for everything else */ . return UNKNOWN; %% #include <stddef.h> #include <stdio.h> static void print_token(char *str, int type) { puts("---### TOKEN ###---"); char *token_type; switch (type) { case UNKNOWN: token_type = "Unknown"; break; case WS: token_type = "Whitespace"; break; case COMMENT: token_type = "Comment"; break; case DIRECTIVE: token_type = "Directive"; break; case NUMBER: token_type = "Number"; break; case STRING: token_type = "String"; break; case BOOL: token_type = "Boolean"; break; case WORD: token_type = "Word"; break; case MACRO: token_type = "Macro"; break; case VARIABLE: token_type = "Variable"; break; case OPERATOR: token_type = "Operator"; break; case BRACKET: token_type = "Bracket"; break; case DOT: token_type = "Dot"; break; case COMMA: token_type = "Comma"; break; default: token_type = "Unnamed"; break; } fputs("Type: ", stdout); puts(token_type); fputs("Data: ", stdout); puts(str); } static void scan() { int type; for (;;) { type = yylex(); if (!type) break; print_token(token_str, type); } } bool parse(char *file, source_reader read_func) { read_file = read_func; push_file(file); scan(); return true; } static bool push_file(char *file) { size_t code_len; file = strdup(file); if (!file) return false; char *code = read_file(file, &code_len, false); if (!code) { free(file); return false; } struct BufferStack *new_buffer = malloc(sizeof *new_buffer); if (!new_buffer) return false; if (lex_buffer) lex_buffer->line = yylineno; *new_buffer = (struct BufferStack){ .prev = lex_buffer, .code = code, .state = yy_scan_buffer(code, code_len + 2), .file = file, .line = yylineno = 1, }; lex_buffer = new_buffer; yy_switch_to_buffer(lex_buffer->state); return true; } static bool pop_file() { struct BufferStack *prev_buffer = lex_buffer->prev; yy_delete_buffer(lex_buffer->state); free(lex_buffer->code); free(lex_buffer->file); free(lex_buffer); lex_buffer = prev_buffer; if (!lex_buffer) return false; yylineno = lex_buffer->line; yy_switch_to_buffer(lex_buffer->state); return true; } // eci.c /* * This file is part of EasyCodeIt. * * Copyright (C) 2020 TheDcoder <TheDcoder@protonmail.com> * * EasyCodeIt is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. */ static char *provide_code(char *file, size_t *size, bool once) { static char **once_list = NULL; static size_t once_list_len = 0; if (once) { // Add the file to "include once" list if (!once_list) { once_list = malloc(sizeof(char *)); if (!once_list) return NULL; ++once_list_len; } else { char **expanded_list = realloc(once_list, sizeof(char *) * ++once_list_len); if (!expanded_list) { --once_list_len; return NULL; } once_list = expanded_list; } once_list[once_list_len - 1] = strdup(file); return NULL; } else { // Skip if the file is in the "include once" list for (size_t i = 0; i < once_list_len; ++i) { if (strcmp(once_list[i], file) == 0) return NULL; } } // Open the source file char *code; FILE *source_file = fopen(file, "r"); if (source_file) { // Read the source file code = readfile(source_file); fclose(source_file); if (!code) die("Failed to read from source file!"); } else { code = malloc(1); code[0] = '\0'; } // The following is required because the parser needs a string with two null terminators *size = strlen(code); char *code_padded = realloc(code, *size + 2); if (!code_padded) { free(code); die("Failed to expand code buffer"); } code_padded[*size + 1] = '\0'; return code_padded; } int main(int argc, char *argv[]) { if (argc < 2) die("No arguments!"); // Parse the code parse(argv[1], provide_code); return EXIT_SUCCESS; } It was surprisingly easy to write a fully featured scanner/tokenizer in flex, guess I should have used it from the beginning. Now I can start work on the parser, hopefully it will be easy too, surely easier than writing it all manually 🥵 Source: https://forum.dtw.tools/d/28-easycodeit-update-flex-bison-parser/2 TheSaint 1 EasyCodeIt - A cross-platform AutoIt implementation - Fund the development! (GitHub will double your donations for a limited time) DcodingTheWeb Forum - Follow for updates and Join for discussion
jpm Posted July 17, 2021 Posted July 17, 2021 perhaps you miss "_" for VARIABLE I don't remember if MACRO can have them too Cheers TheDcoder 1
JockoDundee Posted July 17, 2021 Posted July 17, 2021 That comma after COMMA looks suspicious enum { // Token Types UNKNOWN = 420, WS, COMMENT, DIRECTIVE, NUMBER, STRING, BOOL, WORD, MACRO, VARIABLE, OPERATOR, BRACKET, DOT, COMMA, }; Code hard, but don’t hard code...
TheDcoder Posted July 17, 2021 Author Posted July 17, 2021 @jpm Oops, thanks, fixed /* Macro or Variable */ [@$][A-Za-z0-9_]+ return *yytext == '$' ? VARIABLE : MACRO; I also removed the limitation of not being able start a variable (or macro) with a digit, seems arbitrary as we already have a special symbol to denote a variable. 1 minute ago, JockoDundee said: That comma after COMMA looks suspicious LOL, indeed, normally it shouldn't be there but it is allowed since C99... patches are cleaner if you change those values because you don't have to add that extra comma at that time. JockoDundee 1 EasyCodeIt - A cross-platform AutoIt implementation - Fund the development! (GitHub will double your donations for a limited time) DcodingTheWeb Forum - Follow for updates and Join for discussion
JockoDundee Posted July 17, 2021 Posted July 17, 2021 9 hours ago, TheDcoder said: patches are cleaner if you change those values because you don't have to add that extra comma at that time. Wow, did not know. For me it’s often the other way around, in a loop I keep adding a comma to a concatenated string and then have to remember to lop off the last one. This is so brilliant it’s inspired me to song: Comma, Comma, Comma, Comma, Comma, Chameleon, You come and go, you come and go, Adapted from the Original TheSaint, TheDcoder and seadoggie01 3 Code hard, but don’t hard code...
TheSaint Posted July 17, 2021 Posted July 17, 2021 Boy, has George got a lot to answer for. But then maybe he's just a comma medium ... comedian for short ... who have poetic lie sense I guess. seadoggie01, TheDcoder and JockoDundee 2 1 Make sure brain is in gear before opening mouth! Remember, what is not said, can be just as important as what is said. Spoiler What is the Secret Key? Life is like a Donut If I put effort into communication, I expect you to read properly & fully, or just not comment. Ignoring those who try to divert conversation with irrelevancies. If I'm intent on insulting you or being rude, I will be obvious, not ambiguous about it. I'm only big and bad, to those who have an over-active imagination. I may have the Artistic Liesense to disagree with you. TheSaint's Toolbox (be advised many downloads are not working due to ISP screwup with my storage)
seadoggie01 Posted July 19, 2021 Posted July 19, 2021 On 7/17/2021 at 1:05 PM, JockoDundee said: Comma, Comma, Comma, Comma, Comma, Chameleon, You come and go, you come and go, Adapted from the Original Interestingly, I didn't realize until a few years ago that it wasn't Chame (like the first part of Chameleon). On 7/17/2021 at 7:51 PM, TheSaint said: comma medium ... comedian for short ... who have poetic lie sense This hurt to read TheDcoder 1 All my code provided is Public Domain... but it may not work. Use it, change it, break it, whatever you want. Spoiler My Humble Contributions:Personal Function Documentation - A personal HelpFile for your functionsAcro.au3 UDF - Automating Acrobat ProToDo Finder - Find #ToDo: lines in your scriptsUI-SimpleWrappers UDF - Use UI Automation more Simply-erKeePass UDF - Automate KeePass, a password managerInputBoxes - Simple Input boxes for various variable types
TheDcoder Posted July 24, 2021 Author Posted July 24, 2021 (edited) I think this is a new record, another update just before a week passes! 🥳 I am here to present the first prototype of the new bison parser: // parser.y /* * This file is part of EasyCodeIt. * * Copyright (C) 2021 TheDcoder <TheDcoder@protonmail.com> * * EasyCodeIt is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. */ %code top { #define _GNU_SOURCE /* Required to enable (v)asprintf */ #include <stdio.h> #include <string.h> } %union { char *str; } %token UNKNOWN %token WS %token COMMENT DIRECTIVE %token <str> NUMBER STRING BOOL %token WORD %token MACRO VARIABLE %token OPERATOR BRACKET DOT COMMA /* Operators */ %precedence '?' %precedence ':' %left AND "And" OR "Or" %left LT '<' GT '>' LTE "<=" GTE ">=" EQU '=' NEQ "<>" SEQU "==" %left '&' %left '+' '-' %left '*' '/' %left '^' %left NOT "Not" %precedence INVERSION %precedence GROUPING %type <str> expression %{ int yylex(); void yyerror(const char *s); %} %% exp-list: /* nothing */ | expression {puts($1);} expression: NUMBER {$$ = strdup($1);} | expression '?' expression ':' expression {asprintf(&$$, " (%s ? %s : %s) ", $1, $3, $5);} | expression "And" expression {asprintf(&$$, " (%s And %s) ", $1, $3);} | expression "Or" expression {asprintf(&$$, " (%s Or %s) ", $1, $3);} | expression '<' expression {asprintf(&$$, " (%s < %s) ", $1, $3);} | expression '>' expression {asprintf(&$$, " (%s > %s) ", $1, $3);} | expression '=' expression {asprintf(&$$, " (%s = %s) ", $1, $3);} | expression "<=" expression {asprintf(&$$, " (%s <= %s) ", $1, $3);} | expression ">=" expression {asprintf(&$$, " (%s >= %s) ", $1, $3);} | expression "<>" expression {asprintf(&$$, " (%s <> %s) ", $1, $3);} | expression "==" expression {asprintf(&$$, " (%s == %s) ", $1, $3);} | expression '&' expression {asprintf(&$$, " (%s & %s) ", $1, $3);} | expression '+' expression {asprintf(&$$, " (%s + %s) ", $1, $3);} | expression '-' expression {asprintf(&$$, " (%s - %s) ", $1, $3);} | expression '*' expression {asprintf(&$$, " (%s * %s) ", $1, $3);} | expression '/' expression {asprintf(&$$, " (%s / %s) ", $1, $3);} | expression '^' expression {asprintf(&$$, " (%s ^ %s) ", $1, $3);} | "Not" expression {asprintf(&$$, " (Not %s) ", $2);} | '-' expression %prec INVERSION {asprintf(&$$, " (-%s) ", $2);} | '(' expression ')' %prec GROUPING {asprintf(&$$, " (%s) ", $2);} %% void start_parser() { yyparse(); } void yyerror(char const *s) { fputs(s, stderr); fputs("\n", stderr); } This version can only handle numeric expressions, and the output is just a string with an excessive amount of brackets to show the correct order of evaluation. It ain't pretty but it does the job Here are a few sample inputs I tried: > echo '1 + 2' | ./eci /dev/fd/0 (1 + 2) > echo '-((1 + 2) / 3) * 4' | ./eci /dev/fd/0 ( (- ( ( ( (1 + 2) ) / 3) ) ) * 4) > echo '42 ? 123 ? 86 : -((1 + 2) / 3) * 4 : 007' | ./eci /dev/fd/0 (42 ? (123 ? 86 : ( (- ( ( ( (1 + 2) ) / 3) ) ) * 4) ) : 007) (the output is the line of text below the > shell prompt) Even though this is very primitive, it has served as proof that I can use bison to write a proper parser, now I can move onto the more intricate details of parsing such as evaluating values and constructing a syntax tree to represent the code. I will keep you guys updated on the progress, hope the next update comes as soon as this one 🤞 Source: https://forum.dtw.tools/d/28-easycodeit-update-flex-bison-parser/5 -- Also, If anyone has not noticed the new thread I created, please check it out: I am gathering community consensus on which features are more popular so that they can be prioritized accordingly. Edited July 24, 2021 by TheDcoder EasyCodeIt - A cross-platform AutoIt implementation - Fund the development! (GitHub will double your donations for a limited time) DcodingTheWeb Forum - Follow for updates and Join for discussion
JockoDundee Posted July 28, 2021 Posted July 28, 2021 So just for the hell of it I installed gcc under wsl and compiled an exe that was nothing more than a for loop to 1000000000. It ran 15 times faster than the same functionality via an autoit executable. Not dissing autoit, but whats your take on the speed differential on something super primitive like a for loop? I'm sure that gcc optimizes it well, but how much is there to do? Do you think, in this case, that its because of variant math that eats up the time? TheDcoder 1 Code hard, but don’t hard code...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now