Skip to content

Commit

Permalink
Конюнктивные грамматики
Browse files Browse the repository at this point in the history
  • Loading branch information
Encapsulateed committed Jan 21, 2024
1 parent 0ad911b commit 3c78133
Show file tree
Hide file tree
Showing 7 changed files with 127 additions and 216 deletions.
4 changes: 2 additions & 2 deletions lab5/.dart_tool/package_config.json
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@
"languageVersion": "3.1"
}
],
"generated": "2024-01-13T23:11:37.399658Z",
"generated": "2024-01-21T13:28:36.891219Z",
"generator": "pub",
"generatorVersion": "3.1.2"
"generatorVersion": "3.1.0"
}
4 changes: 2 additions & 2 deletions lab5/input.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
S->AA
A->aA
A->b
A->a&b
A->a
115 changes: 6 additions & 109 deletions lab5/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,121 +6,18 @@ import 'src/lr0/LR0Table.dart';
import 'src/lr0/lr0Parser.dart';
import 'src/state_machine/FSM.dart';
import 'src/utils/Production.dart';
import 'src/utils/conjunctiveGrammar.dart';
import 'src/utils/stack.dart';
// import 'src/lr0/base/LR0Fms.dart';

void main(List<String> arguments) {
List<Grammar> grammars = [];
var g = Grammar.fromFile('input.txt');
LR0FMS f = LR0FMS(g);
f.DumpToDOT();
/*
if (arguments[1] == 'd') {
print("Searching for Conjunctive grammar");

var rules_lst = [];
for (var rule in g.rules) {
if (rule.right.contains('&')) {
var curr_left = rule.left;
var rule_parts = rule.right.join('').toString().split('&');
for (var part in rule_parts) {
Production N = Production(curr_left, part.split(''));
List<Production> curr_rules_copy = [...rules_lst];
curr_rules_copy.add(N);
grammars
.add(Grammar.make(curr_rules_copy, g.nonTerminals, g.terminals));
}
continue;
}
rules_lst.add(rule);
var cg = conjunctiveGrammar.fromFile('input.txt');

for (var gg in grammars) {
gg.rules.add(rule);
}
}
String word = arguments[0];
List<bool> total = [];
print("Total amount of grammars after separating the rules: ${grammars.length}\n");
for (var gg in grammars) {
LR0Parser pp = LR0Parser(gg);
total.add(pp.Parse(word));
print("${gg.rules}\n");
}
bool answer = true;
for (var ans in total) {
if (ans == false) {
answer = false;
break;
}
}
print("\nResult: ");
print(answer);
} else {
var g = Grammar.fromFile('input.txt');
Stack<String> inputStack = Stack();
Stack<String> tokenStack = Stack();
Stack<String> actionStack = Stack();
LR0Parser p = LR0Parser(g);
tokenStack.push('0');
inputStack.push('\$');
p.stack_screens.add(tokenStack.copyStack());
String word = arguments[0];
for (int i = word.length - 1; i >= 0; i--) {
inputStack.push(word[i]);
}
List<Stack<String>> stacks = [];
List<Stack<String>> action_stacks = [];
p.parseLR0_params(tokenStack, actionStack, inputStack, stacks, action_stacks);
print(getStrFromStack(action_stacks[0], reverse: false));
GSStack<String> stack = GSStackImpl();
Map<int, GSSNode<String>> Nodes = {};
int id = 0;
for (var stackScreen in p.stack_screens) {
for (var s in stackScreen.toList().toList()) {
Nodes[id] = stack.push(s, Nodes[id - 1]);
id++;
}
}
id = 0;
GSStack<String> stack1 = GSStackImpl();
Map<int, GSSNode<String>> Nodes1 = {};
for (var stackScreen in action_stacks) {
for (var s in stackScreen.toList().toList()) {
Nodes1[id] = stack1.push(s, Nodes1[id - 1]);
id++;
}
}
id = 0;
GSStack<String> stack2 = GSStackImpl();
Map<int, GSSNode<String>> Nodes2 = {};
for (var stackScreen in stacks) {
for (var s in stackScreen.toList().toList()) {
Nodes2[id] = stack2.push(s, Nodes2[id - 1]);
id++;
}
}
//print(getStrFromStack(stacks[0], reverse: false));
if (arguments.length == 3) {
int n = int.parse(arguments[2]);
print('STACK AT STEP ${n}\n=========================');
print(getStrFromStack(p.stack_screens[n]));
print('=========================');
*/
for(var grammar in cg.possible_grammars){
print(grammar);
}

}

