Skip to content

Commit

Permalink
Задача 12. Про парсер. Описание языка.
Browse files Browse the repository at this point in the history
  • Loading branch information
gsvgit committed Apr 19, 2024
1 parent b8d2e25 commit f3a454a
Showing 1 changed file with 97 additions and 175 deletions.
272 changes: 97 additions & 175 deletions tasks/task12.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,252 +4,182 @@
* **Жёсткий дедлайн**: 21.12.2022, 23:59
* Полный балл: 5

## Описание абстрактного синтаксиса языка

```
prog = List<stmt>
stmt =
bind of var * expr
| print of expr
val =
String of string
| Int of int
| // а здесь пространство для творчества
expr =
Var of var // переменные
| Val of val // константы
| Set_start of Set<val> * expr // задать множество стартовых состояний
| Set_final of Set<val> * expr // задать множество финальных состояний
| Add_start of Set<val> * expr // добавить состояния в множество стартовых
| Add_final of Set<val> * expr // добавить состояния в множество финальных
| Get_start of expr // получить множество стартовых состояний
| Get_final of expr // получить множество финальных состояний
| Get_reachable of expr // получить все пары достижимых вершин
| Get_vertices of expr // получить все вершины
| Get_edges of expr // получить все рёбра
| Get_labels of expr // получить все метки
| Map of lambda * expr // классический map
| Filter of lambda * expr // классический filter
| Load of path // загрузка графа
| Intersect of expr * expr // пересечение языков
| Concat of expr * expr // конкатенация языков
| Union of expr * expr // объединение языков
| Star of expr // замыкание языка (звезда Клини)
| Smb of expr // единичный переход
lambda =
// а здесь пространство для творчества
## Конкретный синтаксис
```
prog = stmt*
Выразительные возможности лямбды должны позволять решать такие задачи как получение достижимых вершин, получение вершин из которых достижимы некоторые, получение пар вершин, между которыми существует путь, удовлетворяющий ограничению.
stmt = bind | add | remove | declare
Пример запроса в некотором гипотетическом конкретном синтаксисе.
declare = VAR 'is' 'graph'
```
let g' = load graph "wine"
bind = 'let' VAR '=' expr
let g = set start of (set finals of g' to (vertices of g')) to {0..100}
remove = 'remove' ('vertex' | 'edge' | 'vertices') expr 'from' VAR
let l1 = "l1" | "l2"
add = 'add' ('vertex' | 'edge') expr 'to' VAR
let q1 = ("type" | l1)*
let q2 = "sub_class_of" | l1 | q2
expr = NUM | CHAR | VAR | edge_expr | set_expr | regexp | select
let res1 = g & q1
let res2 = g & q2
set_expr = '[' expr (',' expr)* ']'
print res1
edge_expr = '(' expr ',' expr ',' expr ')'
let s = start set of g
regexp = CHAR | VAR | '(' regexp ')' | (regexp '|' regexp) | (regexp '^' range) | (regexp '.' regexp) | (regexp '&' regexp)
let vertices1 = filter (fun v -> v in s) (map (fun ((u_g,u_q1),l,(v_g,v_q1)) -> u_g) (get edges of res1))
let vertices2 = filter (fun v -> v in s) (map (fun ((u_g,u_q2),l,(v_g,v_q2)) -> u_g) (get edges of res2))
let vertices = vertices1 & vertices2
range = '[' NUM '..' NUM? ']'
print vertices
select = v_filter? v_filter? 'return' VAR (',' VAR)? 'where' VAR 'reachable' 'from' VAR 'in' VAR 'by' expr
```
v_filter = 'for' VAR 'in' expr
## Правила вывода типов

Константы типизируются очевидным образом.

Тип переменной определяется типом выражения, с которым она связана.
```
[b(v)] => t
_________________
[Var (v)](b) => t
```

