ParseKit анализ JavaScript

Я хотел бы использовать ParseKit для анализа некоторого кода JavaScript. Я получил настройку фреймворка с грамматикой javascript, но я не могу понять, какой путь выбрать для анализа кода. Дело в том, что я хотел бы, в конце концов, получить, например, массив всех глобально объявленных var (так что var определены вне функции). Но я не могу понять, как я могу получить этот результат! Я читал здесь много вопросов о переполнении стека и вижу, что мне как-то, вероятно, следует использовать стек и цель ассемблера, но дело в том, что функция обратного вызова вызывается, когда она достигает конца блока функций, поэтому все определения переменных передаются обратным вызовам раньше. Как я узнаю, что когда я получаю обратный вызов для переменной внутри функции, она внутри?

var i = 0;
function test(){
   var u = 0;
}

Здесь я хочу найти меня, например, а не вы. Но обратные вызовы

#1  Found var i
#2  Found var u
#3  Found func test

Jonas

1 ответ

Решение

Разработчик ParseKit здесь.

Во-первых, зацените этот ответ на другой, несколько связанный с ParseKit вопрос. Там есть много соответствующей информации (и в других ответах, связанных там).

Затем, для вашего конкретного примера, ключ должен установить флаг всякий раз, когда function начинается, и очистить флаг, когда он заканчивается. Так что всякий раз, когда var decl совпадает, просто отметьте флаг. Если флаг установлен, тогда игнорируйте var decl. Если флаг не установлен, сохраните его.

Чрезвычайно важно, чтобы упомянутый мной флаг был сохранен на PKAssembly объект, который является аргументом для ваших функций обратного вызова ассемблера. Вы не можете хранить этот флаг как ivar или глобальную переменную. Это не сработает (подробности см. В предыдущих ссылках).

Вот несколько примеров обратных вызовов для установки флага и соответствия var decls. Они должны дать вам представление о том, о чем я говорю:

// matched when function begins
- (void)parser:(PKParser *)p didMatchFunctionKeyword:(PKAssembly *)a {
    [a push:[NSNull null]]; // set a flag
}

// matched when a function ends
- (void)parser:(PKParser *)p didMatchFunctionCloseCurly:(PKAssembly *)a {
    NSArray *discarded = [a objectsAbove:[NSNull null]];
    id obj = [a pop]; // clear the flag
    NSAssert(obj == [NSNull null], @"null should be on the top of the stack");
}

// matched when a var is declared
- (void)parser:(PKParser *)p didMatchVarDecl:(PKAssembly *)a {
    id obj = [a pop];
    if (obj == [NSNull null]) { // check for flag
        [a push:obj]; // we're in a function. put the flag back and bail.
    } else {
        PKToken *fence = [PKToken tokenWithTokenType:PKTokenTypeWord stringValue:@"var" floatValue:0.0];
        NSArray *toks = [a objectsAbove:fence]; // get all the tokens for the var decl
        // now do whatever you want with the var decl tokens here.
    }
}
Другие вопросы по тегам