Compiladores/Aula Prática 02/Exemplos

From Wiki**3

< Compiladores‎ | Aula Prática 02
Revision as of 10:56, 12 May 2022 by Root (talk | contribs) (Solução)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Exemplo 1: sweep-from-to-step-do

Problema

Uma linguagem dispõe de uma instrução que corresponde a um ciclo que faz variar uma variável de controlo entre dois limites, utilizando um incremento variável. Na instrução abaixo, partes em negrito correspondem a palavras chave da linguagem e partes em itálico correspondem a partes variáveis.

sweep variable from expression to expression step expression do instruction

variable corresponde a uma variável inteira ou real, expression corresponde a uma expressão com tipo compatível com a variável e instruction corresponde a uma instrução que faz uso da variável.

Escreva a classe que representa o nó correspondente a esta instrução, indicando todos os seus atributos. Defina ainda a função de visita (accept). Além do nó pedido, não é necessário definir outros, devem ser usados os que são fornecidos com a CDK.

Um exemplo de uso é indicado a seguir. Supõe-se que i é uma variável real, que f() é uma chamada a uma função que devolve um valor real e que print(i) é uma chamada a uma função que aceita um valor real.

sweep i from f()/3 to f()/2 step 0.1 do print(i)

Solução

AST node: sweep_node
class sweep_node : public cdk::basic_node {
    cdk::lvalue_node *_variable;
    cdk::expression_node *_from;
    cdk::expression_node *_to;
    cdk::expression_node *_step;
    cdk::basic_node *_instruction;

public:
    sweep_node(int lineno, cdk::lvalue_node *variable, cdk::expression_node *from, cdk::expression_node *to, cdk::expression_node *step, cdk::basic_node *instruction) :
        basic_node(lineno), _variable(variable), _from(from), _to(to), _step(step), _instruction(instruction) {
            // EMPTY
    }

    void accept(basic_ast_visitor *sp, int level) {
        sp->do_sweep_node(this, level);
    }
    // other functions
};

Exemplo 2: with-run-between-and-stepping

Problema

Uma linguagem dispõe de uma instrução que corresponde a um ciclo que faz variar uma variável de controlo entre dois limites, utilizando um incremento variável. Na instrução abaixo, partes em negrito correspondem a palavras chave da linguagem e partes em itálico correspondem a partes variáveis.

with variable run instruction between expression and expression stepping expression

variable corresponde a uma variável inteira ou real, expression corresponde a uma expressão com tipo compatível com a variável e instruction corresponde a uma instrução que faz uso da variável.

Escreva a classe que representa o nó correspondente a esta instrução, indicando todos os seus atributos. Defina ainda a função de visita (accept). Além do nó pedido, não é necessário definir outros, devem ser usados os que são fornecidos com a CDK.

Um exemplo de uso é indicado a seguir. Supõe-se que i é uma variável real, que f() é uma chamada a uma função que devolve um valor real e que print(i) é uma chamada a uma função que aceita um valor real.

with i run print(i) between f()/3 and f()/2 stepping 0.1

Solução

AST node: with_node
class with_node : public cdk::basic_node {
    cdk::lvalue_node *_variable;
    cdk::basic_node *_instruction;
    cdk::expression_node *_between;
    cdk::expression_node *_and_expression;
    cdk::expression_node *_step;

public:
    with_node(int lineno, cdk::lvalue_node *variable, cdk::basic_node *instruction, cdk::expression_node *between, cdk::expression_node *and_expression, cdk::expression_node *step) :
        basic_node(lineno), _variable(variable), _instruction(instruction), _between(between), _and_expression(and_expression), _step(step) {
            // EMPTY
    }

    void accept(basic_ast_visitor *sp, int level) {
        sp->do_with_node(this, level);
    }
    // other functions
};

Exemplo 3: with-if-call-otherwise

Problema

Uma linguagem dispõe de uma instrução que corresponde a escolher uma função a executar, entre duas possíveis, com base numa condição. As duas funções em alternativa devem ter a mesma assinatura (i.e., receber os mesmos tipos de argumentos e retornar o mesmo tipo de dados). Na instrução abaixo, partes em negrito correspondem a palavras chave da linguagem e partes em itálico correspondem a partes variáveis.

with args if condition call func-name-1 otherwise func-name-2

args corresponde a uma sequência de expressões não vazia (separadas por vírgulas) compatível com os argumentos das duas funções, condition corresponde a uma expressão booleana (tipo inteiro, por simplicidade) e func-name-1 e func-name-2 são nomes de funções (correspondentes a funções declaradas nas condições descritas no primeiro parágrafo).