Загрузить можно только автомат.
```
_________________________
[Load (p)](b) => FA<int>
```
VAR = [a..z]+[a..z 0..1]*
NUM = [1..9]+[0..9]*
CHAR = '"' [a..z] '"'
Установка финальных состояний, а так же добавление стартовых и финальных типизируется аналогично типизации установки стартовых, которая приведена ниже.
```
[s](b) => Set<t> ; [e](b) => FA<t>
___________________________________
[Set_start (s, e)](b) => FA<t>

[s](b) => Set<t> ; [e](b) => RSM<t>
____________________________________
[Set_start (s, e)](b) => RSM<t>
Пример запроса.

```
let g is graph
Получение финальных типизируется аналогично получению стартовых, правила для которого приведены ниже.
```
[e](b) => FA<t>
____________________________
[Get_start (e)](b) => Set<t>
add edge (1, "a", 2) to g
add edge (2, "a", 3) to g
add edge (3, "a", 1) to g
add edge (1, "c", 0) to g
add edge (0, "b", 4) to g
add edge (4, "b", 0) to g
let q = "a"^[1..3] . q . "b"^[2..3] | "c"
[e](b) => RSM<t>
____________________________
[Get_start (e)](b) => Set<t>
let r1 = for v in [2] return u where u reachable from v in g by q
```

```
[e](b) => FA<t>
__________________________________
[Get_reachable (e)](b) => Set<t*t>
add edge (0, "d", 5) to g
[e](b) => RSM<t>
__________________________________
[Get_reachable (e)](b) => Set<t*t>
```
let r2 = for v in [2,3] return u,v where u reachable from v in g by (q . "d")
```
[e](b) => FA<t>
_______________________________
[Get_vertices (e)](b) => Set<t>

## Правила вывода типов

[e](b) => RSM<t>
_______________________________
[Get_vertices (e)](b) => Set<t>
[e](b) => FA<t>
______________________________________
[Get_edges (e)](b) => Set<t*string*t>
[e](b) => RSM<t>
______________________________________
[Get_edges (e)](b) => Set<t*string*t>
[e](b) => FA<t>
__________________________________
[Get_labels (e)](b) => Set<string>
[e](b) => RSM<t>
__________________________________
[Get_labels (e)](b) => Set<string>
```
Константы типизируются очевидным образом.

Правила для ```map``` и ```filter``` традиционные.
Тип переменной определяется типом выражения, с которым она связана.
```
[f](b) => t1 -> t2 ; [q](b) => Set<t1>
_______________________________________
[Map (f,q)](b) => Set<t2>
[f](b) => t1 -> bool ; [q](b) => Set<t1>
________________________________________
[Filter (f,q)](b) => Set<t1>
[b(v)] => t
_________________
[Var (v)](b) => t
```

Пересечение для двух КС не определено.

```
[e1](b) => FA<t1> ; [e2](b) => FA<t2>
[e1](b) => FA ; [e2](b) => FA
______________________________________
[Intersect (e1, e2)](b) => FA<t1*t2>
[Intersect (e1, e2)](b) => FA
[e1](b) => FA<t1> ; [e2](b) => RSM<t2>
[e1](b) => FA ; [e2](b) => RSM
_______________________________________
[Intersect (e1, e2)](b) => RSM<t1*t2>
[Intersect (e1, e2)](b) => RSM
[e1](b) => RSM<t1> ; [e2](b) => FA<t2>
[e1](b) => RSM ; [e2](b) => FA
_______________________________________
[Intersect (e1, e2)](b) => RSM<t1*t2>
[Intersect (e1, e2)](b) => RSM
```

Остальные операции над автоматами типизируются согласно формальных свойств классов языков.
```
[e1](b) => FA<t> ; [e2](b) => FA<t>
[e1](b) => FA ; [e2](b) => FA
_____________________________________
[Concat (e1, e2)](b) => FA<t>
[Concat (e1, e2)](b) => FA
[e1](b) => FA<t> ; [e2](b) => RSM<t>
[e1](b) => FA ; [e2](b) => RSM
______________________________________
[Concat (e1, e2)](b) => RSM<t>
[Concat (e1, e2)](b) => RSM
[e1](b) => RSM<t> ; [e2](b) => FA<t>
[e1](b) => RSM ; [e2](b) => FA
______________________________________
[Concat (e1, e2)](b) => RSM<t>
[Concat (e1, e2)](b) => RSM
[e1](b) => RSM<t> ; [e2](b) => RSM<t>
[e1](b) => RSM ; [e2](b) => RSM
______________________________________
[Concat (e1, e2)](b) => RSM<t>
[Concat (e1, e2)](b) => RSM
```

