Семантические проверки после создания АСТ - PullRequest
0 голосов
/ 27 сентября 2018

Я создал сканер и парсер (с flex и bison соответственно) и AST для реализации транслятора Java-Python.Я не понимаю, как управлять семантическими действиями в AST (проверка типов, проверка объявления переменных, ...), где вставить функции, которые реализуют эти проверки, и как подключить таблицу символов (которую я создал) к AST.Учитывая, например, это производство в синтаксическом анализаторе:

VariableDeclaration
                   : VariableName                               {$$ = varDec_new($1,NULL);}
                   | VariableName ASSIGNOP ExpressionStatement  {$$ = varDec_new($1,$3);}
                ;

С varDec_new , определенным следующим образом в ast.c:

ast_node *varDec_new(ast_node *variableName, ast_node *exprStmt)
{
    ast_node *n = newast(AST_VARDEC); // ast_node allocation (in this case for the ast_node AST_VARDEC (type of ast_node)
    n->varDec.variableName = variableName; // pointer to variableName struct in AST
    n->varDec.exprStmt = expreStmt;   //pointer to expreStmt struct in AST
    return n;
}

Как мне управлять типомпроверка (между VariableName и ExpressionStatement)?Должен ли я создать функцию со всем параметром, подобным AST (в ast.c), или я должен вызывать эту функцию всякий раз, когда нахожу производственный процесс, требующий проверки типа в парсере?

1 Ответ

0 голосов
/ 05 октября 2018

Посмотрите здесь, чтобы ваша таблица символов была доступна в ваших семантических действиях:

ТогдаВот очень упрощенный псевдо-cpp-код функции назначения семантического действия, хотя лучше сделать это, когда дерево будет завершено:

bool storeNodeType(symtable* sym, node* assignment)
{
    switch(root->RHS_node_kind):
    {
        case '+':
             left_type = getNodeType(sym, assignment->RHS->left);
             right_type = getNodeType(sym, assignment->RHS->right);
             [ ... apply_type_coercion_rules ... ]
             return sym->store(found_type,assignment->left->var);

        break;
        [... Plenty of cases]
        case t_Var:
             return symtable->store(assignment->left->var->vartype,assignment->left->var);
        break;
    }
    // each return returns if assignement vaild regarding types */;
}
  1. Это делаетпредположение, что любая переменная, используемая в правой части, уже имеет тип, если это не так, вам нужно будет набрать дерево во втором проходе, как только будет сделан бизон.
  2. Вы в основном выполняетеПосле прохождения RHS вы определяете тип каждого подвыражения на основе правил приведения типов для каждого оператора.Конечные узлы будут либо переменными известного типа, либо константами.Таким образом, вы вводите RHS "снизу вверх".
  3. В sym :: store вы должны решить, принимаете ли вы транскрипцию (string <- int) и / или снова управляете приведением типа (int <- float) например.Вернуть ошибки соответственно. </li>
...