Escreva a classe que representa o nó correspondente a esta instrução, indicando todos os seus atributos. Defina ainda a função de visita (accept). Além do nó pedido, não é necessário definir outros, devem ser usados os que são fornecidos com a CDK.

Um exemplo de uso é indicado a seguir. Supõe-se que i e j são variáveis compatíveis com os argumentos de f e de g e que a é uma variável inteira.

with i, j if a > 3 call f otherwise g

Solução

AST node: with_node
class with_node : public cdk::basic_node {
    cdk::sequence_node *_args;
    cdk::expression_node *_condition;
    std::string _func_1;
    std::string _func_2;

public:
    with_node(int lineno, cdk::sequence_node *args, cdk::expression_node *condition, const std::string &func_1, const std::string &func_2) :
        basic_node(lineno), _args(args), _condition(condition), _func_1(func_1), _func_2(func_2) {
            // EMPTY
    }

    void accept(basic_ast_visitor *sp, int level) {
        sp->do_with_node(this, level);
    }
    // other functions
};

Exemplo 4: call-on-or-if

Problema

Uma linguagem dispõe de uma expressão que corresponde a chamar condicionalmente uma função sobre conjuntos alternativos de argumentos, dependendo de um valor lógico. Na expressão abaixo, partes em negrito são palavras chave da linguagem e partes em itálico são partes variáveis.

call function-name on expressions or expressions if expression

function-name corresponde ao nome da função cujos argumentos são compatíveis com as listas de expressões que seguem on e or. A condição que segue if determina se é usado o primeiro conjunto (condição verdadeira) de expressões ou o segundo (condição falsa) na chamada à função.

Escreva a classe que representa o nó correspondente a esta expressão, indicando todos os seus atributos. Defina ainda a função de visita (accept). Além do nó pedido, não é necessário definir outros: devem ser usados os que são fornecidos com a CDK.

Um exemplo de uso é indicado a seguir. Supõe-se que f é uma função que aceita dois inteiros e que i, j e k são variáveis inteiras.

call f on i, 3 or 2, j + 1 if k

Solução

AST node: call_if_node
class call_if_node : public cdk::expression_node {
    std::string _func;
    cdk::sequence_node *_on_args;
    cdk::sequence_node *_or_args;
    cdk::expression_node *_condition;

public:
    call_if_node(int lineno, const std::string &func, cdk::sequence_node *on_args, cdk::sequence_node *or_args, cdk::expression_node *condition) :
        expression_node(lineno), _func(func), _on_args(on_args), _or_args(or_args), _condition(condition) {
            // EMPTY
    }

    void accept(basic_ast_visitor *sp, int level) {
        sp->do_call_if_node(this, level);
    }
    // other functions
};

Exemplo 5: when-call-on-or

Problema

Uma linguagem dispõe de uma expressão que corresponde a chamar condicionalmente uma função sobre conjuntos alternativos de argumentos, dependendo de um valor lógico. Na expressão abaixo, partes em negrito são palavras chave da linguagem e partes em itálico são partes variáveis.

when expression call function-name on expressions or expressions

function-name corresponde ao nome da função cujos argumentos são compatíveis com as listas de expressões que seguem on e or. A condição que segue when determina se é usado o primeiro conjunto (condição verdadeira) de expressões ou o segundo (condição falsa) na chamada à função.

Escreva a classe que representa o nó correspondente a esta expressão, indicando todos os seus atributos. Defina ainda a função de visita (accept). Além do nó pedido, não é necessário definir outros: devem ser usados os que são fornecidos com a CDK.

Um exemplo de uso é indicado a seguir. Supõe-se que f é uma função que aceita dois inteiros e que i, j e k são variáveis inteiras.

when k call f on i, 3 or 2, j + 1

Solução

AST node: when_node
class when_node : public cdk::expression_node {
    cdk::expression_node *_condition;
    std::string _func;
    cdk::sequence_node *_on_args;
    cdk::sequence_node *_or_args;

public:
    when_node(int lineno, cdk::expression_node *condition, const std::string &func, cdk::sequence_node *on_args, cdk::sequence_node *or_args) :
        expression_node(lineno), _condition(condition), _func(func), _on_args(on_args), _or_args(or_args) {
            // EMPTY
    }

    void accept(basic_ast_visitor *sp, int level) {
        sp->do_when_node(this, level);
    }
    // other functions
};