Ask coding questions

← Back to all posts
I'm Trying To Make A Custom Parser In JS, I need help with a piece of regex
h
Battledash2 (79)

Hello there! I need help with finding any thing around the lines of var(varName), I got this working but if I do var(var(otherVarName)) it'll end at var(var(otherVarName) and miss the ) and I know this is because I'm using the "lazy" operator (?) but if I don't it will end up selecting everything inside of the -'s (for example, u wouldn't actually need -'s):

print: -var(varName) Hello, World! var(otherVarName)-

and I really don't want that!

All Help Would Be Appreciated :D

My Regex:

/var\(\(.*?))/gm // Get Vars
/var (.*) = (.*)/gm // Set Vars
Comments
hotnewtop
Coder100 (16757)

um why would you use regex like that whatt

Battledash2 (79)

??
I like using regex, it just never works >:( @Coder100

Coder100 (16757)

lol, the thing is, you can't make a language using only replace @Battledash2

Battledash2 (79)

lol the thing is, i'm not. I'm using split xDDDD

replace is only for the variables and making it readable by the computer (removing all backspaces and replacing them with semi-colons) so you can run theRecievedText.split(';') to get a list of commands. @Coder100

Im trying to say, I BARELY use much regex.

Battledash2 (79)

You didn't even go through the 300 lines of code :/ (xD) @Coder100

Battledash2 (79)

All of the juicy stuff happens in the function "parse" @Coder100

Battledash2 (79)

Look closely, barely using replace/regex:

function parse(ctr, drdv=false) {
    if(!drdv) {
        error = '';
        jsCode = '';
        ret = '';
        variables = {};
    }

    $('#fin').style.color = 'black';
    var recievedCode = ctr || $('#code').value;
    

    recievedCode = recievedCode
        .replace(/\/\/([^\n]+)/gmi, '')
        .replace(/([^;])\n/gmi, '$1;')
        .replace(/;\n/gmi, ';')
        .replace(/\n/gmi, ''); // Making it readable by the parser.

    var parts = recievedCode.split(';');
    var cmd = [];

    for(var i = 0; i < parts.length; i++) {
        cmd[i] = parts[i];


        if(cmd[i] == null || cmd[i] == '') {
            cmd.splice(i, 1);
        }
    }

    function err(rsn) {
        error = rsn;
        console.error(rsn);
    }

    for(var i = 0; i < cmd.length; i++) {
        let rcmd = cmd[i] || '';
        let csplit = rcmd.split(':') || [];
        for(var o = 0; o < csplit.length; o++) {
            if(csplit[o] == null || csplit[o].trim() == '') {
                csplit.splice(o, 1);
            } else {
                csplit[o] = csplit[o].trim();
            }
        }
        var rsplit = rcmd.split('=');
        for(var o = 0; o < rsplit.length; o++) {
            if(rsplit[o] == null || rsplit[o].trim() == '') {
                rsplit.splice(o, 1);
            } else {
                rsplit[o] = rsplit[o].trim();
            }
        }
        function setVariable(match, name, value) {
            variables[name] = value.replace(/var\((.*)\)/gm, getVariable);
            // console.log(name + ' = ' + value)
            return match;
        }
        function getVariable(match, name) {
            if(variables[name]) {
                return variables[name];
            } else if(getCookie(name)) {
                return getCookie(name);
            }

            err('Unkown Variable "'+name+'');
            return match;
        }
        function getVarM(name) {
            if(variables[name]) {
                return variables[name];
            } else if(getCookie(name)) {
                return getCookie(name);
            }
        }
        function varC() {
            rcmd = rcmd.replace(/var (.*) = (.*)/gm, setVariable);
            ret = ret.replace(/var (.*) = (.*)/gm, setVariable);
            
            ret = ret.replace(/var\((.*)\)/gm, getVariable);
            rcmd = rcmd.replace(/var\((.*)\)/gm, getVariable);

            // console.log(ret, jsCode, rcmd)
        }


        if(csplit[0] == 'print') {
            if(csplit[1] != null && csplit[1] != '') {
                let tts = csplit.splice(1).join(':').replace(/var\((.*)\)/gm, getVariable);
                jsCode += 'console.log("'+tts+'")\n';
                ret += tts + '\n';
                varC();
            } else {
                err('UncaughtError: Missing Argument.');
            }
        } else if(csplit[0] == 'ignore') {

        } else if(csplit[0] == 'alert') {
            if(csplit[1] != null && csplit[1] != '') {
                let tts = csplit.splice(1).join(':').replace(/var\((.*)\)/gm, getVariable);
                jsCode += 'alert("'+tts+'")\n';
                varC();
            } else {
                err('UncaughtError: Missing Argument.');
            }
        } else if(csplit[0] == 'cookie') {
            if(csplit[1] != null && rsplit[1] != null) {
                var rsplit2 = csplit[1].split('=');
                // console.log(//rsplit2, csplit)
                let length = rsplit2.length || 0;

                for(var y = 0; y < length; y++) {
                    if(rsplit2[y] == null || rsplit2[y].trim() == '') {
                        rsplit2.splice(y, 1);
                    }
                }

                if(rsplit2[0] != null && rsplit[1] != null && rsplit2[1] != null) {
                    var time;
                    var s3 = rsplit2[1].split(',');
                    // console.log(s3)
                    let length = s3.length || 0;

                    for(var y = 0; y < length; y++) {
                        if(s3[y] == null || s3[y].trim() == '') {
                            s3.splice(y, 1);
                        }
                    }

                    if(s3[1]) {
                        time = s3[1];
                        // console.log(rsplit2)
                        setCookie(rsplit2[0], s3[0], time);
                    } else {
                        err('UncaughtError: Missing Argument 3.');
                        console.log('quack')
                    }
                } else {
                    // console.log('Debug Log Recieved.')
                    // console.log(rsplit2[0], rsplit[1], rsplit2[1])
                    err('UncaughtError: Missing Argument 2.');
                }
            } else {
                err('UncaughtError: Missing Argument 1.')
            }
        } else if(rsplit[0] == 'prompt') {
            if(rsplit[1] != null) {
                let psplt = rsplit[1].split('~:');

                if(psplt[1] != null) {
                    function doPrompt() {
                        var p = prompt(psplt[0].toString().replace(/var\((.*)\)/gm, getVariable))
                        if(p != null && p != '') {
                            variables.lastPrompt = p;
                            parse(psplt.splice(1).join('~:').toString().replace(/var\((.*?)\)/gm, getVariable), true);
                        } else {
                            doPrompt();
                        }
                    }
                    doPrompt();
                    
                } else {
                    err('UncaughtError: Missing Argument.');
                }
            } else {
                err('UncaughtError: Missing Argument.');
            }
        } else if(rsplit[0] == 'if') {
            if(rsplit[1] != null && rsplit[1] != '') {
                let recTr = rsplit.splice(2).join('=');
                let rsplite = recTr.split('~:');
                let rspliter = rsplite.splice(1).join('~:');

                

                if(getVarM(rsplit[1])) {
                    parse(rsplite[0], true);
                } else {
                    if(rspliter) {
                        parse(rspliter, true);
                    }
                }

                // // // // debug // // // //
                // console.log(rsplit.splice(2).join('='));
                // console.log(rsplite);
                // console.log(rspliter);
                // console.log(rsplit);

                // getVarM()
            } else {
                err('UncaughtError: Missing Argument.');
            }
        } else {
            var ukc = true;
            
            function setVariable(match, name, value) {
                variables[name] = value;
                ukc = false;
                // console.log(name + ' = ' + value)
                return match;
            }
            function getVariable(match, name) {
                ukc = false;
                if(variables[name]) {
                    return variables[name];
                }

                err('Unkown Variable');
                return match;
            }

            rcmd = rcmd.replace(/var (.*) = (.*)/gm, setVariable);
            rcmd = rcmd.replace(/var\((.*)\)/gm, getVariable);
            jsCode = jsCode.replace(/var (.*) = (.*)/gm, setVariable);
            jsCode = jsCode.replace(/var\((.*)\)/gm, getVariable);
            ret = ret.replace(/var (.*) = (.*)/gm, setVariable);
            ret = ret.replace(/var\((.*)\)/gm, getVariable);


            if(ukc) err('SyntaxError: Unknown Command');
        }

    }

    if(error != '') {
        $('#fin').innerHTML = error;
        $('#fin').style.color = 'red';
        return error;
    } else {
        $('#fin').innerText = ret.toString();
        eval(jsCode);
    }
}

:) (I use replace for the variables quite a bit actually but what I mean is I don't use it for the actual parsing.) @Coder100

Battledash2 (79)

Here's an example of some code that would work in my interpreter:

prompt=Hello, What's Your Name?~:alert: Hello, var(lastPrompt)

It would give you a prompt saying Hello, What's Your Name? then when you finish the prompt (typing it in etc) it says Hello, ${txtyouentered}
@Coder100

Battledash2 (79)

A More "Advanced" Code For My Interpreter:

var start = Hello, What's Your

prompt=var(start) Name?~:ignore
var n = var(lastPrompt)
prompt=var(start) Message?~:ignore
var m = var(lastPrompt)

print: var(n)->
print: var(m)

And you can't have 2 variables in 1 command so I need help with that.

Well it does work, but you can't select a variable with a variable like: var(var(lastPrompt))
@Coder100

Battledash2 (79)

I think I found a solution:

/var\([^ \n]+\)/gm

@Coder100

Coder100 (16757)

but that will also capture newlines, do:

/var\([^\s]+\)/gm

instead
@Battledash2

Battledash2 (79)

?? no i changed it to this:

/var\(([^ \n]+)\)/gm

@Coder100

Battledash2 (79)

Look This Now Works:

var hi = hello
var sel = hi

print: var(var(sel))

It prints out hello

This works two!

var hi = Hello!

prompt=var(hi) What Variable Do You Want?~:ignore

if=var(lastPrompt)=print: var(var(lastPrompt))_~:_print: Not A Variable

@Coder100

Battledash2 (79)

This still isn't enough!! I need it so stuff like this works:

var(var(my variable))

See the space?

Ughhh regex so annnoying.. plez halp

i made a mini documentation for my parser
@Coder100