Введение
Документ подробно описывает API для построения LR-автоматов по заданной грамматике. Интерактивную страницу OpenAPI спецификации можно посмотреть здесь.
API является версионируемым. Версия задается в пути запроса (во 2 сегменте).
POST api/{v1+}/build/lr0 (json)
Строит LR(0)-автомат. Результат возвращает в формате json.
Заголовки запроса
| Имя | Описание |
|---|---|
Accept |
application/json |
Параметры пути
| Имя | Описание |
|---|---|
version |
версия API |
Тело запроса
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
.grammar |
Object |
Да |
Грамматика, по которой требуется построить LR-автомат |
.grammar.terminals |
Array |
Да |
Список терминалов грамматики. |
.grammar.nonTerminals |
Array |
Да |
Список нетерминалов грамматики |
.grammar.rules |
Array |
Да |
Список правил грамматики |
.grammar.rules[].left |
String |
Да |
Нетерминал левой части правила грамматики |
.grammar.rules[].right |
String |
Да |
Символы правой части правила грамматики |
.grammar.startSymbol |
String |
Да |
Аксиома грамматики (нетерминал) |
.buildOptions |
Object |
Нет |
Параметры построения LR-автомата |
.buildOptions.namesGenerationStrategy |
String |
Нет |
Стратегия генерации имен состояний при построении автомата |
.buildOptions.enableBuildLog |
Boolean |
Нет |
Передавать ли в ответе лог построения |
Заголовки ответа
| Имя | Описание |
|---|---|
Content-Type |
application/json |
Тело ответа
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
.automaton |
Object |
Да |
Построенный LR-автомат |
.automaton.states |
Array |
Да |
Состояния автомата |
.automaton.states[].name |
String |
Да |
Имя состояния |
.automaton.states[].items |
Array |
Да |
LR(0)-пункты в состоянии |
.automaton.states[].items[].rule |
Object |
Да |
Правило грамматики пункта |
.automaton.states[].items[].rule.left |
String |
Да |
Левая часть правила |
.automaton.states[].items[].rule.right |
String |
Да |
Правая часть правила |
.automaton.states[].items[].dotIndex |
Number |
Да |
Позиция точки в правой части правила |
.automaton.transitions |
Array |
Да |
Переходы между состояниями автомата |
.automaton.transitions[].from |
String |
Да |
Исходное состояние |
.automaton.transitions[].to |
String |
Да |
Целевое состояние |
.automaton.transitions[].through |
String |
Да |
Символ перехода |
.buildLog |
Object |
Нет |
Лог построения LR-автомата (если указана соответствующая опция) |
.buildLog.operations |
Array |
Да |
Последовательность операций построения |
.buildLog.operations[].message |
String |
Да |
Человекочитаемое описание операции |
.buildLog.operations[].level |
String |
Да |
Тип операции |
.buildLog.operations[].name |
String |
Да |
Имя операции |
.buildLog.operations[].stateName |
String |
Нет |
Имя состояния |
.buildLog.operations[].state |
String |
Нет |
Состояние, к которому применяется операция |
.buildLog.operations[].item |
Object |
Нет |
LR-пункт, связанный с операцией |
.buildLog.operations[].item.rule.left |
String |
Нет |
Левая часть правила пункта |
.buildLog.operations[].item.rule.right |
String |
Нет |
Правая часть правила пункта |
.buildLog.operations[].item.dotIndex |
Number |
Нет |
Позиция точки |
.buildLog.operations[].from |
String |
Нет |
Исходное состояние перехода |
.buildLog.operations[].to |
String |
Нет |
Целевое состояние перехода |
.buildLog.operations[].through |
String |
Нет |
Символ перехода |
curl
$ curl 'http://localhost:8080/api/v1/build/lr0' -i -X POST \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d '{
"grammar" : {
"terminals" : [ "(", ")" ],
"nonTerminals" : [ "S" ],
"rules" : [ {
"left" : "S",
"right" : "(S)"
}, {
"left" : "S",
"right" : ""
} ],
"startSymbol" : "S"
},
"buildOptions" : {
"enableBuildLog" : true
}
}'
Примеры
Пример запроса
POST /api/v1/build/lr0 HTTP/1.1
Content-Type: application/json
Accept: application/json
Content-Length: 280
Host: localhost:8080
{
"grammar" : {
"terminals" : [ "(", ")" ],
"nonTerminals" : [ "S" ],
"rules" : [ {
"left" : "S",
"right" : "(S)"
}, {
"left" : "S",
"right" : ""
} ],
"startSymbol" : "S"
},
"buildOptions" : {
"enableBuildLog" : true
}
}
Пример ответа
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 7577
{
"automaton" : {
"states" : [ {
"name" : "S1",
"items" : [ {
"rule" : {
"left" : "S'",
"right" : "S"
},
"dotIndex" : 1
} ]
}, {
"name" : "S2",
"items" : [ {
"rule" : {
"left" : "S",
"right" : "(S)"
},
"dotIndex" : 2
} ]
}, {
"name" : "(1",
"items" : [ {
"rule" : {
"left" : "S",
"right" : "(S)"
},
"dotIndex" : 1
}, {
"rule" : {
"left" : "S",
"right" : ""
},
"dotIndex" : 0
}, {
"rule" : {
"left" : "S",
"right" : "(S)"
},
"dotIndex" : 0
} ]
}, {
"name" : ")1",
"items" : [ {
"rule" : {
"left" : "S",
"right" : "(S)"
},
"dotIndex" : 3
} ]
}, {
"name" : "∇",
"items" : [ {
"rule" : {
"left" : "S'",
"right" : "S"
},
"dotIndex" : 0
}, {
"rule" : {
"left" : "S",
"right" : ""
},
"dotIndex" : 0
}, {
"rule" : {
"left" : "S",
"right" : "(S)"
},
"dotIndex" : 0
} ]
} ],
"transitions" : [ {
"from" : "(1",
"to" : "S2",
"through" : "S"
}, {
"from" : "∇",
"to" : "S1",
"through" : "S"
}, {
"from" : "S2",
"to" : ")1",
"through" : ")"
}, {
"from" : "(1",
"to" : "(1",
"through" : "("
}, {
"from" : "∇",
"to" : "(1",
"through" : "("
} ]
},
"buildLog" : {
"operations" : [ {
"message" : "Построим LR-автомат lr(0)",
"level" : "comment",
"name" : "buildLrAutomaton"
}, {
"message" : "Расширяем исходную грамматику.",
"level" : "comment",
"name" : "extendGrammar"
}, {
"message" : "Добавляем состояние '∇'.",
"stateName" : "∇",
"level" : "action",
"name" : "addState"
}, {
"message" : "Добавляем в состояние '∇' пункт '[S'→•S]'.",
"state" : "∇",
"item" : {
"rule" : {
"left" : "S'",
"right" : "S"
},
"dotIndex" : 0
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние '∇' пункт '[S→•]'.",
"state" : "∇",
"item" : {
"rule" : {
"left" : "S",
"right" : ""
},
"dotIndex" : 0
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние '∇' пункт '[S→•(S)]'.",
"state" : "∇",
"item" : {
"rule" : {
"left" : "S",
"right" : "(S)"
},
"dotIndex" : 0
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Просматриваем состояние '∇'",
"level" : "comment",
"name" : "startAddNewTransitions"
}, {
"message" : "Добавляем состояние 'S1'.",
"stateName" : "S1",
"level" : "action",
"name" : "addState"
}, {
"message" : "Добавляем в состояние 'S1' пункт '[S'→S•]'.",
"state" : "S1",
"item" : {
"rule" : {
"left" : "S'",
"right" : "S"
},
"dotIndex" : 1
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем переход из состояния '∇' в состояние 'S1' по символу 'S'.",
"from" : "∇",
"to" : "S1",
"through" : "S",
"level" : "action",
"name" : "addTransition"
}, {
"message" : "Добавляем состояние '(1'.",
"stateName" : "(1",
"level" : "action",
"name" : "addState"
}, {
"message" : "Добавляем в состояние '(1' пункт '[S→(•S)]'.",
"state" : "(1",
"item" : {
"rule" : {
"left" : "S",
"right" : "(S)"
},
"dotIndex" : 1
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние '(1' пункт '[S→•]'.",
"state" : "(1",
"item" : {
"rule" : {
"left" : "S",
"right" : ""
},
"dotIndex" : 0
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние '(1' пункт '[S→•(S)]'.",
"state" : "(1",
"item" : {
"rule" : {
"left" : "S",
"right" : "(S)"
},
"dotIndex" : 0
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем переход из состояния '∇' в состояние '(1' по символу '('.",
"from" : "∇",
"to" : "(1",
"through" : "(",
"level" : "action",
"name" : "addTransition"
}, {
"message" : "Просматриваем состояние 'S1'",
"level" : "comment",
"name" : "startAddNewTransitions"
}, {
"message" : "Просматриваем состояние '(1'",
"level" : "comment",
"name" : "startAddNewTransitions"
}, {
"message" : "Добавляем состояние 'S2'.",
"stateName" : "S2",
"level" : "action",
"name" : "addState"
}, {
"message" : "Добавляем в состояние 'S2' пункт '[S→(S•)]'.",
"state" : "S2",
"item" : {
"rule" : {
"left" : "S",
"right" : "(S)"
},
"dotIndex" : 2
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем переход из состояния '(1' в состояние 'S2' по символу 'S'.",
"from" : "(1",
"to" : "S2",
"through" : "S",
"level" : "action",
"name" : "addTransition"
}, {
"message" : "Добавляем переход из состояния '(1' в состояние '(1' по символу '('.",
"from" : "(1",
"to" : "(1",
"through" : "(",
"level" : "action",
"name" : "addTransition"
}, {
"message" : "Просматриваем состояние 'S2'",
"level" : "comment",
"name" : "startAddNewTransitions"
}, {
"message" : "Добавляем состояние ')1'.",
"stateName" : ")1",
"level" : "action",
"name" : "addState"
}, {
"message" : "Добавляем в состояние ')1' пункт '[S→(S)•]'.",
"state" : ")1",
"item" : {
"rule" : {
"left" : "S",
"right" : "(S)"
},
"dotIndex" : 3
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем переход из состояния 'S2' в состояние ')1' по символу ')'.",
"from" : "S2",
"to" : ")1",
"through" : ")",
"level" : "action",
"name" : "addTransition"
}, {
"message" : "Просматриваем состояние ')1'",
"level" : "comment",
"name" : "startAddNewTransitions"
} ]
}
}
POST api/{v1+}/build/lr0 (png)
Строит LR(0)-автомат. Результат возвращает в формате png.
Заголовки запроса
| Имя | Описание |
|---|---|
Accept |
image/png |
Параметры пути
| Имя | Описание |
|---|---|
version |
версия API |
Тело запроса
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
.grammar |
Object |
Да |
Грамматика, по которой требуется построить LR-автомат |
.grammar.terminals |
Array |
Да |
Список терминалов грамматики. |
.grammar.nonTerminals |
Array |
Да |
Список нетерминалов грамматики |
.grammar.rules |
Array |
Да |
Список правил грамматики |
.grammar.rules[].left |
String |
Да |
Нетерминал левой части правила грамматики |
.grammar.rules[].right |
String |
Да |
Символы правой части правила грамматики |
.grammar.startSymbol |
String |
Да |
Аксиома грамматики (нетерминал) |
.buildOptions |
Object |
Нет |
Параметры построения LR-автомата |
.buildOptions.namesGenerationStrategy |
String |
Нет |
Стратегия генерации имен состояний при построении автомата |
visualizeOperations.colorizeTransitions |
Boolean |
Нет |
Нужно ли окрашивать переходы автомата. По умолчанию не окрашиваются. |
visualizeOperations.colorizeStateNames |
Boolean |
Нет |
Окрашивать ли имена состояний. По умолчанию не окрашиваются. |
visualizeOperations.stateNameStyle |
String |
Нет |
Стиль оформления названия состояния. По умолчанию 'onBlackBackground'. |
Заголовки ответа
| Имя | Описание |
|---|---|
Content-Type |
image/png |
curl
$ curl 'http://localhost:8080/api/v1/build/lr0' -i -X POST \
-H 'Content-Type: application/json' \
-H 'Accept: image/png' \
-d '{
"grammar" : {
"terminals" : [ "a", "b", "c", "d" ],
"nonTerminals" : [ "S", "A" ],
"rules" : [ {
"left" : "S",
"right" : "Aa"
}, {
"left" : "S",
"right" : "bAc"
}, {
"left" : "S",
"right" : "bc"
}, {
"left" : "S",
"right" : "bda"
}, {
"left" : "A",
"right" : "d"
} ],
"startSymbol" : "S"
}
}'
Пример запроса
POST /api/v1/build/lr0 HTTP/1.1
Content-Type: application/json
Accept: image/png
Content-Length: 393
Host: localhost:8080
{
"grammar" : {
"terminals" : [ "a", "b", "c", "d" ],
"nonTerminals" : [ "S", "A" ],
"rules" : [ {
"left" : "S",
"right" : "Aa"
}, {
"left" : "S",
"right" : "bAc"
}, {
"left" : "S",
"right" : "bc"
}, {
"left" : "S",
"right" : "bda"
}, {
"left" : "A",
"right" : "d"
} ],
"startSymbol" : "S"
}
}
Пример ответа
POST api/{v1+}/build/lr0 (zip)
Строит LR(0)-автомат. Лог построения возвращает в zip архиве с изображениями автомата.
Заголовки запроса
| Имя | Описание |
|---|---|
Accept |
application/octet-stream |
Параметры пути
| Имя | Описание |
|---|---|
version |
версия API |
Тело запроса
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
.grammar |
Object |
Да |
Грамматика, по которой требуется построить LR-автомат |
.grammar.terminals |
Array |
Да |
Список терминалов грамматики. |
.grammar.nonTerminals |
Array |
Да |
Список нетерминалов грамматики |
.grammar.rules |
Array |
Да |
Список правил грамматики |
.grammar.rules[].left |
String |
Да |
Нетерминал левой части правила грамматики |
.grammar.rules[].right |
String |
Да |
Символы правой части правила грамматики |
.grammar.startSymbol |
String |
Да |
Аксиома грамматики (нетерминал) |
.buildOptions |
Object |
Нет |
Параметры построения LR-автомата |
.buildOptions.namesGenerationStrategy |
String |
Нет |
Стратегия генерации имен состояний при построении автомата |
visualizeOperations.visualizeOperations |
Array |
Нет |
Номера операций, которые нужно визуализировать. Если не указаны, то визуализируются все операции |
visualizeOperations.colorizeTransitions |
Boolean |
Нет |
Нужно ли окрашивать переходы автомата. По умолчанию не окрашиваются. |
visualizeOperations.colorizeStateNames |
Boolean |
Нет |
Окрашивать ли имена состояний. По умолчанию не окрашиваются. |
visualizeOperations.stateNameStyle |
String |
Нет |
Стиль оформления названия состояния. По умолчанию 'onBlackBackground'. |
Заголовки ответа
| Имя | Описание |
|---|---|
Content-Type |
application/octet-stream (zip) |
curl
$ curl 'http://localhost:8080/api/v1/build/lr0' -i -X POST \
-H 'Content-Type: application/json' \
-H 'Accept: application/octet-stream' \
-d '{
"grammar" : {
"terminals" : [ "u", "z", "v", "w", "y", "x" ],
"nonTerminals" : [ "S", "B", "D", "E", "F" ],
"rules" : [ {
"left" : "S",
"right" : "uBDz"
}, {
"left" : "B",
"right" : "Bv"
}, {
"left" : "B",
"right" : "w"
}, {
"left" : "D",
"right" : "EF"
}, {
"left" : "E",
"right" : "y"
}, {
"left" : "E",
"right" : ""
}, {
"left" : "F",
"right" : "x"
}, {
"left" : "F",
"right" : ""
} ],
"startSymbol" : "S"
}
}'
Пример запроса
POST /api/v1/build/lr0 HTTP/1.1
Content-Type: application/json
Accept: application/octet-stream
Content-Length: 562
Host: localhost:8080
{
"grammar" : {
"terminals" : [ "u", "z", "v", "w", "y", "x" ],
"nonTerminals" : [ "S", "B", "D", "E", "F" ],
"rules" : [ {
"left" : "S",
"right" : "uBDz"
}, {
"left" : "B",
"right" : "Bv"
}, {
"left" : "B",
"right" : "w"
}, {
"left" : "D",
"right" : "EF"
}, {
"left" : "E",
"right" : "y"
}, {
"left" : "E",
"right" : ""
}, {
"left" : "F",
"right" : "x"
}, {
"left" : "F",
"right" : ""
} ],
"startSymbol" : "S"
}
}
POST api/{v1+}/build/lalr1 (json)
Строит LALR(1)-автомат. Результат возвращает в формате json.
Заголовки запроса
| Имя | Описание |
|---|---|
Accept |
application/json |
Параметры пути
| Имя | Описание |
|---|---|
version |
версия API |
Тело запроса
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
.grammar |
Object |
Да |
Грамматика, по которой требуется построить LR-автомат |
.grammar.terminals |
Array |
Да |
Список терминалов грамматики. |
.grammar.nonTerminals |
Array |
Да |
Список нетерминалов грамматики |
.grammar.rules |
Array |
Да |
Список правил грамматики |
.grammar.rules[].left |
String |
Да |
Нетерминал левой части правила грамматики |
.grammar.rules[].right |
String |
Да |
Символы правой части правила грамматики |
.grammar.startSymbol |
String |
Да |
Аксиома грамматики (нетерминал) |
.buildOptions |
Object |
Нет |
Параметры построения LR-автомата |
.buildOptions.namesGenerationStrategy |
String |
Нет |
Стратегия генерации имен состояний при построении автомата |
.buildOptions.lalr1BuildAlgorithm |
String |
Нет |
|
.buildOptions.enableBuildLog |
Boolean |
Нет |
Передавать ли в ответе лог построения |
Заголовки ответа
| Имя | Описание |
|---|---|
Content-Type |
application/json |
Тело ответа
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
.automaton |
Object |
Да |
Построенный LR-автомат |
.automaton.states |
Array |
Да |
Состояния автомата |
.automaton.states[].name |
String |
Да |
Имя состояния |
.automaton.states[].items |
Array |
Да |
LR(0)-пункты в состоянии |
.automaton.states[].items[].rule |
Object |
Да |
Правило грамматики пункта |
.automaton.states[].items[].rule.left |
String |
Да |
Левая часть правила |
.automaton.states[].items[].rule.right |
String |
Да |
Правая часть правила |
.automaton.states[].items[].dotIndex |
Number |
Да |
Позиция точки в правой части правила |
.automaton.transitions |
Array |
Да |
Переходы между состояниями автомата |
.automaton.transitions[].from |
String |
Да |
Исходное состояние |
.automaton.transitions[].to |
String |
Да |
Целевое состояние |
.automaton.transitions[].through |
String |
Да |
Символ перехода |
.buildLog |
Object |
Нет |
Лог построения LR-автомата (если указана соответствующая опция) |
.buildLog.operations |
Array |
Да |
Последовательность операций построения |
.buildLog.operations[].message |
String |
Да |
Человекочитаемое описание операции |
.buildLog.operations[].level |
String |
Да |
Тип операции |
.buildLog.operations[].name |
String |
Да |
Имя операции |
.buildLog.operations[].stateName |
String |
Нет |
Имя состояния |
.buildLog.operations[].state |
String |
Нет |
Состояние, к которому применяется операция |
.buildLog.operations[].item |
Object |
Нет |
LR-пункт, связанный с операцией |
.buildLog.operations[].item.rule.left |
String |
Нет |
Левая часть правила пункта |
.buildLog.operations[].item.rule.right |
String |
Нет |
Правая часть правила пункта |
.buildLog.operations[].item.dotIndex |
Number |
Нет |
Позиция точки |
.buildLog.operations[].from |
String |
Нет |
Исходное состояние перехода |
.buildLog.operations[].to |
String |
Нет |
Целевое состояние перехода |
.buildLog.operations[].through |
String |
Нет |
Символ перехода |
.automaton.states[].items[].lookAheadSymbol |
String |
Нет |
Символ предпросмотра |
.buildLog.operations[].item.lookAheadSymbol |
String |
Нет |
Символ предпросмотра |
.automaton.states[].items[].lookAheadSymbols |
Array |
Нет |
Символы предпросмотра (при построении через канальный алгоритм) |
curl
$ curl 'http://localhost:8080/api/v1/build/lalr1' -i -X POST \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d '{
"grammar" : {
"terminals" : [ "x", "*", "=" ],
"nonTerminals" : [ "S", "L", "R" ],
"rules" : [ {
"left" : "S",
"right" : "L=R"
}, {
"left" : "S",
"right" : "R"
}, {
"left" : "L",
"right" : "*R"
}, {
"left" : "L",
"right" : "x"
}, {
"left" : "R",
"right" : "L"
} ],
"startSymbol" : "S"
},
"buildOptions" : {
"enableBuildLog" : true
}
}'
Примеры
Пример запроса
POST /api/v1/build/lalr1 HTTP/1.1
Content-Type: application/json
Accept: application/json
Content-Length: 444
Host: localhost:8080
{
"grammar" : {
"terminals" : [ "x", "*", "=" ],
"nonTerminals" : [ "S", "L", "R" ],
"rules" : [ {
"left" : "S",
"right" : "L=R"
}, {
"left" : "S",
"right" : "R"
}, {
"left" : "L",
"right" : "*R"
}, {
"left" : "L",
"right" : "x"
}, {
"left" : "R",
"right" : "L"
} ],
"startSymbol" : "S"
},
"buildOptions" : {
"enableBuildLog" : true
}
}
Пример ответа
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 41323
{
"automaton" : {
"states" : [ {
"name" : "R3",
"items" : [ {
"rule" : {
"left" : "S",
"right" : "L=R"
},
"dotIndex" : 3,
"lookAheadSymbol" : "⊣"
} ]
}, {
"name" : "=1",
"items" : [ {
"rule" : {
"left" : "S",
"right" : "L=R"
},
"dotIndex" : 2,
"lookAheadSymbol" : "⊣"
}, {
"rule" : {
"left" : "R",
"right" : "L"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
}, {
"rule" : {
"left" : "L",
"right" : "*R"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
}, {
"rule" : {
"left" : "L",
"right" : "x"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
} ]
}, {
"name" : "L1",
"items" : [ {
"rule" : {
"left" : "S",
"right" : "L=R"
},
"dotIndex" : 1,
"lookAheadSymbol" : "⊣"
}, {
"rule" : {
"left" : "R",
"right" : "L"
},
"dotIndex" : 1,
"lookAheadSymbol" : "⊣"
} ]
}, {
"name" : "R2;R4",
"items" : [ {
"rule" : {
"left" : "L",
"right" : "*R"
},
"dotIndex" : 2,
"lookAheadSymbol" : "="
}, {
"rule" : {
"left" : "L",
"right" : "*R"
},
"dotIndex" : 2,
"lookAheadSymbol" : "⊣"
} ]
}, {
"name" : "∇",
"items" : [ {
"rule" : {
"left" : "S'",
"right" : "S"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
}, {
"rule" : {
"left" : "S",
"right" : "R"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
}, {
"rule" : {
"left" : "S",
"right" : "L=R"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
}, {
"rule" : {
"left" : "R",
"right" : "L"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
}, {
"rule" : {
"left" : "L",
"right" : "x"
},
"dotIndex" : 0,
"lookAheadSymbol" : "="
}, {
"rule" : {
"left" : "L",
"right" : "*R"
},
"dotIndex" : 0,
"lookAheadSymbol" : "="
}, {
"rule" : {
"left" : "L",
"right" : "*R"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
}, {
"rule" : {
"left" : "L",
"right" : "x"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
} ]
}, {
"name" : "L2;L3",
"items" : [ {
"rule" : {
"left" : "R",
"right" : "L"
},
"dotIndex" : 1,
"lookAheadSymbol" : "⊣"
}, {
"rule" : {
"left" : "R",
"right" : "L"
},
"dotIndex" : 1,
"lookAheadSymbol" : "="
} ]
}, {
"name" : "*1;*2",
"items" : [ {
"rule" : {
"left" : "L",
"right" : "*R"
},
"dotIndex" : 1,
"lookAheadSymbol" : "⊣"
}, {
"rule" : {
"left" : "L",
"right" : "*R"
},
"dotIndex" : 1,
"lookAheadSymbol" : "="
}, {
"rule" : {
"left" : "R",
"right" : "L"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
}, {
"rule" : {
"left" : "R",
"right" : "L"
},
"dotIndex" : 0,
"lookAheadSymbol" : "="
}, {
"rule" : {
"left" : "L",
"right" : "*R"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
}, {
"rule" : {
"left" : "L",
"right" : "x"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
}, {
"rule" : {
"left" : "L",
"right" : "x"
},
"dotIndex" : 0,
"lookAheadSymbol" : "="
}, {
"rule" : {
"left" : "L",
"right" : "*R"
},
"dotIndex" : 0,
"lookAheadSymbol" : "="
} ]
}, {
"name" : "x1;x2",
"items" : [ {
"rule" : {
"left" : "L",
"right" : "x"
},
"dotIndex" : 1,
"lookAheadSymbol" : "⊣"
}, {
"rule" : {
"left" : "L",
"right" : "x"
},
"dotIndex" : 1,
"lookAheadSymbol" : "="
} ]
}, {
"name" : "S1",
"items" : [ {
"rule" : {
"left" : "S'",
"right" : "S"
},
"dotIndex" : 1,
"lookAheadSymbol" : "⊣"
} ]
}, {
"name" : "R1",
"items" : [ {
"rule" : {
"left" : "S",
"right" : "R"
},
"dotIndex" : 1,
"lookAheadSymbol" : "⊣"
} ]
} ],
"transitions" : [ {
"from" : "∇",
"to" : "L1",
"through" : "L"
}, {
"from" : "=1",
"to" : "x1;x2",
"through" : "x"
}, {
"from" : "*1;*2",
"to" : "x1;x2",
"through" : "x"
}, {
"from" : "∇",
"to" : "*1;*2",
"through" : "*"
}, {
"from" : "∇",
"to" : "S1",
"through" : "S"
}, {
"from" : "*1;*2",
"to" : "L2;L3",
"through" : "L"
}, {
"from" : "∇",
"to" : "R1",
"through" : "R"
}, {
"from" : "*1;*2",
"to" : "R2;R4",
"through" : "R"
}, {
"from" : "∇",
"to" : "x1;x2",
"through" : "x"
}, {
"from" : "=1",
"to" : "*1;*2",
"through" : "*"
}, {
"from" : "*1;*2",
"to" : "*1;*2",
"through" : "*"
}, {
"from" : "=1",
"to" : "L2;L3",
"through" : "L"
}, {
"from" : "L1",
"to" : "=1",
"through" : "="
}, {
"from" : "=1",
"to" : "R3",
"through" : "R"
} ]
},
"buildLog" : {
"operations" : [ {
"message" : "Построим LR-автомат lalr(1)",
"level" : "comment",
"name" : "buildLrAutomaton"
}, {
"message" : "Построим LR-автомат lr(1)",
"level" : "comment",
"name" : "buildLrAutomaton"
}, {
"message" : "Расширяем исходную грамматику.",
"level" : "comment",
"name" : "extendGrammar"
}, {
"message" : "Добавляем состояние '∇'.",
"stateName" : "∇",
"level" : "action",
"name" : "addState"
}, {
"message" : "Добавляем в состояние '∇' пункт '[S'→•S, ⊣]'.",
"state" : "∇",
"item" : {
"rule" : {
"left" : "S'",
"right" : "S"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние '∇' пункт '[S→•R, ⊣]'.",
"state" : "∇",
"item" : {
"rule" : {
"left" : "S",
"right" : "R"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние '∇' пункт '[S→•L=R, ⊣]'.",
"state" : "∇",
"item" : {
"rule" : {
"left" : "S",
"right" : "L=R"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние '∇' пункт '[R→•L, ⊣]'.",
"state" : "∇",
"item" : {
"rule" : {
"left" : "R",
"right" : "L"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние '∇' пункт '[L→•x, =]'.",
"state" : "∇",
"item" : {
"rule" : {
"left" : "L",
"right" : "x"
},
"dotIndex" : 0,
"lookAheadSymbol" : "="
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние '∇' пункт '[L→•*R, =]'.",
"state" : "∇",
"item" : {
"rule" : {
"left" : "L",
"right" : "*R"
},
"dotIndex" : 0,
"lookAheadSymbol" : "="
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние '∇' пункт '[L→•*R, ⊣]'.",
"state" : "∇",
"item" : {
"rule" : {
"left" : "L",
"right" : "*R"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние '∇' пункт '[L→•x, ⊣]'.",
"state" : "∇",
"item" : {
"rule" : {
"left" : "L",
"right" : "x"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Просматриваем состояние '∇'",
"level" : "comment",
"name" : "startAddNewTransitions"
}, {
"message" : "Добавляем состояние 'S1'.",
"stateName" : "S1",
"level" : "action",
"name" : "addState"
}, {
"message" : "Добавляем в состояние 'S1' пункт '[S'→S•, ⊣]'.",
"state" : "S1",
"item" : {
"rule" : {
"left" : "S'",
"right" : "S"
},
"dotIndex" : 1,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем переход из состояния '∇' в состояние 'S1' по символу 'S'.",
"from" : "∇",
"to" : "S1",
"through" : "S",
"level" : "action",
"name" : "addTransition"
}, {
"message" : "Добавляем состояние 'R1'.",
"stateName" : "R1",
"level" : "action",
"name" : "addState"
}, {
"message" : "Добавляем в состояние 'R1' пункт '[S→R•, ⊣]'.",
"state" : "R1",
"item" : {
"rule" : {
"left" : "S",
"right" : "R"
},
"dotIndex" : 1,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем переход из состояния '∇' в состояние 'R1' по символу 'R'.",
"from" : "∇",
"to" : "R1",
"through" : "R",
"level" : "action",
"name" : "addTransition"
}, {
"message" : "Добавляем состояние 'L1'.",
"stateName" : "L1",
"level" : "action",
"name" : "addState"
}, {
"message" : "Добавляем в состояние 'L1' пункт '[S→L•=R, ⊣]'.",
"state" : "L1",
"item" : {
"rule" : {
"left" : "S",
"right" : "L=R"
},
"dotIndex" : 1,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние 'L1' пункт '[R→L•, ⊣]'.",
"state" : "L1",
"item" : {
"rule" : {
"left" : "R",
"right" : "L"
},
"dotIndex" : 1,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем переход из состояния '∇' в состояние 'L1' по символу 'L'.",
"from" : "∇",
"to" : "L1",
"through" : "L",
"level" : "action",
"name" : "addTransition"
}, {
"message" : "Добавляем состояние 'x1'.",
"stateName" : "x1",
"level" : "action",
"name" : "addState"
}, {
"message" : "Добавляем в состояние 'x1' пункт '[L→x•, ⊣]'.",
"state" : "x1",
"item" : {
"rule" : {
"left" : "L",
"right" : "x"
},
"dotIndex" : 1,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние 'x1' пункт '[L→x•, =]'.",
"state" : "x1",
"item" : {
"rule" : {
"left" : "L",
"right" : "x"
},
"dotIndex" : 1,
"lookAheadSymbol" : "="
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем переход из состояния '∇' в состояние 'x1' по символу 'x'.",
"from" : "∇",
"to" : "x1",
"through" : "x",
"level" : "action",
"name" : "addTransition"
}, {
"message" : "Добавляем состояние '*1'.",
"stateName" : "*1",
"level" : "action",
"name" : "addState"
}, {
"message" : "Добавляем в состояние '*1' пункт '[L→*•R, ⊣]'.",
"state" : "*1",
"item" : {
"rule" : {
"left" : "L",
"right" : "*R"
},
"dotIndex" : 1,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние '*1' пункт '[L→*•R, =]'.",
"state" : "*1",
"item" : {
"rule" : {
"left" : "L",
"right" : "*R"
},
"dotIndex" : 1,
"lookAheadSymbol" : "="
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние '*1' пункт '[R→•L, ⊣]'.",
"state" : "*1",
"item" : {
"rule" : {
"left" : "R",
"right" : "L"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние '*1' пункт '[R→•L, =]'.",
"state" : "*1",
"item" : {
"rule" : {
"left" : "R",
"right" : "L"
},
"dotIndex" : 0,
"lookAheadSymbol" : "="
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние '*1' пункт '[L→•*R, ⊣]'.",
"state" : "*1",
"item" : {
"rule" : {
"left" : "L",
"right" : "*R"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние '*1' пункт '[L→•x, ⊣]'.",
"state" : "*1",
"item" : {
"rule" : {
"left" : "L",
"right" : "x"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние '*1' пункт '[L→•x, =]'.",
"state" : "*1",
"item" : {
"rule" : {
"left" : "L",
"right" : "x"
},
"dotIndex" : 0,
"lookAheadSymbol" : "="
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние '*1' пункт '[L→•*R, =]'.",
"state" : "*1",
"item" : {
"rule" : {
"left" : "L",
"right" : "*R"
},
"dotIndex" : 0,
"lookAheadSymbol" : "="
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем переход из состояния '∇' в состояние '*1' по символу '*'.",
"from" : "∇",
"to" : "*1",
"through" : "*",
"level" : "action",
"name" : "addTransition"
}, {
"message" : "Просматриваем состояние 'S1'",
"level" : "comment",
"name" : "startAddNewTransitions"
}, {
"message" : "Просматриваем состояние 'R1'",
"level" : "comment",
"name" : "startAddNewTransitions"
}, {
"message" : "Просматриваем состояние 'L1'",
"level" : "comment",
"name" : "startAddNewTransitions"
}, {
"message" : "Добавляем состояние '=1'.",
"stateName" : "=1",
"level" : "action",
"name" : "addState"
}, {
"message" : "Добавляем в состояние '=1' пункт '[S→L=•R, ⊣]'.",
"state" : "=1",
"item" : {
"rule" : {
"left" : "S",
"right" : "L=R"
},
"dotIndex" : 2,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние '=1' пункт '[R→•L, ⊣]'.",
"state" : "=1",
"item" : {
"rule" : {
"left" : "R",
"right" : "L"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние '=1' пункт '[L→•*R, ⊣]'.",
"state" : "=1",
"item" : {
"rule" : {
"left" : "L",
"right" : "*R"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние '=1' пункт '[L→•x, ⊣]'.",
"state" : "=1",
"item" : {
"rule" : {
"left" : "L",
"right" : "x"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем переход из состояния 'L1' в состояние '=1' по символу '='.",
"from" : "L1",
"to" : "=1",
"through" : "=",
"level" : "action",
"name" : "addTransition"
}, {
"message" : "Просматриваем состояние 'x1'",
"level" : "comment",
"name" : "startAddNewTransitions"
}, {
"message" : "Просматриваем состояние '*1'",
"level" : "comment",
"name" : "startAddNewTransitions"
}, {
"message" : "Добавляем состояние 'R2'.",
"stateName" : "R2",
"level" : "action",
"name" : "addState"
}, {
"message" : "Добавляем в состояние 'R2' пункт '[L→*R•, =]'.",
"state" : "R2",
"item" : {
"rule" : {
"left" : "L",
"right" : "*R"
},
"dotIndex" : 2,
"lookAheadSymbol" : "="
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние 'R2' пункт '[L→*R•, ⊣]'.",
"state" : "R2",
"item" : {
"rule" : {
"left" : "L",
"right" : "*R"
},
"dotIndex" : 2,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем переход из состояния '*1' в состояние 'R2' по символу 'R'.",
"from" : "*1",
"to" : "R2",
"through" : "R",
"level" : "action",
"name" : "addTransition"
}, {
"message" : "Добавляем состояние 'L2'.",
"stateName" : "L2",
"level" : "action",
"name" : "addState"
}, {
"message" : "Добавляем в состояние 'L2' пункт '[R→L•, ⊣]'.",
"state" : "L2",
"item" : {
"rule" : {
"left" : "R",
"right" : "L"
},
"dotIndex" : 1,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние 'L2' пункт '[R→L•, =]'.",
"state" : "L2",
"item" : {
"rule" : {
"left" : "R",
"right" : "L"
},
"dotIndex" : 1,
"lookAheadSymbol" : "="
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем переход из состояния '*1' в состояние 'L2' по символу 'L'.",
"from" : "*1",
"to" : "L2",
"through" : "L",
"level" : "action",
"name" : "addTransition"
}, {
"message" : "Добавляем переход из состояния '*1' в состояние '*1' по символу '*'.",
"from" : "*1",
"to" : "*1",
"through" : "*",
"level" : "action",
"name" : "addTransition"
}, {
"message" : "Добавляем переход из состояния '*1' в состояние 'x1' по символу 'x'.",
"from" : "*1",
"to" : "x1",
"through" : "x",
"level" : "action",
"name" : "addTransition"
}, {
"message" : "Просматриваем состояние '=1'",
"level" : "comment",
"name" : "startAddNewTransitions"
}, {
"message" : "Добавляем состояние 'R3'.",
"stateName" : "R3",
"level" : "action",
"name" : "addState"
}, {
"message" : "Добавляем в состояние 'R3' пункт '[S→L=R•, ⊣]'.",
"state" : "R3",
"item" : {
"rule" : {
"left" : "S",
"right" : "L=R"
},
"dotIndex" : 3,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем переход из состояния '=1' в состояние 'R3' по символу 'R'.",
"from" : "=1",
"to" : "R3",
"through" : "R",
"level" : "action",
"name" : "addTransition"
}, {
"message" : "Добавляем состояние 'L3'.",
"stateName" : "L3",
"level" : "action",
"name" : "addState"
}, {
"message" : "Добавляем в состояние 'L3' пункт '[R→L•, ⊣]'.",
"state" : "L3",
"item" : {
"rule" : {
"left" : "R",
"right" : "L"
},
"dotIndex" : 1,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем переход из состояния '=1' в состояние 'L3' по символу 'L'.",
"from" : "=1",
"to" : "L3",
"through" : "L",
"level" : "action",
"name" : "addTransition"
}, {
"message" : "Добавляем состояние '*2'.",
"stateName" : "*2",
"level" : "action",
"name" : "addState"
}, {
"message" : "Добавляем в состояние '*2' пункт '[L→*•R, ⊣]'.",
"state" : "*2",
"item" : {
"rule" : {
"left" : "L",
"right" : "*R"
},
"dotIndex" : 1,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние '*2' пункт '[R→•L, ⊣]'.",
"state" : "*2",
"item" : {
"rule" : {
"left" : "R",
"right" : "L"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние '*2' пункт '[L→•*R, ⊣]'.",
"state" : "*2",
"item" : {
"rule" : {
"left" : "L",
"right" : "*R"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние '*2' пункт '[L→•x, ⊣]'.",
"state" : "*2",
"item" : {
"rule" : {
"left" : "L",
"right" : "x"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем переход из состояния '=1' в состояние '*2' по символу '*'.",
"from" : "=1",
"to" : "*2",
"through" : "*",
"level" : "action",
"name" : "addTransition"
}, {
"message" : "Добавляем состояние 'x2'.",
"stateName" : "x2",
"level" : "action",
"name" : "addState"
}, {
"message" : "Добавляем в состояние 'x2' пункт '[L→x•, ⊣]'.",
"state" : "x2",
"item" : {
"rule" : {
"left" : "L",
"right" : "x"
},
"dotIndex" : 1,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем переход из состояния '=1' в состояние 'x2' по символу 'x'.",
"from" : "=1",
"to" : "x2",
"through" : "x",
"level" : "action",
"name" : "addTransition"
}, {
"message" : "Просматриваем состояние 'R2'",
"level" : "comment",
"name" : "startAddNewTransitions"
}, {
"message" : "Просматриваем состояние 'L2'",
"level" : "comment",
"name" : "startAddNewTransitions"
}, {
"message" : "Просматриваем состояние 'R3'",
"level" : "comment",
"name" : "startAddNewTransitions"
}, {
"message" : "Просматриваем состояние 'L3'",
"level" : "comment",
"name" : "startAddNewTransitions"
}, {
"message" : "Просматриваем состояние '*2'",
"level" : "comment",
"name" : "startAddNewTransitions"
}, {
"message" : "Добавляем состояние 'R4'.",
"stateName" : "R4",
"level" : "action",
"name" : "addState"
}, {
"message" : "Добавляем в состояние 'R4' пункт '[L→*R•, ⊣]'.",
"state" : "R4",
"item" : {
"rule" : {
"left" : "L",
"right" : "*R"
},
"dotIndex" : 2,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем переход из состояния '*2' в состояние 'R4' по символу 'R'.",
"from" : "*2",
"to" : "R4",
"through" : "R",
"level" : "action",
"name" : "addTransition"
}, {
"message" : "Добавляем переход из состояния '*2' в состояние 'L3' по символу 'L'.",
"from" : "*2",
"to" : "L3",
"through" : "L",
"level" : "action",
"name" : "addTransition"
}, {
"message" : "Добавляем переход из состояния '*2' в состояние '*2' по символу '*'.",
"from" : "*2",
"to" : "*2",
"through" : "*",
"level" : "action",
"name" : "addTransition"
}, {
"message" : "Добавляем переход из состояния '*2' в состояние 'x2' по символу 'x'.",
"from" : "*2",
"to" : "x2",
"through" : "x",
"level" : "action",
"name" : "addTransition"
}, {
"message" : "Просматриваем состояние 'x2'",
"level" : "comment",
"name" : "startAddNewTransitions"
}, {
"message" : "Просматриваем состояние 'R4'",
"level" : "comment",
"name" : "startAddNewTransitions"
}, {
"message" : "Уплотняем полученный LR-автомат",
"level" : "comment",
"name" : "compactLRAutomaton"
}, {
"message" : "Удаляем переход из состояния '∇' в состояние '*1' по символу '*'.",
"from" : "∇",
"to" : "*1",
"through" : "*",
"level" : "action",
"name" : "deleteTransition"
}, {
"message" : "Удаляем переход из состояния '*2' в состояние 'L3' по символу 'L'.",
"from" : "*2",
"to" : "L3",
"through" : "L",
"level" : "action",
"name" : "deleteTransition"
}, {
"message" : "Удаляем переход из состояния '*1' в состояние 'L2' по символу 'L'.",
"from" : "*1",
"to" : "L2",
"through" : "L",
"level" : "action",
"name" : "deleteTransition"
}, {
"message" : "Удаляем переход из состояния '*1' в состояние '*1' по символу '*'.",
"from" : "*1",
"to" : "*1",
"through" : "*",
"level" : "action",
"name" : "deleteTransition"
}, {
"message" : "Удаляем переход из состояния '*2' в состояние 'R4' по символу 'R'.",
"from" : "*2",
"to" : "R4",
"through" : "R",
"level" : "action",
"name" : "deleteTransition"
}, {
"message" : "Удаляем переход из состояния '*1' в состояние 'x1' по символу 'x'.",
"from" : "*1",
"to" : "x1",
"through" : "x",
"level" : "action",
"name" : "deleteTransition"
}, {
"message" : "Удаляем переход из состояния '*2' в состояние '*2' по символу '*'.",
"from" : "*2",
"to" : "*2",
"through" : "*",
"level" : "action",
"name" : "deleteTransition"
}, {
"message" : "Удаляем переход из состояния '*2' в состояние 'x2' по символу 'x'.",
"from" : "*2",
"to" : "x2",
"through" : "x",
"level" : "action",
"name" : "deleteTransition"
}, {
"message" : "Удаляем переход из состояния '*1' в состояние 'R2' по символу 'R'.",
"from" : "*1",
"to" : "R2",
"through" : "R",
"level" : "action",
"name" : "deleteTransition"
}, {
"message" : "Удаляем переход из состояния '∇' в состояние 'x1' по символу 'x'.",
"from" : "∇",
"to" : "x1",
"through" : "x",
"level" : "action",
"name" : "deleteTransition"
}, {
"message" : "Удаляем переход из состояния '=1' в состояние '*2' по символу '*'.",
"from" : "=1",
"to" : "*2",
"through" : "*",
"level" : "action",
"name" : "deleteTransition"
}, {
"message" : "Удаляем переход из состояния '=1' в состояние 'x2' по символу 'x'.",
"from" : "=1",
"to" : "x2",
"through" : "x",
"level" : "action",
"name" : "deleteTransition"
}, {
"message" : "Удаляем переход из состояния '=1' в состояние 'L3' по символу 'L'.",
"from" : "=1",
"to" : "L3",
"through" : "L",
"level" : "action",
"name" : "deleteTransition"
}, {
"message" : "Удаляем состояние 'R2'.",
"stateName" : "R2",
"level" : "action",
"name" : "deleteState"
}, {
"message" : "Удаляем состояние 'R4'.",
"stateName" : "R4",
"level" : "action",
"name" : "deleteState"
}, {
"message" : "Удаляем состояние 'L2'.",
"stateName" : "L2",
"level" : "action",
"name" : "deleteState"
}, {
"message" : "Удаляем состояние '*1'.",
"stateName" : "*1",
"level" : "action",
"name" : "deleteState"
}, {
"message" : "Удаляем состояние 'L3'.",
"stateName" : "L3",
"level" : "action",
"name" : "deleteState"
}, {
"message" : "Удаляем состояние '*2'.",
"stateName" : "*2",
"level" : "action",
"name" : "deleteState"
}, {
"message" : "Удаляем состояние 'x1'.",
"stateName" : "x1",
"level" : "action",
"name" : "deleteState"
}, {
"message" : "Удаляем состояние 'x2'.",
"stateName" : "x2",
"level" : "action",
"name" : "deleteState"
}, {
"message" : "Добавляем состояние 'R2;R4'.",
"stateName" : "R2;R4",
"level" : "action",
"name" : "addState"
}, {
"message" : "Добавляем в состояние 'R2;R4' пункт '[L→*R•, =]'.",
"state" : "R2;R4",
"item" : {
"rule" : {
"left" : "L",
"right" : "*R"
},
"dotIndex" : 2,
"lookAheadSymbol" : "="
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние 'R2;R4' пункт '[L→*R•, ⊣]'.",
"state" : "R2;R4",
"item" : {
"rule" : {
"left" : "L",
"right" : "*R"
},
"dotIndex" : 2,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем состояние 'L2;L3'.",
"stateName" : "L2;L3",
"level" : "action",
"name" : "addState"
}, {
"message" : "Добавляем в состояние 'L2;L3' пункт '[R→L•, ⊣]'.",
"state" : "L2;L3",
"item" : {
"rule" : {
"left" : "R",
"right" : "L"
},
"dotIndex" : 1,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние 'L2;L3' пункт '[R→L•, =]'.",
"state" : "L2;L3",
"item" : {
"rule" : {
"left" : "R",
"right" : "L"
},
"dotIndex" : 1,
"lookAheadSymbol" : "="
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем состояние '*1;*2'.",
"stateName" : "*1;*2",
"level" : "action",
"name" : "addState"
}, {
"message" : "Добавляем в состояние '*1;*2' пункт '[L→*•R, ⊣]'.",
"state" : "*1;*2",
"item" : {
"rule" : {
"left" : "L",
"right" : "*R"
},
"dotIndex" : 1,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние '*1;*2' пункт '[L→*•R, =]'.",
"state" : "*1;*2",
"item" : {
"rule" : {
"left" : "L",
"right" : "*R"
},
"dotIndex" : 1,
"lookAheadSymbol" : "="
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние '*1;*2' пункт '[R→•L, ⊣]'.",
"state" : "*1;*2",
"item" : {
"rule" : {
"left" : "R",
"right" : "L"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние '*1;*2' пункт '[R→•L, =]'.",
"state" : "*1;*2",
"item" : {
"rule" : {
"left" : "R",
"right" : "L"
},
"dotIndex" : 0,
"lookAheadSymbol" : "="
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние '*1;*2' пункт '[L→•*R, ⊣]'.",
"state" : "*1;*2",
"item" : {
"rule" : {
"left" : "L",
"right" : "*R"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние '*1;*2' пункт '[L→•x, ⊣]'.",
"state" : "*1;*2",
"item" : {
"rule" : {
"left" : "L",
"right" : "x"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние '*1;*2' пункт '[L→•x, =]'.",
"state" : "*1;*2",
"item" : {
"rule" : {
"left" : "L",
"right" : "x"
},
"dotIndex" : 0,
"lookAheadSymbol" : "="
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние '*1;*2' пункт '[L→•*R, =]'.",
"state" : "*1;*2",
"item" : {
"rule" : {
"left" : "L",
"right" : "*R"
},
"dotIndex" : 0,
"lookAheadSymbol" : "="
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем состояние 'x1;x2'.",
"stateName" : "x1;x2",
"level" : "action",
"name" : "addState"
}, {
"message" : "Добавляем в состояние 'x1;x2' пункт '[L→x•, ⊣]'.",
"state" : "x1;x2",
"item" : {
"rule" : {
"left" : "L",
"right" : "x"
},
"dotIndex" : 1,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние 'x1;x2' пункт '[L→x•, =]'.",
"state" : "x1;x2",
"item" : {
"rule" : {
"left" : "L",
"right" : "x"
},
"dotIndex" : 1,
"lookAheadSymbol" : "="
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем переход из состояния '=1' в состояние 'L2;L3' по символу 'L'.",
"from" : "=1",
"to" : "L2;L3",
"through" : "L",
"level" : "action",
"name" : "addTransition"
}, {
"message" : "Добавляем переход из состояния '*1;*2' в состояние 'L2;L3' по символу 'L'.",
"from" : "*1;*2",
"to" : "L2;L3",
"through" : "L",
"level" : "action",
"name" : "addTransition"
}, {
"message" : "Добавляем переход из состояния '*1;*2' в состояние 'R2;R4' по символу 'R'.",
"from" : "*1;*2",
"to" : "R2;R4",
"through" : "R",
"level" : "action",
"name" : "addTransition"
}, {
"message" : "Добавляем переход из состояния '=1' в состояние 'x1;x2' по символу 'x'.",
"from" : "=1",
"to" : "x1;x2",
"through" : "x",
"level" : "action",
"name" : "addTransition"
}, {
"message" : "Добавляем переход из состояния '*1;*2' в состояние 'x1;x2' по символу 'x'.",
"from" : "*1;*2",
"to" : "x1;x2",
"through" : "x",
"level" : "action",
"name" : "addTransition"
}, {
"message" : "Добавляем переход из состояния '∇' в состояние 'x1;x2' по символу 'x'.",
"from" : "∇",
"to" : "x1;x2",
"through" : "x",
"level" : "action",
"name" : "addTransition"
}, {
"message" : "Добавляем переход из состояния '∇' в состояние '*1;*2' по символу '*'.",
"from" : "∇",
"to" : "*1;*2",
"through" : "*",
"level" : "action",
"name" : "addTransition"
}, {
"message" : "Добавляем переход из состояния '*1;*2' в состояние '*1;*2' по символу '*'.",
"from" : "*1;*2",
"to" : "*1;*2",
"through" : "*",
"level" : "action",
"name" : "addTransition"
}, {
"message" : "Добавляем переход из состояния '=1' в состояние '*1;*2' по символу '*'.",
"from" : "=1",
"to" : "*1;*2",
"through" : "*",
"level" : "action",
"name" : "addTransition"
} ]
}
}
POST api/{v1+}/build/lalr1 (png)
Строит LALR(1)-автомат. Результат возвращает в формате png.
Заголовки запроса
| Имя | Описание |
|---|---|
Content-Type |
image/png |
Параметры пути
| Имя | Описание |
|---|---|
version |
версия API |
Тело запроса
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
.grammar |
Object |
Да |
Грамматика, по которой требуется построить LR-автомат |
.grammar.terminals |
Array |
Да |
Список терминалов грамматики. |
.grammar.nonTerminals |
Array |
Да |
Список нетерминалов грамматики |
.grammar.rules |
Array |
Да |
Список правил грамматики |
.grammar.rules[].left |
String |
Да |
Нетерминал левой части правила грамматики |
.grammar.rules[].right |
String |
Да |
Символы правой части правила грамматики |
.grammar.startSymbol |
String |
Да |
Аксиома грамматики (нетерминал) |
.buildOptions |
Object |
Нет |
Параметры построения LR-автомата |
.buildOptions.namesGenerationStrategy |
String |
Нет |
Стратегия генерации имен состояний при построении автомата |
.buildOptions.lalr1BuildAlgorithm |
String |
Нет |
|
visualizeOperations.colorizeTransitions |
Boolean |
Нет |
Нужно ли окрашивать переходы автомата. По умолчанию не окрашиваются. |
visualizeOperations.colorizeStateNames |
Boolean |
Нет |
Окрашивать ли имена состояний. По умолчанию не окрашиваются. |
visualizeOperations.stateNameStyle |
String |
Нет |
Стиль оформления названия состояния. По умолчанию 'onBlackBackground'. |
Заголовки ответа
| Имя | Описание |
|---|---|
Content-Type |
application/json |
curl
$ curl 'http://localhost:8080/api/v1/build/lalr1' -i -X POST \
-H 'Content-Type: application/json' \
-H 'Accept: image/png' \
-d '{
"grammar" : {
"terminals" : [ "i", "+", "(", ")" ],
"nonTerminals" : [ "E", "T" ],
"rules" : [ {
"left" : "E",
"right" : "T"
}, {
"left" : "E",
"right" : "E+T"
}, {
"left" : "T",
"right" : "i"
}, {
"left" : "T",
"right" : "(E)"
} ],
"startSymbol" : "E"
}
}'
Пример запроса
POST /api/v1/build/lalr1 HTTP/1.1
Content-Type: application/json
Accept: image/png
Content-Length: 342
Host: localhost:8080
{
"grammar" : {
"terminals" : [ "i", "+", "(", ")" ],
"nonTerminals" : [ "E", "T" ],
"rules" : [ {
"left" : "E",
"right" : "T"
}, {
"left" : "E",
"right" : "E+T"
}, {
"left" : "T",
"right" : "i"
}, {
"left" : "T",
"right" : "(E)"
} ],
"startSymbol" : "E"
}
}
Пример ответа
POST api/{v1+}/build/lalr1 (zip)
Строит LALR(1)-автомат. Лог построения возвращает в zip архиве с изображениями автомата.
Заголовки запроса
| Имя | Описание |
|---|---|
Accept |
application/octet-stream |
Параметры пути
| Имя | Описание |
|---|---|
version |
версия API |
Тело запроса
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
.grammar |
Object |
Да |
Грамматика, по которой требуется построить LR-автомат |
.grammar.terminals |
Array |
Да |
Список терминалов грамматики. |
.grammar.nonTerminals |
Array |
Да |
Список нетерминалов грамматики |
.grammar.rules |
Array |
Да |
Список правил грамматики |
.grammar.rules[].left |
String |
Да |
Нетерминал левой части правила грамматики |
.grammar.rules[].right |
String |
Да |
Символы правой части правила грамматики |
.grammar.startSymbol |
String |
Да |
Аксиома грамматики (нетерминал) |
.buildOptions |
Object |
Нет |
Параметры построения LR-автомата |
.buildOptions.namesGenerationStrategy |
String |
Нет |
Стратегия генерации имен состояний при построении автомата |
.buildOptions.lalr1BuildAlgorithm |
String |
Нет |
|
visualizeOperations.visualizeOperations |
Array |
Нет |
Номера операций, которые нужно визуализировать. Если не указаны, то визуализируются все операции |
visualizeOperations.colorizeTransitions |
Boolean |
Нет |
Нужно ли окрашивать переходы автомата. По умолчанию не окрашиваются. |
visualizeOperations.colorizeStateNames |
Boolean |
Нет |
Окрашивать ли имена состояний. По умолчанию не окрашиваются. |
visualizeOperations.stateNameStyle |
String |
Нет |
Стиль оформления названия состояния. По умолчанию 'onBlackBackground'. |
Заголовки ответа
| Имя | Описание |
|---|---|
Content-Type |
application/octet-stream (zip) |
curl
$ curl 'http://localhost:8080/api/v1/build/lalr1' -i -X POST \
-H 'Content-Type: application/json' \
-H 'Accept: application/octet-stream' \
-d '{
"grammar" : {
"terminals" : [ "a", "b", "c", "d" ],
"nonTerminals" : [ "S", "A" ],
"rules" : [ {
"left" : "S",
"right" : "Aa"
}, {
"left" : "S",
"right" : "bAc"
}, {
"left" : "S",
"right" : "bc"
}, {
"left" : "S",
"right" : "bda"
}, {
"left" : "A",
"right" : "d"
} ],
"startSymbol" : "S"
}
}'
Пример запроса
POST /api/v1/build/lalr1 HTTP/1.1
Content-Type: application/json
Accept: application/octet-stream
Content-Length: 393
Host: localhost:8080
{
"grammar" : {
"terminals" : [ "a", "b", "c", "d" ],
"nonTerminals" : [ "S", "A" ],
"rules" : [ {
"left" : "S",
"right" : "Aa"
}, {
"left" : "S",
"right" : "bAc"
}, {
"left" : "S",
"right" : "bc"
}, {
"left" : "S",
"right" : "bda"
}, {
"left" : "A",
"right" : "d"
} ],
"startSymbol" : "S"
}
}
POST api/{v1+}/build/lr1 (json)
Строит LR(1)-автомат. Результат возвращает в формате json.
Заголовки запроса
| Имя | Описание |
|---|---|
Accept |
application/json |
Параметры пути
| Имя | Описание |
|---|---|
version |
версия API |
Тело запроса
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
.grammar |
Object |
Да |
Грамматика, по которой требуется построить LR-автомат |
.grammar.terminals |
Array |
Да |
Список терминалов грамматики. |
.grammar.nonTerminals |
Array |
Да |
Список нетерминалов грамматики |
.grammar.rules |
Array |
Да |
Список правил грамматики |
.grammar.rules[].left |
String |
Да |
Нетерминал левой части правила грамматики |
.grammar.rules[].right |
String |
Да |
Символы правой части правила грамматики |
.grammar.startSymbol |
String |
Да |
Аксиома грамматики (нетерминал) |
.buildOptions |
Object |
Нет |
Параметры построения LR-автомата |
.buildOptions.namesGenerationStrategy |
String |
Нет |
Стратегия генерации имен состояний при построении автомата |
.buildOptions.lalr1BuildAlgorithm |
String |
Нет |
|
.buildOptions.enableBuildLog |
Boolean |
Нет |
Передавать ли в ответе лог построения |
Заголовки ответа
| Имя | Описание |
|---|---|
Content-Type |
application/json |
Тело ответа
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
.automaton |
Object |
Да |
Построенный LR-автомат |
.automaton.states |
Array |
Да |
Состояния автомата |
.automaton.states[].name |
String |
Да |
Имя состояния |
.automaton.states[].items |
Array |
Да |
LR(0)-пункты в состоянии |
.automaton.states[].items[].rule |
Object |
Да |
Правило грамматики пункта |
.automaton.states[].items[].rule.left |
String |
Да |
Левая часть правила |
.automaton.states[].items[].rule.right |
String |
Да |
Правая часть правила |
.automaton.states[].items[].dotIndex |
Number |
Да |
Позиция точки в правой части правила |
.automaton.transitions |
Array |
Да |
Переходы между состояниями автомата |
.automaton.transitions[].from |
String |
Да |
Исходное состояние |
.automaton.transitions[].to |
String |
Да |
Целевое состояние |
.automaton.transitions[].through |
String |
Да |
Символ перехода |
.buildLog |
Object |
Нет |
Лог построения LR-автомата (если указана соответствующая опция) |
.buildLog.operations |
Array |
Да |
Последовательность операций построения |
.buildLog.operations[].message |
String |
Да |
Человекочитаемое описание операции |
.buildLog.operations[].level |
String |
Да |
Тип операции |
.buildLog.operations[].name |
String |
Да |
Имя операции |
.buildLog.operations[].stateName |
String |
Нет |
Имя состояния |
.buildLog.operations[].state |
String |
Нет |
Состояние, к которому применяется операция |
.buildLog.operations[].item |
Object |
Нет |
LR-пункт, связанный с операцией |
.buildLog.operations[].item.rule.left |
String |
Нет |
Левая часть правила пункта |
.buildLog.operations[].item.rule.right |
String |
Нет |
Правая часть правила пункта |
.buildLog.operations[].item.dotIndex |
Number |
Нет |
Позиция точки |
.buildLog.operations[].from |
String |
Нет |
Исходное состояние перехода |
.buildLog.operations[].to |
String |
Нет |
Целевое состояние перехода |
.buildLog.operations[].through |
String |
Нет |
Символ перехода |
.automaton.states[].items[].lookAheadSymbol |
String |
Нет |
Символ предпросмотра |
.buildLog.operations[].item.lookAheadSymbol |
String |
Нет |
Символ предпросмотра |
.automaton.states[].items[].lookAheadSymbols |
Array |
Нет |
Символы предпросмотра (при построении через канальный алгоритм) |
curl
$ curl 'http://localhost:8080/api/v1/build/lalr1' -i -X POST \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d '{
"grammar" : {
"terminals" : [ "x", "*", "=" ],
"nonTerminals" : [ "S", "L", "R" ],
"rules" : [ {
"left" : "S",
"right" : "L=R"
}, {
"left" : "S",
"right" : "R"
}, {
"left" : "L",
"right" : "*R"
}, {
"left" : "L",
"right" : "x"
}, {
"left" : "R",
"right" : "L"
} ],
"startSymbol" : "S"
},
"buildOptions" : {
"enableBuildLog" : true
}
}'
Примеры
Пример запроса
POST /api/v1/build/lalr1 HTTP/1.1
Content-Type: application/json
Accept: application/json
Content-Length: 444
Host: localhost:8080
{
"grammar" : {
"terminals" : [ "x", "*", "=" ],
"nonTerminals" : [ "S", "L", "R" ],
"rules" : [ {
"left" : "S",
"right" : "L=R"
}, {
"left" : "S",
"right" : "R"
}, {
"left" : "L",
"right" : "*R"
}, {
"left" : "L",
"right" : "x"
}, {
"left" : "R",
"right" : "L"
} ],
"startSymbol" : "S"
},
"buildOptions" : {
"enableBuildLog" : true
}
}
Пример ответа
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 41323
{
"automaton" : {
"states" : [ {
"name" : "R3",
"items" : [ {
"rule" : {
"left" : "S",
"right" : "L=R"
},
"dotIndex" : 3,
"lookAheadSymbol" : "⊣"
} ]
}, {
"name" : "=1",
"items" : [ {
"rule" : {
"left" : "S",
"right" : "L=R"
},
"dotIndex" : 2,
"lookAheadSymbol" : "⊣"
}, {
"rule" : {
"left" : "R",
"right" : "L"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
}, {
"rule" : {
"left" : "L",
"right" : "*R"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
}, {
"rule" : {
"left" : "L",
"right" : "x"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
} ]
}, {
"name" : "L1",
"items" : [ {
"rule" : {
"left" : "S",
"right" : "L=R"
},
"dotIndex" : 1,
"lookAheadSymbol" : "⊣"
}, {
"rule" : {
"left" : "R",
"right" : "L"
},
"dotIndex" : 1,
"lookAheadSymbol" : "⊣"
} ]
}, {
"name" : "R2;R4",
"items" : [ {
"rule" : {
"left" : "L",
"right" : "*R"
},
"dotIndex" : 2,
"lookAheadSymbol" : "="
}, {
"rule" : {
"left" : "L",
"right" : "*R"
},
"dotIndex" : 2,
"lookAheadSymbol" : "⊣"
} ]
}, {
"name" : "∇",
"items" : [ {
"rule" : {
"left" : "S'",
"right" : "S"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
}, {
"rule" : {
"left" : "S",
"right" : "R"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
}, {
"rule" : {
"left" : "S",
"right" : "L=R"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
}, {
"rule" : {
"left" : "R",
"right" : "L"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
}, {
"rule" : {
"left" : "L",
"right" : "x"
},
"dotIndex" : 0,
"lookAheadSymbol" : "="
}, {
"rule" : {
"left" : "L",
"right" : "*R"
},
"dotIndex" : 0,
"lookAheadSymbol" : "="
}, {
"rule" : {
"left" : "L",
"right" : "*R"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
}, {
"rule" : {
"left" : "L",
"right" : "x"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
} ]
}, {
"name" : "L2;L3",
"items" : [ {
"rule" : {
"left" : "R",
"right" : "L"
},
"dotIndex" : 1,
"lookAheadSymbol" : "⊣"
}, {
"rule" : {
"left" : "R",
"right" : "L"
},
"dotIndex" : 1,
"lookAheadSymbol" : "="
} ]
}, {
"name" : "*1;*2",
"items" : [ {
"rule" : {
"left" : "L",
"right" : "*R"
},
"dotIndex" : 1,
"lookAheadSymbol" : "⊣"
}, {
"rule" : {
"left" : "L",
"right" : "*R"
},
"dotIndex" : 1,
"lookAheadSymbol" : "="
}, {
"rule" : {
"left" : "R",
"right" : "L"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
}, {
"rule" : {
"left" : "R",
"right" : "L"
},
"dotIndex" : 0,
"lookAheadSymbol" : "="
}, {
"rule" : {
"left" : "L",
"right" : "*R"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
}, {
"rule" : {
"left" : "L",
"right" : "x"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
}, {
"rule" : {
"left" : "L",
"right" : "x"
},
"dotIndex" : 0,
"lookAheadSymbol" : "="
}, {
"rule" : {
"left" : "L",
"right" : "*R"
},
"dotIndex" : 0,
"lookAheadSymbol" : "="
} ]
}, {
"name" : "x1;x2",
"items" : [ {
"rule" : {
"left" : "L",
"right" : "x"
},
"dotIndex" : 1,
"lookAheadSymbol" : "⊣"
}, {
"rule" : {
"left" : "L",
"right" : "x"
},
"dotIndex" : 1,
"lookAheadSymbol" : "="
} ]
}, {
"name" : "S1",
"items" : [ {
"rule" : {
"left" : "S'",
"right" : "S"
},
"dotIndex" : 1,
"lookAheadSymbol" : "⊣"
} ]
}, {
"name" : "R1",
"items" : [ {
"rule" : {
"left" : "S",
"right" : "R"
},
"dotIndex" : 1,
"lookAheadSymbol" : "⊣"
} ]
} ],
"transitions" : [ {
"from" : "∇",
"to" : "L1",
"through" : "L"
}, {
"from" : "=1",
"to" : "x1;x2",
"through" : "x"
}, {
"from" : "*1;*2",
"to" : "x1;x2",
"through" : "x"
}, {
"from" : "∇",
"to" : "*1;*2",
"through" : "*"
}, {
"from" : "∇",
"to" : "S1",
"through" : "S"
}, {
"from" : "*1;*2",
"to" : "L2;L3",
"through" : "L"
}, {
"from" : "∇",
"to" : "R1",
"through" : "R"
}, {
"from" : "*1;*2",
"to" : "R2;R4",
"through" : "R"
}, {
"from" : "∇",
"to" : "x1;x2",
"through" : "x"
}, {
"from" : "=1",
"to" : "*1;*2",
"through" : "*"
}, {
"from" : "*1;*2",
"to" : "*1;*2",
"through" : "*"
}, {
"from" : "=1",
"to" : "L2;L3",
"through" : "L"
}, {
"from" : "L1",
"to" : "=1",
"through" : "="
}, {
"from" : "=1",
"to" : "R3",
"through" : "R"
} ]
},
"buildLog" : {
"operations" : [ {
"message" : "Построим LR-автомат lalr(1)",
"level" : "comment",
"name" : "buildLrAutomaton"
}, {
"message" : "Построим LR-автомат lr(1)",
"level" : "comment",
"name" : "buildLrAutomaton"
}, {
"message" : "Расширяем исходную грамматику.",
"level" : "comment",
"name" : "extendGrammar"
}, {
"message" : "Добавляем состояние '∇'.",
"stateName" : "∇",
"level" : "action",
"name" : "addState"
}, {
"message" : "Добавляем в состояние '∇' пункт '[S'→•S, ⊣]'.",
"state" : "∇",
"item" : {
"rule" : {
"left" : "S'",
"right" : "S"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние '∇' пункт '[S→•R, ⊣]'.",
"state" : "∇",
"item" : {
"rule" : {
"left" : "S",
"right" : "R"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние '∇' пункт '[S→•L=R, ⊣]'.",
"state" : "∇",
"item" : {
"rule" : {
"left" : "S",
"right" : "L=R"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние '∇' пункт '[R→•L, ⊣]'.",
"state" : "∇",
"item" : {
"rule" : {
"left" : "R",
"right" : "L"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние '∇' пункт '[L→•x, =]'.",
"state" : "∇",
"item" : {
"rule" : {
"left" : "L",
"right" : "x"
},
"dotIndex" : 0,
"lookAheadSymbol" : "="
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние '∇' пункт '[L→•*R, =]'.",
"state" : "∇",
"item" : {
"rule" : {
"left" : "L",
"right" : "*R"
},
"dotIndex" : 0,
"lookAheadSymbol" : "="
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние '∇' пункт '[L→•*R, ⊣]'.",
"state" : "∇",
"item" : {
"rule" : {
"left" : "L",
"right" : "*R"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние '∇' пункт '[L→•x, ⊣]'.",
"state" : "∇",
"item" : {
"rule" : {
"left" : "L",
"right" : "x"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Просматриваем состояние '∇'",
"level" : "comment",
"name" : "startAddNewTransitions"
}, {
"message" : "Добавляем состояние 'S1'.",
"stateName" : "S1",
"level" : "action",
"name" : "addState"
}, {
"message" : "Добавляем в состояние 'S1' пункт '[S'→S•, ⊣]'.",
"state" : "S1",
"item" : {
"rule" : {
"left" : "S'",
"right" : "S"
},
"dotIndex" : 1,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем переход из состояния '∇' в состояние 'S1' по символу 'S'.",
"from" : "∇",
"to" : "S1",
"through" : "S",
"level" : "action",
"name" : "addTransition"
}, {
"message" : "Добавляем состояние 'R1'.",
"stateName" : "R1",
"level" : "action",
"name" : "addState"
}, {
"message" : "Добавляем в состояние 'R1' пункт '[S→R•, ⊣]'.",
"state" : "R1",
"item" : {
"rule" : {
"left" : "S",
"right" : "R"
},
"dotIndex" : 1,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем переход из состояния '∇' в состояние 'R1' по символу 'R'.",
"from" : "∇",
"to" : "R1",
"through" : "R",
"level" : "action",
"name" : "addTransition"
}, {
"message" : "Добавляем состояние 'L1'.",
"stateName" : "L1",
"level" : "action",
"name" : "addState"
}, {
"message" : "Добавляем в состояние 'L1' пункт '[S→L•=R, ⊣]'.",
"state" : "L1",
"item" : {
"rule" : {
"left" : "S",
"right" : "L=R"
},
"dotIndex" : 1,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние 'L1' пункт '[R→L•, ⊣]'.",
"state" : "L1",
"item" : {
"rule" : {
"left" : "R",
"right" : "L"
},
"dotIndex" : 1,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем переход из состояния '∇' в состояние 'L1' по символу 'L'.",
"from" : "∇",
"to" : "L1",
"through" : "L",
"level" : "action",
"name" : "addTransition"
}, {
"message" : "Добавляем состояние 'x1'.",
"stateName" : "x1",
"level" : "action",
"name" : "addState"
}, {
"message" : "Добавляем в состояние 'x1' пункт '[L→x•, ⊣]'.",
"state" : "x1",
"item" : {
"rule" : {
"left" : "L",
"right" : "x"
},
"dotIndex" : 1,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние 'x1' пункт '[L→x•, =]'.",
"state" : "x1",
"item" : {
"rule" : {
"left" : "L",
"right" : "x"
},
"dotIndex" : 1,
"lookAheadSymbol" : "="
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем переход из состояния '∇' в состояние 'x1' по символу 'x'.",
"from" : "∇",
"to" : "x1",
"through" : "x",
"level" : "action",
"name" : "addTransition"
}, {
"message" : "Добавляем состояние '*1'.",
"stateName" : "*1",
"level" : "action",
"name" : "addState"
}, {
"message" : "Добавляем в состояние '*1' пункт '[L→*•R, ⊣]'.",
"state" : "*1",
"item" : {
"rule" : {
"left" : "L",
"right" : "*R"
},
"dotIndex" : 1,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние '*1' пункт '[L→*•R, =]'.",
"state" : "*1",
"item" : {
"rule" : {
"left" : "L",
"right" : "*R"
},
"dotIndex" : 1,
"lookAheadSymbol" : "="
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние '*1' пункт '[R→•L, ⊣]'.",
"state" : "*1",
"item" : {
"rule" : {
"left" : "R",
"right" : "L"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние '*1' пункт '[R→•L, =]'.",
"state" : "*1",
"item" : {
"rule" : {
"left" : "R",
"right" : "L"
},
"dotIndex" : 0,
"lookAheadSymbol" : "="
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние '*1' пункт '[L→•*R, ⊣]'.",
"state" : "*1",
"item" : {
"rule" : {
"left" : "L",
"right" : "*R"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние '*1' пункт '[L→•x, ⊣]'.",
"state" : "*1",
"item" : {
"rule" : {
"left" : "L",
"right" : "x"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние '*1' пункт '[L→•x, =]'.",
"state" : "*1",
"item" : {
"rule" : {
"left" : "L",
"right" : "x"
},
"dotIndex" : 0,
"lookAheadSymbol" : "="
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние '*1' пункт '[L→•*R, =]'.",
"state" : "*1",
"item" : {
"rule" : {
"left" : "L",
"right" : "*R"
},
"dotIndex" : 0,
"lookAheadSymbol" : "="
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем переход из состояния '∇' в состояние '*1' по символу '*'.",
"from" : "∇",
"to" : "*1",
"through" : "*",
"level" : "action",
"name" : "addTransition"
}, {
"message" : "Просматриваем состояние 'S1'",
"level" : "comment",
"name" : "startAddNewTransitions"
}, {
"message" : "Просматриваем состояние 'R1'",
"level" : "comment",
"name" : "startAddNewTransitions"
}, {
"message" : "Просматриваем состояние 'L1'",
"level" : "comment",
"name" : "startAddNewTransitions"
}, {
"message" : "Добавляем состояние '=1'.",
"stateName" : "=1",
"level" : "action",
"name" : "addState"
}, {
"message" : "Добавляем в состояние '=1' пункт '[S→L=•R, ⊣]'.",
"state" : "=1",
"item" : {
"rule" : {
"left" : "S",
"right" : "L=R"
},
"dotIndex" : 2,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние '=1' пункт '[R→•L, ⊣]'.",
"state" : "=1",
"item" : {
"rule" : {
"left" : "R",
"right" : "L"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние '=1' пункт '[L→•*R, ⊣]'.",
"state" : "=1",
"item" : {
"rule" : {
"left" : "L",
"right" : "*R"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние '=1' пункт '[L→•x, ⊣]'.",
"state" : "=1",
"item" : {
"rule" : {
"left" : "L",
"right" : "x"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем переход из состояния 'L1' в состояние '=1' по символу '='.",
"from" : "L1",
"to" : "=1",
"through" : "=",
"level" : "action",
"name" : "addTransition"
}, {
"message" : "Просматриваем состояние 'x1'",
"level" : "comment",
"name" : "startAddNewTransitions"
}, {
"message" : "Просматриваем состояние '*1'",
"level" : "comment",
"name" : "startAddNewTransitions"
}, {
"message" : "Добавляем состояние 'R2'.",
"stateName" : "R2",
"level" : "action",
"name" : "addState"
}, {
"message" : "Добавляем в состояние 'R2' пункт '[L→*R•, =]'.",
"state" : "R2",
"item" : {
"rule" : {
"left" : "L",
"right" : "*R"
},
"dotIndex" : 2,
"lookAheadSymbol" : "="
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние 'R2' пункт '[L→*R•, ⊣]'.",
"state" : "R2",
"item" : {
"rule" : {
"left" : "L",
"right" : "*R"
},
"dotIndex" : 2,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем переход из состояния '*1' в состояние 'R2' по символу 'R'.",
"from" : "*1",
"to" : "R2",
"through" : "R",
"level" : "action",
"name" : "addTransition"
}, {
"message" : "Добавляем состояние 'L2'.",
"stateName" : "L2",
"level" : "action",
"name" : "addState"
}, {
"message" : "Добавляем в состояние 'L2' пункт '[R→L•, ⊣]'.",
"state" : "L2",
"item" : {
"rule" : {
"left" : "R",
"right" : "L"
},
"dotIndex" : 1,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние 'L2' пункт '[R→L•, =]'.",
"state" : "L2",
"item" : {
"rule" : {
"left" : "R",
"right" : "L"
},
"dotIndex" : 1,
"lookAheadSymbol" : "="
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем переход из состояния '*1' в состояние 'L2' по символу 'L'.",
"from" : "*1",
"to" : "L2",
"through" : "L",
"level" : "action",
"name" : "addTransition"
}, {
"message" : "Добавляем переход из состояния '*1' в состояние '*1' по символу '*'.",
"from" : "*1",
"to" : "*1",
"through" : "*",
"level" : "action",
"name" : "addTransition"
}, {
"message" : "Добавляем переход из состояния '*1' в состояние 'x1' по символу 'x'.",
"from" : "*1",
"to" : "x1",
"through" : "x",
"level" : "action",
"name" : "addTransition"
}, {
"message" : "Просматриваем состояние '=1'",
"level" : "comment",
"name" : "startAddNewTransitions"
}, {
"message" : "Добавляем состояние 'R3'.",
"stateName" : "R3",
"level" : "action",
"name" : "addState"
}, {
"message" : "Добавляем в состояние 'R3' пункт '[S→L=R•, ⊣]'.",
"state" : "R3",
"item" : {
"rule" : {
"left" : "S",
"right" : "L=R"
},
"dotIndex" : 3,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем переход из состояния '=1' в состояние 'R3' по символу 'R'.",
"from" : "=1",
"to" : "R3",
"through" : "R",
"level" : "action",
"name" : "addTransition"
}, {
"message" : "Добавляем состояние 'L3'.",
"stateName" : "L3",
"level" : "action",
"name" : "addState"
}, {
"message" : "Добавляем в состояние 'L3' пункт '[R→L•, ⊣]'.",
"state" : "L3",
"item" : {
"rule" : {
"left" : "R",
"right" : "L"
},
"dotIndex" : 1,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем переход из состояния '=1' в состояние 'L3' по символу 'L'.",
"from" : "=1",
"to" : "L3",
"through" : "L",
"level" : "action",
"name" : "addTransition"
}, {
"message" : "Добавляем состояние '*2'.",
"stateName" : "*2",
"level" : "action",
"name" : "addState"
}, {
"message" : "Добавляем в состояние '*2' пункт '[L→*•R, ⊣]'.",
"state" : "*2",
"item" : {
"rule" : {
"left" : "L",
"right" : "*R"
},
"dotIndex" : 1,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние '*2' пункт '[R→•L, ⊣]'.",
"state" : "*2",
"item" : {
"rule" : {
"left" : "R",
"right" : "L"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние '*2' пункт '[L→•*R, ⊣]'.",
"state" : "*2",
"item" : {
"rule" : {
"left" : "L",
"right" : "*R"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние '*2' пункт '[L→•x, ⊣]'.",
"state" : "*2",
"item" : {
"rule" : {
"left" : "L",
"right" : "x"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем переход из состояния '=1' в состояние '*2' по символу '*'.",
"from" : "=1",
"to" : "*2",
"through" : "*",
"level" : "action",
"name" : "addTransition"
}, {
"message" : "Добавляем состояние 'x2'.",
"stateName" : "x2",
"level" : "action",
"name" : "addState"
}, {
"message" : "Добавляем в состояние 'x2' пункт '[L→x•, ⊣]'.",
"state" : "x2",
"item" : {
"rule" : {
"left" : "L",
"right" : "x"
},
"dotIndex" : 1,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем переход из состояния '=1' в состояние 'x2' по символу 'x'.",
"from" : "=1",
"to" : "x2",
"through" : "x",
"level" : "action",
"name" : "addTransition"
}, {
"message" : "Просматриваем состояние 'R2'",
"level" : "comment",
"name" : "startAddNewTransitions"
}, {
"message" : "Просматриваем состояние 'L2'",
"level" : "comment",
"name" : "startAddNewTransitions"
}, {
"message" : "Просматриваем состояние 'R3'",
"level" : "comment",
"name" : "startAddNewTransitions"
}, {
"message" : "Просматриваем состояние 'L3'",
"level" : "comment",
"name" : "startAddNewTransitions"
}, {
"message" : "Просматриваем состояние '*2'",
"level" : "comment",
"name" : "startAddNewTransitions"
}, {
"message" : "Добавляем состояние 'R4'.",
"stateName" : "R4",
"level" : "action",
"name" : "addState"
}, {
"message" : "Добавляем в состояние 'R4' пункт '[L→*R•, ⊣]'.",
"state" : "R4",
"item" : {
"rule" : {
"left" : "L",
"right" : "*R"
},
"dotIndex" : 2,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем переход из состояния '*2' в состояние 'R4' по символу 'R'.",
"from" : "*2",
"to" : "R4",
"through" : "R",
"level" : "action",
"name" : "addTransition"
}, {
"message" : "Добавляем переход из состояния '*2' в состояние 'L3' по символу 'L'.",
"from" : "*2",
"to" : "L3",
"through" : "L",
"level" : "action",
"name" : "addTransition"
}, {
"message" : "Добавляем переход из состояния '*2' в состояние '*2' по символу '*'.",
"from" : "*2",
"to" : "*2",
"through" : "*",
"level" : "action",
"name" : "addTransition"
}, {
"message" : "Добавляем переход из состояния '*2' в состояние 'x2' по символу 'x'.",
"from" : "*2",
"to" : "x2",
"through" : "x",
"level" : "action",
"name" : "addTransition"
}, {
"message" : "Просматриваем состояние 'x2'",
"level" : "comment",
"name" : "startAddNewTransitions"
}, {
"message" : "Просматриваем состояние 'R4'",
"level" : "comment",
"name" : "startAddNewTransitions"
}, {
"message" : "Уплотняем полученный LR-автомат",
"level" : "comment",
"name" : "compactLRAutomaton"
}, {
"message" : "Удаляем переход из состояния '∇' в состояние '*1' по символу '*'.",
"from" : "∇",
"to" : "*1",
"through" : "*",
"level" : "action",
"name" : "deleteTransition"
}, {
"message" : "Удаляем переход из состояния '*2' в состояние 'L3' по символу 'L'.",
"from" : "*2",
"to" : "L3",
"through" : "L",
"level" : "action",
"name" : "deleteTransition"
}, {
"message" : "Удаляем переход из состояния '*1' в состояние 'L2' по символу 'L'.",
"from" : "*1",
"to" : "L2",
"through" : "L",
"level" : "action",
"name" : "deleteTransition"
}, {
"message" : "Удаляем переход из состояния '*1' в состояние '*1' по символу '*'.",
"from" : "*1",
"to" : "*1",
"through" : "*",
"level" : "action",
"name" : "deleteTransition"
}, {
"message" : "Удаляем переход из состояния '*2' в состояние 'R4' по символу 'R'.",
"from" : "*2",
"to" : "R4",
"through" : "R",
"level" : "action",
"name" : "deleteTransition"
}, {
"message" : "Удаляем переход из состояния '*1' в состояние 'x1' по символу 'x'.",
"from" : "*1",
"to" : "x1",
"through" : "x",
"level" : "action",
"name" : "deleteTransition"
}, {
"message" : "Удаляем переход из состояния '*2' в состояние '*2' по символу '*'.",
"from" : "*2",
"to" : "*2",
"through" : "*",
"level" : "action",
"name" : "deleteTransition"
}, {
"message" : "Удаляем переход из состояния '*2' в состояние 'x2' по символу 'x'.",
"from" : "*2",
"to" : "x2",
"through" : "x",
"level" : "action",
"name" : "deleteTransition"
}, {
"message" : "Удаляем переход из состояния '*1' в состояние 'R2' по символу 'R'.",
"from" : "*1",
"to" : "R2",
"through" : "R",
"level" : "action",
"name" : "deleteTransition"
}, {
"message" : "Удаляем переход из состояния '∇' в состояние 'x1' по символу 'x'.",
"from" : "∇",
"to" : "x1",
"through" : "x",
"level" : "action",
"name" : "deleteTransition"
}, {
"message" : "Удаляем переход из состояния '=1' в состояние '*2' по символу '*'.",
"from" : "=1",
"to" : "*2",
"through" : "*",
"level" : "action",
"name" : "deleteTransition"
}, {
"message" : "Удаляем переход из состояния '=1' в состояние 'x2' по символу 'x'.",
"from" : "=1",
"to" : "x2",
"through" : "x",
"level" : "action",
"name" : "deleteTransition"
}, {
"message" : "Удаляем переход из состояния '=1' в состояние 'L3' по символу 'L'.",
"from" : "=1",
"to" : "L3",
"through" : "L",
"level" : "action",
"name" : "deleteTransition"
}, {
"message" : "Удаляем состояние 'R2'.",
"stateName" : "R2",
"level" : "action",
"name" : "deleteState"
}, {
"message" : "Удаляем состояние 'R4'.",
"stateName" : "R4",
"level" : "action",
"name" : "deleteState"
}, {
"message" : "Удаляем состояние 'L2'.",
"stateName" : "L2",
"level" : "action",
"name" : "deleteState"
}, {
"message" : "Удаляем состояние '*1'.",
"stateName" : "*1",
"level" : "action",
"name" : "deleteState"
}, {
"message" : "Удаляем состояние 'L3'.",
"stateName" : "L3",
"level" : "action",
"name" : "deleteState"
}, {
"message" : "Удаляем состояние '*2'.",
"stateName" : "*2",
"level" : "action",
"name" : "deleteState"
}, {
"message" : "Удаляем состояние 'x1'.",
"stateName" : "x1",
"level" : "action",
"name" : "deleteState"
}, {
"message" : "Удаляем состояние 'x2'.",
"stateName" : "x2",
"level" : "action",
"name" : "deleteState"
}, {
"message" : "Добавляем состояние 'R2;R4'.",
"stateName" : "R2;R4",
"level" : "action",
"name" : "addState"
}, {
"message" : "Добавляем в состояние 'R2;R4' пункт '[L→*R•, =]'.",
"state" : "R2;R4",
"item" : {
"rule" : {
"left" : "L",
"right" : "*R"
},
"dotIndex" : 2,
"lookAheadSymbol" : "="
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние 'R2;R4' пункт '[L→*R•, ⊣]'.",
"state" : "R2;R4",
"item" : {
"rule" : {
"left" : "L",
"right" : "*R"
},
"dotIndex" : 2,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем состояние 'L2;L3'.",
"stateName" : "L2;L3",
"level" : "action",
"name" : "addState"
}, {
"message" : "Добавляем в состояние 'L2;L3' пункт '[R→L•, ⊣]'.",
"state" : "L2;L3",
"item" : {
"rule" : {
"left" : "R",
"right" : "L"
},
"dotIndex" : 1,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние 'L2;L3' пункт '[R→L•, =]'.",
"state" : "L2;L3",
"item" : {
"rule" : {
"left" : "R",
"right" : "L"
},
"dotIndex" : 1,
"lookAheadSymbol" : "="
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем состояние '*1;*2'.",
"stateName" : "*1;*2",
"level" : "action",
"name" : "addState"
}, {
"message" : "Добавляем в состояние '*1;*2' пункт '[L→*•R, ⊣]'.",
"state" : "*1;*2",
"item" : {
"rule" : {
"left" : "L",
"right" : "*R"
},
"dotIndex" : 1,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние '*1;*2' пункт '[L→*•R, =]'.",
"state" : "*1;*2",
"item" : {
"rule" : {
"left" : "L",
"right" : "*R"
},
"dotIndex" : 1,
"lookAheadSymbol" : "="
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние '*1;*2' пункт '[R→•L, ⊣]'.",
"state" : "*1;*2",
"item" : {
"rule" : {
"left" : "R",
"right" : "L"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние '*1;*2' пункт '[R→•L, =]'.",
"state" : "*1;*2",
"item" : {
"rule" : {
"left" : "R",
"right" : "L"
},
"dotIndex" : 0,
"lookAheadSymbol" : "="
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние '*1;*2' пункт '[L→•*R, ⊣]'.",
"state" : "*1;*2",
"item" : {
"rule" : {
"left" : "L",
"right" : "*R"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние '*1;*2' пункт '[L→•x, ⊣]'.",
"state" : "*1;*2",
"item" : {
"rule" : {
"left" : "L",
"right" : "x"
},
"dotIndex" : 0,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние '*1;*2' пункт '[L→•x, =]'.",
"state" : "*1;*2",
"item" : {
"rule" : {
"left" : "L",
"right" : "x"
},
"dotIndex" : 0,
"lookAheadSymbol" : "="
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние '*1;*2' пункт '[L→•*R, =]'.",
"state" : "*1;*2",
"item" : {
"rule" : {
"left" : "L",
"right" : "*R"
},
"dotIndex" : 0,
"lookAheadSymbol" : "="
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем состояние 'x1;x2'.",
"stateName" : "x1;x2",
"level" : "action",
"name" : "addState"
}, {
"message" : "Добавляем в состояние 'x1;x2' пункт '[L→x•, ⊣]'.",
"state" : "x1;x2",
"item" : {
"rule" : {
"left" : "L",
"right" : "x"
},
"dotIndex" : 1,
"lookAheadSymbol" : "⊣"
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем в состояние 'x1;x2' пункт '[L→x•, =]'.",
"state" : "x1;x2",
"item" : {
"rule" : {
"left" : "L",
"right" : "x"
},
"dotIndex" : 1,
"lookAheadSymbol" : "="
},
"level" : "action",
"name" : "addItem"
}, {
"message" : "Добавляем переход из состояния '=1' в состояние 'L2;L3' по символу 'L'.",
"from" : "=1",
"to" : "L2;L3",
"through" : "L",
"level" : "action",
"name" : "addTransition"
}, {
"message" : "Добавляем переход из состояния '*1;*2' в состояние 'L2;L3' по символу 'L'.",
"from" : "*1;*2",
"to" : "L2;L3",
"through" : "L",
"level" : "action",
"name" : "addTransition"
}, {
"message" : "Добавляем переход из состояния '*1;*2' в состояние 'R2;R4' по символу 'R'.",
"from" : "*1;*2",
"to" : "R2;R4",
"through" : "R",
"level" : "action",
"name" : "addTransition"
}, {
"message" : "Добавляем переход из состояния '=1' в состояние 'x1;x2' по символу 'x'.",
"from" : "=1",
"to" : "x1;x2",
"through" : "x",
"level" : "action",
"name" : "addTransition"
}, {
"message" : "Добавляем переход из состояния '*1;*2' в состояние 'x1;x2' по символу 'x'.",
"from" : "*1;*2",
"to" : "x1;x2",
"through" : "x",
"level" : "action",
"name" : "addTransition"
}, {
"message" : "Добавляем переход из состояния '∇' в состояние 'x1;x2' по символу 'x'.",
"from" : "∇",
"to" : "x1;x2",
"through" : "x",
"level" : "action",
"name" : "addTransition"
}, {
"message" : "Добавляем переход из состояния '∇' в состояние '*1;*2' по символу '*'.",
"from" : "∇",
"to" : "*1;*2",
"through" : "*",
"level" : "action",
"name" : "addTransition"
}, {
"message" : "Добавляем переход из состояния '*1;*2' в состояние '*1;*2' по символу '*'.",
"from" : "*1;*2",
"to" : "*1;*2",
"through" : "*",
"level" : "action",
"name" : "addTransition"
}, {
"message" : "Добавляем переход из состояния '=1' в состояние '*1;*2' по символу '*'.",
"from" : "=1",
"to" : "*1;*2",
"through" : "*",
"level" : "action",
"name" : "addTransition"
} ]
}
}
POST api/{v1+}/build/lr1 (png)
Строит LR(1)-автомат. Результат возвращает в формате png.
Заголовки запроса
| Имя | Описание |
|---|---|
Content-Type |
image/png |
Параметры пути
| Имя | Описание |
|---|---|
version |
версия API |
Тело запроса
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
.grammar |
Object |
Да |
Грамматика, по которой требуется построить LR-автомат |
.grammar.terminals |
Array |
Да |
Список терминалов грамматики. |
.grammar.nonTerminals |
Array |
Да |
Список нетерминалов грамматики |
.grammar.rules |
Array |
Да |
Список правил грамматики |
.grammar.rules[].left |
String |
Да |
Нетерминал левой части правила грамматики |
.grammar.rules[].right |
String |
Да |
Символы правой части правила грамматики |
.grammar.startSymbol |
String |
Да |
Аксиома грамматики (нетерминал) |
.buildOptions |
Object |
Нет |
Параметры построения LR-автомата |
.buildOptions.namesGenerationStrategy |
String |
Нет |
Стратегия генерации имен состояний при построении автомата |
visualizeOperations.colorizeTransitions |
Boolean |
Нет |
Нужно ли окрашивать переходы автомата. По умолчанию не окрашиваются. |
visualizeOperations.colorizeStateNames |
Boolean |
Нет |
Окрашивать ли имена состояний. По умолчанию не окрашиваются. |
visualizeOperations.stateNameStyle |
String |
Нет |
Стиль оформления названия состояния. По умолчанию 'onBlackBackground'. |
Заголовки ответа
| Имя | Описание |
|---|---|
Content-Type |
application/json |
curl
$ curl 'http://localhost:8080/api/v1/build/lr1' -i -X POST \
-H 'Content-Type: application/json' \
-H 'Accept: image/png' \
-d '{
"grammar" : {
"terminals" : [ "i", "+", "(", ")" ],
"nonTerminals" : [ "E", "T" ],
"rules" : [ {
"left" : "E",
"right" : "T"
}, {
"left" : "E",
"right" : "E+T"
}, {
"left" : "T",
"right" : "i"
}, {
"left" : "T",
"right" : "(E)"
} ],
"startSymbol" : "E"
}
}'
Пример запроса
POST /api/v1/build/lr1 HTTP/1.1
Content-Type: application/json
Accept: image/png
Content-Length: 342
Host: localhost:8080
{
"grammar" : {
"terminals" : [ "i", "+", "(", ")" ],
"nonTerminals" : [ "E", "T" ],
"rules" : [ {
"left" : "E",
"right" : "T"
}, {
"left" : "E",
"right" : "E+T"
}, {
"left" : "T",
"right" : "i"
}, {
"left" : "T",
"right" : "(E)"
} ],
"startSymbol" : "E"
}
}
Пример ответа
POST api/{v1+}/build/lr1 (zip)
Строит LR(1)-автомат. Лог построения возвращает в zip архиве с изображениями автомата.
Заголовки запроса
| Имя | Описание |
|---|---|
Accept |
application/octet-stream |
Параметры пути
| Имя | Описание |
|---|---|
version |
версия API |
Тело запроса
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
.grammar |
Object |
Да |
Грамматика, по которой требуется построить LR-автомат |
.grammar.terminals |
Array |
Да |
Список терминалов грамматики. |
.grammar.nonTerminals |
Array |
Да |
Список нетерминалов грамматики |
.grammar.rules |
Array |
Да |
Список правил грамматики |
.grammar.rules[].left |
String |
Да |
Нетерминал левой части правила грамматики |
.grammar.rules[].right |
String |
Да |
Символы правой части правила грамматики |
.grammar.startSymbol |
String |
Да |
Аксиома грамматики (нетерминал) |
.buildOptions |
Object |
Нет |
Параметры построения LR-автомата |
.buildOptions.namesGenerationStrategy |
String |
Нет |
Стратегия генерации имен состояний при построении автомата |
visualizeOperations.visualizeOperations |
Array |
Нет |
Номера операций, которые нужно визуализировать. Если не указаны, то визуализируются все операции |
visualizeOperations.colorizeTransitions |
Boolean |
Нет |
Нужно ли окрашивать переходы автомата. По умолчанию не окрашиваются. |
visualizeOperations.colorizeStateNames |
Boolean |
Нет |
Окрашивать ли имена состояний. По умолчанию не окрашиваются. |
visualizeOperations.stateNameStyle |
String |
Нет |
Стиль оформления названия состояния. По умолчанию 'onBlackBackground'. |
Заголовки ответа
| Имя | Описание |
|---|---|
Content-Type |
application/octet-stream (zip) |
curl
$ curl 'http://localhost:8080/api/v1/build/lr1' -i -X POST \
-H 'Content-Type: application/json' \
-H 'Accept: application/octet-stream' \
-d '{
"grammar" : {
"terminals" : [ "i", "+", "(", ")" ],
"nonTerminals" : [ "E", "T" ],
"rules" : [ {
"left" : "E",
"right" : "T"
}, {
"left" : "E",
"right" : "E+T"
}, {
"left" : "T",
"right" : "i"
}, {
"left" : "T",
"right" : "(E)"
} ],
"startSymbol" : "E"
}
}'
Пример запроса
POST /api/v1/build/lr1 HTTP/1.1
Content-Type: application/json
Accept: application/octet-stream
Content-Length: 342
Host: localhost:8080
{
"grammar" : {
"terminals" : [ "i", "+", "(", ")" ],
"nonTerminals" : [ "E", "T" ],
"rules" : [ {
"left" : "E",
"right" : "T"
}, {
"left" : "E",
"right" : "E+T"
}, {
"left" : "T",
"right" : "i"
}, {
"left" : "T",
"right" : "(E)"
} ],
"startSymbol" : "E"
}
}
POST api/{v1+}/grammar/first
Строит множества FIRST для каждого символа грамматики.
Заголовки запроса
| Имя | Описание |
|---|---|
Accept |
application/json |
Параметры пути
| Имя | Описание |
|---|---|
version |
версия API |
Тело запроса
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
.terminals |
Array |
Да |
Список терминалов грамматики. |
.nonTerminals |
Array |
Да |
Список нетерминалов грамматики |
.rules |
Array |
Да |
Список правил грамматики |
.rules[].left |
String |
Да |
Нетерминал левой части правила грамматики |
.rules[].right |
String |
Да |
Символы правой части правила грамматики |
.startSymbol |
String |
Да |
Аксиома грамматики (нетерминал) |
Заголовки ответа
| Имя | Описание |
|---|---|
Content-Type |
application/json |
Тело ответа
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
* |
Array |
Да |
Символы грамматики |
*.[] |
Array |
Да |
Множество FIRST для соответствующего символа грамматики |
curl
$ curl 'http://localhost:8080/api/v1/grammar/first' -i -X POST \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d '{
"terminals" : [ "a", "b" ],
"nonTerminals" : [ "S", "A" ],
"rules" : [ {
"left" : "S",
"right" : "AA"
}, {
"left" : "A",
"right" : "aA"
}, {
"left" : "A",
"right" : "b"
} ],
"startSymbol" : "S"
}'
Примеры
Пример запроса
POST /api/v1/grammar/first HTTP/1.1
Content-Type: application/json
Accept: application/json
Content-Length: 235
Host: localhost:8080
{
"terminals" : [ "a", "b" ],
"nonTerminals" : [ "S", "A" ],
"rules" : [ {
"left" : "S",
"right" : "AA"
}, {
"left" : "A",
"right" : "aA"
}, {
"left" : "A",
"right" : "b"
} ],
"startSymbol" : "S"
}
Пример ответа
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 46
{
"A" : [ "a", "b" ],
"S" : [ "a", "b" ]
}
Грамматика
Грамматика передаётся в теле запроса при вызове методов построения LR-автоматов (POST api/{v1+}/build/lr0 (json), POST api/{v1+}/build/lalr1 (json), POST api/{v1+}/build/lr1 (json)).
Грамматика задаётся четвёркой:
-
список терминалов (terminals)
-
список нетерминалов (nonTerminals)
-
список правил (rules)
-
аксиома (startSymbol)
Терминалы
Терминалы передаются в поле terminals.
Это список символов, каждый из которых:
-
представляет собой строку длины 1
-
не должен совпадать ни с одним нетерминалом
-
не должен совпадать с прочими терминалами
Нетерминалы
Нетерминалы передаются в поле nonTerminals.
Это список символов, каждый из которых:
-
представляет собой строку длины 1
-
не должен совпадать ни с одним терминалом
-
не должен совпадать с прочими нетерминалами
Правила
Правила передаются в поле rules.
Каждое правило состоит из двух частей:
-
left - нетерминал левой части (должен содержаться в списке нетерминалов)
-
right - строка, задающая правую часть правила
Правая часть правила представляет собой последовательность символов, где каждый символ должен находится в объединении списков терминалов и нетерминалов.
Если right - пустая строка, правило считается ε-правилом.
Аксиома
Аксиома передаётся в поле startSymbol.
Это нетерминал из списка нетерминалов, с которого начинается вывод.
Аксиома должна принадлежать множеству нетерминалов
LR-автомат
LR-автомат возвращается в поле automaton при вызове методов построения:
LR-автомат состоит из:
Состояния
Состояния передаются в поле states
Каждое состояние содержит:
-
name - уникальное имя состояния
-
items - список LR-пунктов, принадлежащих состоянию
LR-пункты
Каждый элемент списка items представляет собой LR-пункт.
LR-пункт состоит из:
-
rule - правила грамматики
-
dotIndex - позиции точки в правой части правила
Поле dotIndex определяет положение точки в правой части правила:
-
0- точка стоит перед первым символом правой части правила -
length(right)- точка стоит в конце правой части правила правила -
0< dotIndex <length(right)- точка стоит в середине правой части правила на соответствующей позиции
Если правая часть правила пустая (ε-правило), допустимое значение dotIndex равно 0.
Состав LR-пунктов зависит от типа строящегося автомата:
-
для LR(0) и LALR(1) используются LR(0)-пункт
-
для LR(1) используются LR(1)-пункты
В случае использования LR(1)-пунктов, добавляется поле lookAheadSymbol - символ предпросмотра.
Значением поля является символ из списка рассматриваемых терминалов или же символ завершения строки ⊣.
Переходы
Переходы передаются в поле transitions.
Каждый переход содержит:
-
from - имя состояния, из которого осуществляется переход (
Исходное состояние) -
to - имя состояния, в которое осуществляется переход (
Целевое состояние) -
through - символ перехода
Символ through принадлежит объединению списков терминалов и нетерминалов исходной грамматики.
| LR-автомат полностью восстанавливается последовательным применением операций из лога построения. |
Лог построения LR-автоматов
Вместе с LR-автоматом (POST api/{v1+}/build/lr0 (json), POST api/{v1+}/build/lalr1 (json), POST api/{v1+}/build/lr1 (json)) в ответе возвращается лог построения автомата.
Лог представляет из себя массив операций, которые нужно произвести, чтобы построить требуемый автомат.
У каждой операции есть имя (name) и пояснительное сообщение (message).
Уровни операций
Операции различаются по уровню важности (level). Существует 2 уровня операций:
-
action
-
comment
action
Операция уровня action - ключевая операция, которую необходимо выполнить для построения автомата. Без её выполнения автомат будет построен некорректно или его дальнейшее построение окажется вовсе невозможным.
Таких операций всего 6. Вот их имена:
-
addState
-
deleteState
-
addItem
-
addTransition
-
deleteTransition
-
addLookAheadSymbol
Операции уровня action также имеют дополнительные поля (помимо name, level, message), которые описаны ниже.
comment
Операция уровня comment - вспомогательная, опциональная операция, помогающая восстановить рассуждения, которые производились, чтобы выполнить очередную операцию уровня action.
Поддерживаемые action операции
addState
Каждое состояние в автомате имеет уникальное имя.
Операция addState добавляет новое состояние c указанным именем в строящийся LR-автомат. В поле stateName операциии addState находится имя добавляемого состояния.
deleteState
Операция deleteState удаляет состояние c указанным именем в строящемся LR-автомате. В поле stateName операциии deleteState находится имя удаляемого состояния.
addItem
Операция addItem добавляет LR-пункт в одно из состояний строящегося автомата.
В поле state находится имя состояния строящегося автомата, в которое добавляется LR-пункт
В поле item находится добавляемый в это состояние LR-пункт
addTransition
Операция addTransition добавляет переход из одного состояние строящегося LR-автомата в другое.
-
В поле from находится имя состояния LR-автомата из которого осуществляется переход
-
В поле to находится имя состояния LR-автомата в которое осуществляется переход
-
В поле through находится символ грамматики через который осуществляется переход
deleteTransition
Операция deleteTransition удаляет переход из одного состояние строящегося LR-автомата в другое.
-
В поле from находится имя состояния LR-автомата из которого осуществляется переход
-
В поле to находится имя состояния LR-автомата в которое осуществляется переход
-
В поле through находится символ грамматики через который осуществляется переход
addLookAheadSymbol
Операция addLookAheadSymbol добавляет символ предпросмотра lookAheadSymbol к LR-пункту item в состоянии с именем stateName.
Пункт item, в который добавляется символ, описывается в секции.
Поддерживемые comment операции
-
buildLrAutomaton - начало построения LR-автомата.
-
extendGrammar - расширение исходной грамматики (добавление нового стартового правила).
-
startAddNewTransitions - начало обработки очередного состояния автомата - просмотр LR-пунктов состояния и поиск возможных переходов
-
compactLRAutomaton - при построении LALR(1)-автоматов классическим алгоритмом. Начало ужатия LR(1)-автомата до LALR(1) автомата путем объединения состояний с одинаковыми множествами ядер.
Параметры построения автомата
В запросах на построение LR-автоматов можно передать параметры, которые будут учитываться при построении
namesGenerationStrategy
Задает стратегию генерации имен состояния строящегося LR-автомата. Поддерживаются 2 стратегии:
byTransitionSymbol - по символу перехода.
Стартовому состоянию дается имя ∇.
Имя очередного состояния, добавляемого в процессе построения формируются в формате:
TRANSITION_SYMBOL + NUMBER
где:
-
TRANSITION_SYMBOL - лексическое значение символа, по которому осуществляется переход в новое состояние
-
NUMBER - порядковый номер состояния, присваиваемый автоматически при его добавлении в автомат. Нумерация начинается с 1 для первого добавленного состояния и увеличивается на 1 для каждого нового состояния.
| используется по умолчанию |
endToEndNumeric - сквозная нумерация состояний.
Стартовому состоянию дается имя 0.
Каждое последующее добавляемое в автомат состояние получает имя в виде следующего целого числа (1, 2, 3, …).
lalr1BuildAlgorithm
Задает алгоритм, с применением которого будет строиться LALR(1)-автомат.
Поддерживается 2 алгоритма:
classic - классический алгоритм построения LALR(1)-автомата.
Сперва строится LR(1)-автомат. После чего состояния с одинаковыми множествами ядер объединяются.
| используется по умолчанию |
channel - канальный алгоритм.
Эффективный алгоритм построения LALR(1)-автомата с применением механизмов спонтанной генерации символов предпросмотра на пунктах ядер lr(0)-автомата и их последующего распространения на другие пункты до тех пор, пока процесс не стабилизируется.
enableBuildLog
Передавать ли в ответе лог построения автомата.
По умолчанию false.
Параметры визуализации автомата
В запросах на построение LR-автоматов можно передать параметры, которые будут учитываться при его визуализации.
visualizeOperations
Массив номеров операций лога построения, которые нужно визуализировать. Операции нумеруются с 0.
colorizeTransitions
Окрашивать ли переходы автомата в разные цвета. С каждым символом перехода связан свой цвет.
| Поддерживается 20 цветов. После исчерпания палитры цвета начинают повторяться. |
colorizeStateNames
Окрашивать ли имена состояний в цвет перехода, по которому это состояние было впервые добавлено в автомат.
| Применяется только с включенным параметром colorizeTransitions |
| Не поддерживается методами POST api/{v1+}/build/lalr1 (png), POST api/{v1+}/build/lalr1 (zip) при использовании алгоритма classic. |
stateNameStyle
Стиль оформления названия состояния.
Поддерживается 2 стиля:
onBlackBackground - название состояния на чёрном фоне.
| используется по умолчанию |
boldOnWhiteBackground - название состояния жирным шрифтом на белом фоне.