// stack.GSStoDot('merged');
// stack1.GSStoDot('actions');
// stack2.GSStoDot('final');
83 changes: 4 additions & 79 deletions lab5/src/lr0/LR0Fms.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,60 +8,7 @@ class LR0FMS extends FSM {
Map<String, State> statyByLR0 = {};
Grammar _grammar = Grammar();

LR0FMS.nka(Grammar grammar) {
Map<Production, List<LR0Situation>> states = {};
_grammar = grammar;
// тут делаем closure для всей грамматики
for (var rule in grammar.rules) {
List<LR0Situation> rule_possible_situation = [];
for (int LR0_pointer = 0;
LR0_pointer <= rule.right.length;
LR0_pointer++) {
var situation = LR0Situation(rule.left, rule.right, LR0_pointer);
rule_possible_situation.add(situation);
}

states[rule] = rule_possible_situation;
}
var first_state = states[grammar.rules.toList()[0]]!.toList()[0];
super.startStates.add(State.valued(first_state.toString(), first_state));

// тут строим реальные переходы в автомате
for (var rule in grammar.rules) {
var first = states[rule]!.toList()[0];

for (var lr0_situations in states[rule]!.toList()) {
if (lr0_situations.isFinal()) {
super
.finalStates
.add(State.valued(lr0_situations.toString(), lr0_situations));
}
var next = lr0_situations;

//
super
.states
.add(State.valued(lr0_situations.toString(), lr0_situations));

// Нужно добавить переход в автомате
if (first != next) {
var transaction = Transaction()
..from = super.getState(first.toString())
..to = super.getState(next.toString())
..letter = first.next;
super.transactions.add(transaction);
}
first = next;
}
}

// тут строим эпсилон переходы в автомате

for (var state in super.states.toList()) {
make_epsilon_goto(state);
}
}


LR0FMS(Grammar CompleteGrammar) {
this._grammar = CompleteGrammar;
super.alphabet.addAll(_grammar.nonTerminals);
Expand All @@ -88,9 +35,7 @@ class LR0FMS extends FSM {
return production_possible_LR0_situations;
}

List<LR0Situation> closure2(List<LR0Situation> productions) {
return [];
}


void buildDFA() {
// Начальное состояние соответвует G+ - пополненной грамматике
Expand Down Expand Up @@ -133,7 +78,7 @@ class LR0FMS extends FSM {
if (beta == "eps") {
continue;
}
print(newl);

newl.move();

var X = newl.getNext();
Expand Down Expand Up @@ -235,25 +180,5 @@ class LR0FMS extends FSM {
}
}

void make_epsilon_goto(State input_state) {
LR0Situation stateLR = input_state.value;

// если точка стоит перед нетерминалом N, у нас есть эпсилон переходы
// в те состояния Слева, которых стоит этот N & точка LR0 ситуации стоит на 0 позиции
if (_grammar.nonTerminals.contains(stateLR.next)) {
var N = stateLR.next;
for (var state in super.states.toList()) {
if ((state.value as LR0Situation).left == N &&
(state.value as LR0Situation).LR0_pointer == 0) {
var transaction = Transaction()
..from =
super.getState((input_state.value as LR0Situation).toString())
..to = super.getState((state.value as LR0Situation).toString())
..letter = 'ε';

super.transactions.add(transaction);
}
}
}
}

}
76 changes: 76 additions & 0 deletions lab5/src/utils/conjunctiveGrammar.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import 'Production.dart';
import 'conjunctiveProduction.dart';
import 'grammar.dart';
import 'dart:io';

class conjunctiveGrammar {
List<Grammar> possible_grammars = [];
List<conjunctiveProdutcion> rules = [];

conjunctiveGrammar.fromFile(String filePath) {
_readGrammarFromFile(filePath);
_makeCFGs();
}
void _readGrammarFromFile(String filePath) {
var lines = File(filePath).readAsStringSync().split('\n');

for (var line in lines) {
if (line.trim().isNotEmpty) {
List<String> parts =
line.split('->').map((part) => part.trim()).toList();

var left = parts[0];
var right = parts[1].split('&').toList();
rules.add(conjunctiveProdutcion(
left, (right.map((e) => e.split('')).toList())));
}
}
}

void PrintCG() {
rules.forEach((element) {
print(element.toString());
});
}

void _makeCFGs() {
var permutations = _allPermutations();

num rules_count = rules.length;

for (int i = 0; i < permutations.length; i++) {
var p = permutations[i];
List<Production> prod = [];
for (int j = 0; j < rules_count; j++) {
var classicProduction = Production(rules[j].left, p[j].split(''));

prod.add(classicProduction);
}
possible_grammars.add(Grammar.fromProductionList(prod));
}
}

List<List<String>> _generatePermutations(
List<List<String>> lists, int index, List<String> current) {
if (index == lists.length) {
return [List<String>.from(current)];
}

List<List<String>> permutations = [];
for (String item in lists[index]) {
current.add(item);
permutations.addAll(_generatePermutations(lists, index + 1, current));
current.removeLast();
}

return permutations;
}

List<List<String>> _allPermutations() {
List<List<String>> possibleRightList = this
.rules
.map((rule) => rule.possible_right.map((lst) => lst.join()).toList())
.toList();
return _generatePermutations(possibleRightList, 0, []);
}
}
13 changes: 13 additions & 0 deletions lab5/src/utils/conjunctiveProduction.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
class conjunctiveProdutcion {
String left;
List<List<String>> possible_right;

conjunctiveProdutcion(this.left, this.possible_right);

@override
String toString() {
return '$left -> ${possible_right}';
}


}
Loading

0 comments on commit 3c78133

Please sign in to comment.