Antlr4 основанный на событиях посетитель (javascript) - PullRequest
0 голосов
/ 27 апреля 2018

Я пытаюсь сделать свой собственный язык с antlr4. Мне удалось создать свою собственную грамматику и создать своего посетителя, который составляет мой язык.

Теперь я пытаюсь создать простой графический интерфейс для моего языка. Однако меня совершенно смущает мысль, как это сделать, или если это вообще возможно. Вот ситуация.

Мой язык поддерживает простые объявления функций. Допустим, у меня есть простая текстовая область на моей html-странице, которая загружает мой анализатор сборки кода и обычные вещи antlr. После этого я звоню посетителю, который запускает мой код.

    var chars = new antlr4.InputStream(inputText);
    var lexer = new TinyLexer(chars);
    var tokens = new antlr4.CommonTokenStream(lexer);
    var parser = new TinyParser(tokens);
    parser.buildParseTrees = true;
    var tree = parser.parse();
    var visitor = new Visitor();
    visitor.visit(tree);

Мой язык:

def rock()
 println("You selected ROCK")
end

rock()

Это работает и выводит сообщение в мои окна вывода. Однако теперь я добавил поддержку кнопок на моем языке, которые могут вызывать некоторые функции при нажатии. Это создаст простую HTML-кнопку, которая при нажатии вызывает функцию rock ():

Button btn1("MyButton", "rock()")

Моя идея была примерно такой при посещении newButtonCall

Visitor.prototype.visitNewButtonCall = function (ctx) {
    var buttonId = ctx.Identifier().getText();
    var buttonName = this.visit(ctx.exprList().expression(0));
    var buttonFunction = this.visit(ctx.exprList().expression(1));

    var button = document.createElement('button');
    button.onclick = function(){
            if(buttonFunction in this.myFunctions){
                return this.myFunctions[buttonFunction].invoke();
            }
        };
};

Конечно, это не может работать, потому что посетитель завершил свою работу, и он больше не хранит ссылки на что-либо, поэтому this.myFunctions больше не существует. Однако я понятия не имею, как заставить это работать (за исключением повторного вызова всего процесса посетителя).

Любая помощь? Большое спасибо!

1 Ответ

0 голосов
/ 28 апреля 2018

Конечно, это не может работать, потому что посетитель закончил свою работу, и он больше не хранит ссылки на что-либо, поэтому this.myFunctions больше не существует

Это не то, почему это не работает. Функции могут получать доступ к объектам из окружающей их области, и эти объекты будут жить столько же, сколько и функция.

Ваш код не работает, потому что на кнопке будет вызываться onclick, поэтому кнопка будет this, а не ваш посетитель. Вы можете присвоить this переменной, пока она все еще ссылается на посетителя (т.е. вне функции onclick), а затем использовать эту переменную вместо this:

var visitor = this;
button.onclick = function(){
    if(buttonFunction in visitor.myFunctions){
        return visitor.myFunctions[buttonFunction].invoke();
    }
};

PS: Примечание по терминологии: То, что вы пишете, не является компилятором. Компилятор генерирует код на другом языке (часто это машинный код / ​​сборка, но в контексте Интернета языки также часто компилируются в JavaScript (или веб-сборку для языков без GCed)). Ваш посетитель выполняет код напрямую, что делает его интерпретатором.

...