# 📘 **1. Regras Gerais do Lexer**

O lexer opera com estas premissas:

1. **Indentação é significativa**
   NL v0.1 usa **tabs** (`\t`) como unidade de indentação.
   Espaços são permitidos dentro de expressões, mas **não contam** para nível de bloco.

2. **Comentários começam com `#` e vão até o fim da linha.**

3. Linhas em branco são ignoradas para efeitos de sintaxe.

4. Quebras de linha (`\n`) são tokens (NEWLINE).

5. O lexer produz tokens de INDENT/DEDENT tal como Python.

---

# 📙 **2. Lista completa de Tokens (v0.1)**

A tabela seguinte lista **todos os tokens reconhecidos** por NL v0.1 no subset mínimo.

## **2.1 Palavras-chave**

| Token   | Lexema  | Descrição                    |
| ------- | ------- | ---------------------------- |
| `DEF`   | `def`   | Declaração de função         |
| `SE`    | `se`    | Início de condicional        |
| `ENTAO` | `entao` | Separador do ramo verdadeiro |
| `SENAO` | `senao` | Ramo alternativo             |
| `EOF`   | —       | Fim do ficheiro fonte        |

> *Todas são **case-sensitive**, minúsculas apenas.*

---

## **2.2 Símbolos e pontuação**

| Token     | Símbolo | Descrição                                 |
| --------- | ------- | ----------------------------------------- |
| `LPAREN`  | `(`     | Abrir parênteses                          |
| `RPAREN`  | `)`     | Fechar parênteses                         |
| `COMMA`   | `,`     | Separador de argumentos                   |
| `NEWLINE` | `\n`    | Fim de linha                              |
| `INDENT`  | —       | Produzido ao aumentar nível de indentação |
| `DEDENT`  | —       | Produzido ao reduzir nível de indentação  |

---

## **2.3 Operadores**

| Token   | Símbolo | Tipo                                         |
| ------- | ------- | -------------------------------------------- |
| `PLUS`  | `+`     | Aritmético                                   |
| `MINUS` | `-`     | Aritmético                                   |
| `STAR`  | `*`     | Aritmético (reservado mas não usado em fib)  |
| `SLASH` | `/`     | Aritmético                                   |
| `LT`    | `<`     | Comparação (Less Than)                       |
| `GT`    | `>`     | Comparação (Greater Than) *(reservado)*      |
| `EQ`    | `==`    | Igualdade *(reservado para versões futuras)* |

> Para o NL v0.1, apenas `<`, `+`, `-` são necessários.
> Mas deixamos `*`, `/`, `>` e `==` definidos para não quebrar extensões.

---

## **2.4 Literais**

### Inteiros

| Token | Exemplo            | Regra                         |
| ----- | ------------------ | ----------------------------- |
| `INT` | `0`, `42`, `12345` | Sequência de dígitos `[0-9]+` |

---

## **2.5 Identificadores**

| Token   | Exemplos                | Regra                    |
| ------- | ----------------------- | ------------------------ |
| `IDENT` | `fib`, `x`, `variavel1` | `[a-zA-Z_][a-zA-Z0-9_]*` |

O lexer deve distinguir entre **IDENTs normais** e **palavras-chave** verificando contra a tabela de keywords.

---

## **2.6 Comentários**

| Token     | Exemplo                  |
| --------- | ------------------------ |
| `COMMENT` | `# isto é um comentário` |

Comentários são lexados até ao fim da linha mas **não são entregues ao parser** — o lexer descarta-os ou emite um modo “ignored”.

---

# 📗 **3. Regras de Indentação**

NL usa **indentação significativa** baseada exclusivamente em **tabs**.

### Regras formais:

* No início de cada nova linha, o lexer conta o número de tabs consecutivos: `n`.
* Compara com o nível anterior `p`.

1. **Se `n > p` → emitir `INDENT`**
2. **Se `n < p` → emitir `DEDENT` repetidamente até igualar**
3. **Se `n == p` → nenhum token de indentação é emitido**

Espaços dentro da linha NÃO afetam indentação.

Qualquer mistura de tabs e espaços no início da linha → erro léxico (v0.1).

---

# 📘 **4. Ordem de Produção dos Tokens**

O lexer deve emitir tokens nesta ordem:

1. Zero ou mais `INDENT`/`DEDENT`
2. Tokens da linha (IDENT, INT, operadores, símbolos…)
3. Um token `NEWLINE` ao final da linha
4. No final do arquivo:

   * emitir `DEDENT` suficientes para nivelar até 0
   * emitir `EOF`

---

# 📙 **5. Exemplos de Tokenização**

## **5.1. Função fib**

Fonte:

```nl
def fib(x)
    se x < 3 entao
        1
    senao
        fib(x-1) + fib(x-2)
```

Tokens relevantes:

```
DEF IDENT LPAREN IDENT RPAREN NEWLINE
INDENT SE IDENT LT INT ENTAO NEWLINE
INDENT INT NEWLINE
DEDENT SENAO NEWLINE
INDENT IDENT LPAREN IDENT MINUS INT RPAREN PLUS IDENT LPAREN IDENT MINUS INT RPAREN NEWLINE
DEDENT DEDENT EOF
```

---

## **5.2. Chamada final**

Fonte:

```
fib(40)
```

Tokens:

```
IDENT LPAREN INT RPAREN NEWLINE
EOF
```

---

# 📗 **6. Considerações Futuras**

Não incluídos no v0.1, mas previstos no design:

* Strings (`"texto"`)
* Booleanos verdadeiros (`verdadeiro`/`falso`)
* Operador de atribuição (`=`) para variáveis locais
* Estruturas de dados
* Blocos `enquanto`, `para`, `repete`
* Tipagem opcional
* Macros sintáticas

---

# 🌑 **Fim do tokens.md**