```
[e1](b) => FA<t> ; [e2](b) => FA<t>
[e1](b) => FA ; [e2](b) => FA
______________________________________
[Union (e1, e2)](b) => FA<t>
[Union (e1, e2)](b) => FA
[e1](b) => FA<t> ; [e2](b) => RSM<t>
[e1](b) => FA ; [e2](b) => RSM
_______________________________________
[Union (e1, e2)](b) => RSM<t>
[Union (e1, e2)](b) => RSM
[e1](b) => RSM<t> ; [e2](b) => FA<t>
[e1](b) => RSM ; [e2](b) => FA
_______________________________________
[Union (e1, e2)](b) => RSM<t>
[Union (e1, e2)](b) => RSM
[e1](b) => RSM<t> ; [e2](b) => RSM<t>
[e1](b) => RSM ; [e2](b) => RSM
_______________________________________
[Union (e1, e2)](b) => RSM<t>
[Union (e1, e2)](b) => RSM
```

```
[e](b) => FA<t>
[e](b) => FA
______________________
[Star (e)](b) => FA<t>
[Repeat (e)](b) => FA
[e](b) => RSM<t>
[e](b) => RSM
______________________
[Star (e)](b) => RSM<t>
[Repeat (e)](b) => RSM
```

```
[e](b) => string
[e](b) => char
________________________
[Smb (e)](b) => FA<int>
[Smb (e)](b) => FA
```

Запрос возвращает множество (вершин или пар вершин)

```
[e](b) => Set<int>
_______________________________
[VFilter (v, e)](b) => Set<int>
[q](b) => RSM, [ret](b) => int
_____________________________________________________
[Select (vf1, vf2, ret, v1, v2, g, q)](b) => Set<int>
[q](b) => FA, [ret](b) => int
_____________________________________________________
[Select (vf1, vf2, ret, v1, v2, g, q)](b) => Set<int>
[q](b) => FA, [ret](b) => int * int
____________________________________________________________
[Select (vf1, vf2, ret, v1, v2, g, q)](b) => Set<int * int>
[q](b) => RSM, [ret](b) => int * int
____________________________________________________________
[Select (vf1, vf2, ret, v1, v2, g, q)](b) => Set<int * int>
```

Expand All @@ -265,17 +195,9 @@ _____________________________________
```

Загрузить можно только автомат и у него все вершины будут стартовыми и финальными.

```
[p](b1) => s,b2 ; read_fa_from_file s => fa
_____________________________________
[Load (p)](b1) => (fa | fa.start = fa.vertices, fa.final = fa.vertices), b1
```
Результатом исполнения программы является словарь, где ключ --- имя переменной в связывании, у которого в правой части select, а значение --- результат вычисления соответствующего запроса.

## Задача
Решение задачи оформляется в виде .md файла в репозитории. Как вариант --- сделать описание языка частью readme. В качестве примера описания языка можно использовать, например, [спецификацию F#](https://fsharp.org/specs/language-spec/4.1/FSharpSpec-4.1-latest.pdf) или [спецификацию Java](https://docs.oracle.com/javase/specs/jls/se11/html/index.html).
- [ ] Расширить абстрактный синтаксис в местах, указанных в его описании (```val```, ```lambda```)
- [ ] Описать конкретный синтаксис языка запросов в виде грамматики (на основе получившегося абстрактного синтаксиса). При необходимости выделить лексическую спецификацию (описание лексики). Постарайтесь, чтобы, с одной стороны, синтаксис был достаточно уникальным, но с другой, достаточно разумным и на получившемся языке можно было писать без сильной боли.
- [ ] Привести примеры скриптов на получившемся языке. Не забыть описать, что же эти скрипты делают.
- [ ] С использованием ANTLR реализовать синтаксический анализатор предложенного выше языка. А именно, реализовать функцию, которая принимает строку и возвращает дерево разбора.
- [ ] Реализовать функцию, которая по дереву разбора возвращает количество узлов в нём.
- [ ] Реализовать функцию, которая по дереву разбора строит строку, которая была разобрана.

0 comments on commit f3a454a

Please sign in to comment.