Перевод с паскаля на с# - C# (212238)
Формулировка задачи:
Очень нужна помощь, помогите перевести следующий кусок кода. Не понимаю, я как написать это шарпе. Пожалуйста!!Очень прошу.
PTree = ^TTree;
TTree = record
Str : string;
Len : integer;
Rul : string;
number : byte;
next : array of PTree;
end;
PTRule = ^TRule;
TRule = record
rule : String;
next : PTRule;
number : byte;
end;
PRule = record
Ch : char;
Len : integer;
P : PTRule;
end;
TAutomat = record
Cons : char;
ind : integer;
chain : string;
stack : array[0..1000] of integer;
el : integer;
end;Решение задачи: «Перевод с паскаля на с#»
textual
Листинг программы
PTree = ^TTree;
TTree = record
Str : string;
Len : integer;
Rul : string;
number : byte;
next : array of PTree;
end;
PTRule = ^TRule;
TRule = record
rule : String;
next : PTRule;
number : byte;
end;
PRule = record
Ch : char;
Len : integer;
P : PTRule;
end;
TAutomat = record
Cons : char;
ind : integer;
chain : string;
stack : array[0..1000] of integer;
el : integer;
end;
var
Form1 : TForm1;
index : array of PRule;
head : PTree;
Tree : string;
find : boolean;
GetIn : integer;
Chain : string;
count : integer;
raspoz : TAutomat;
RulChain : string;
Consists : string;
st1 : string;
implementation
uses Unit2, Unit3, Unit4;
{$R *.dfm}
//определяет является ли ch терминальным символом
function term(ch : char): boolean;
var
i : integer;
begin
term:= true;
for i:= 0 to Length(index)-1 do
if ch = index[i].Ch then
begin
term:= false;
GetIn:= i;
break;
end;
end;
// опрделяет кол-во терминальных символов в строке
function Len(st : string): integer;
var
i : integer;
t : integer;
begin
t:= 0;
for i:= 1 to Length(st) do
if term(st[i]) then inc(t);
len:= t;
end;
//построение цепочек при Генерации
function Rec(st : string; pp : PTree; CouL : integer; rul : string): PTree;
var
i : integer;
j : integer;
S1 : string;
S2 : string;
find : boolean;
p : PTRule;
begin
rec:= nil;
i:= Len(st);
if i > StrToInt(Form1.Edit4.Text) then Exit;
if Length(st) - i > StrToInt(Form1.Edit4.Text) then Exit;
if CouL > round(StrToInt(Form1.Edit4.Text)) then Exit;
find:= false;
for i:= 1 to Length(st) do
begin
if pp = nil then
begin
new(pp);
pp.Str:= St;
pp.Rul:= rul;
pp.Len:= 0;
rec:= pp;
end;
if not(term(st[i])) then
begin
find:= true;
S1:= Copy(st, 1, i-1);
S2:=Copy(st, i+1, Length(st));
p:= index[GetIn].P;
pp.Len:= index[GetIn].Len;
SetLength(pp.next, pp.Len);
for j:= 0 to index[GetIn].Len-1 do
begin
if p.rule = '' then inc(Coul);
pp.next[j]:= rec(S1+p.rule+S2, pp.next[j], CouL, St[i]+'->'+p.rule);
p:= p.next;
end;
break;
end;
end;
if (not(find)) and (Length(st) >= StrToInt(Form1.Edit3.Text)) then Form1.ListBox1.Items.Add(st);
end;
//считывание и объединение правил в единую структуру (список)
procedure TForm1.Button1Click(Sender: TObject);
var
i : integer;
j : integer;
p : PTRule;
q : PTRule;
begin
//-------------------------------------------------------------------------
head:= nil;
count:= 1;
p:= nil;
Form1.ListBox1.Items.Clear;
if Edit1.Text = '' then
begin
ShowMessage('Не указан алфавит терминальных символов!!!');
Exit;
end;
if Edit2.Text = '' then
begin
ShowMessage('Не указан алфавит нетерминальных символов!!!');
Exit;
end;
if Edit3.Text = '' then
begin
ShowMessage('НЕ указана минимальная длинна ципочки!!!');
Exit;
end;
if Edit4.Text = '' then
begin
ShowMessage('НЕ указана максимальная длинна ципочки!!!');
Exit;
end;
if (Memo1.Lines.Count = 0) or (Memo2.Lines.Count = 0) then
begin
ShowMessage('Отсутствуют правила вывода!');
Exit;
end;
if Memo1.Lines.Count <> Memo2.Lines.Count then
begin
ShowMessage('Ошибка в правилах вывода!');
Exit;
end;
if Edit1.Text = '' then
begin
ShowMessage('Отсутствует алфавит терминальных символов!');
Exit;
end;
if Edit2.Text = '' then
begin
ShowMessage('Отсутствует алфавит нетерминальных символов!');
Exit;
end;
for i:= 0 to Memo1.Lines.Count-1 do
if Length(Memo1.Lines.Strings[i]) > 1 then
begin
ShowMessage('Ошибка в правилах вывода! В левой части выражения указан неизвестный символ!');
Exit;
end;
for i:= 0 to Memo2.Lines.Count-1 do
if (Memo2.Lines.Strings[i][1] = '') or (Memo2.Lines.Strings[i][1] = '|') or (Memo2.Lines.Strings[i][1] = #13) then
begin
ShowMessage('Ошибка в правилах вывода! Правая часть выражения задана неверно!');
Exit;
end;
SetLength(Index, Length(Edit2.Text));
for i:= 0 to Length(index)-1 do index[i].P:= nil;
//-------------------------------------------------------------------------
for i:= 0 to Memo1.Lines.Count-1 do
begin
if Memo1.Lines.Strings[i][1] = edtCel.Text then
begin
Memo1.Lines.Insert(0, Memo1.Lines.Strings[i][1]);
Memo1.Lines.Delete(i+1);
Memo2.Lines.Insert(0, Memo2.Lines.Strings[i]);
Memo2.Lines.Delete(i+1);
Break;
end;
end;
btnRulesFill.Enabled := True;
SetLength(index, Memo1.Lines.Count);
for i:= 0 to Memo1.Lines.Count-1 do
begin
index[i].Ch:= Memo1.Lines.Strings[i][1];
index[i].Len:= 0;
new(q);
q.rule:= '';
for j:= 1 to Length(Memo2.Lines.Strings[i]) do
begin
if Memo2.Lines.Strings[i][j] = '|' then
begin
inc(index[i].Len);
if Index[i].P = nil then
begin
q.number:= count;
inc(count);
Index[i].P:= q;
if q.rule = '' then
begin
ShowMessage('Грамматика не должна содержать пустых правил!!!');
Exit;
end;
if (Length(q.rule) = 1) and (not(term(q.rule[1]))) then
begin
ShowMessage('Грамматика не должна содержать цепных правил!!!');
Exit;
end;
p:= q;
end else
begin
q.number:= count;
inc(count);
p.next:= q;
if q.rule = '' then
begin
ShowMessage('Грамматика не должна содержать пустых правил!!!');
Exit;
end;
if (Length(q.rule) = 1) and (not(term(q.rule[1]))) then
begin
ShowMessage('Грамматика не должна содержать цепных правил!!!');
Exit;
end;
p:= p.next;
end;
new(q);
q.rule:= '';
Continue;
end;
q.rule:= q.rule + Memo2.Lines.Strings[i][j];
end;
inc(index[i].Len);
if Index[i].P = nil then
begin
q.number:= count;
inc(count);
Index[i].P:= q;
if q.rule = '' then
begin
ShowMessage('Грамматика не должна содержать пустых правил!!!');
Exit;
end;
if (Length(q.rule) = 1) and (not(term(q.rule[1]))) then
begin
ShowMessage('Грамматика не должна содержать цепных правил!!!');
Exit;
end;
p:= q;
end else
begin
q.number:= count;
inc(count);
p.next:= q;
if q.rule = '' then
begin
ShowMessage('Грамматика не должна содержать пустых правил!!!');
Exit;
end;
if (Length(q.rule) = 1) and (not(term(q.rule[1]))) then
begin
ShowMessage('Грамматика не должна содержать цепных правил!!!');
Exit;
end;
p:= p.next;
end;
p.next:= nil;
end;
head:= rec(index[0].Ch, head, 0, index[0].Ch);
if ListBox1.Items.Count = 0 then ShowMessage('Такие цепочки в такой грамматике сгенерированы быть не могут!!!');
end;
procedure TForm1.Edit2KeyPress(Sender: TObject; var Key: Char);
var
i : integer;
begin
if (ord(key) >= 65) and (ord(key) <= 90) then
begin
if Length(Edit2.Text) > 0 then
for i:= 0 to Length(Edit2.Text) do
if key = Edit2.Text[i] then key:= chr(0);
end
else
key:= chr(0);
end;
procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
var
i : integer;
begin
if ((ord(key) < 65) or (ord(key) >= 90)) and (key <> '|') then
begin
if Length(Edit1.Text) > 0 then
for i:= 0 to Length(Edit1.Text) do
if key = Edit1.Text[i] then key:= chr(0);
end
else
key:= chr(0);
end;
procedure TForm1.Memo1KeyPress(Sender: TObject; var Key: Char);
var
i : integer;
j : integer;
begin
for i:= 0 to Length(Edit2.Text) do
begin
if key = Edit2.Text[i] then
begin
for j:= 0 to Memo1.Lines.Count-1 do
if key = Memo1.Lines.Strings[j][1] then key:= chr(0);
Exit;
end;
end;
if (key <> #8) and (key <> #13) then key:= chr(0);
end;
procedure TForm1.Memo2KeyPress(Sender: TObject; var Key: Char);
var
i : integer;
begin
for i:= 0 to Length(Edit1.Text) do
if key = Edit1.Text[i] then exit;
for i:= 0 to Memo1.Lines.count-1 do
if key = Memo1.Lines.Strings[i][1] then exit;
if (key <> #8) and (key <> #13) and (key <> '|') then key:= chr(0);
end;
procedure TForm1.Edit3KeyPress(Sender: TObject; var Key: Char);
begin
case key of
'0'..'9': ;
#8: ;
else
key:= chr(0);
end;
if key <> #8 then if (StrToInt(Edit3.Text+key) > StrToInt(Edit4.Text)) or
(StrToInt(Edit3.Text+key) > 1001) then key:= chr(0);
end;
procedure TForm1.Edit4KeyPress(Sender: TObject; var Key: Char);
begin
case key of
'0'..'9': ;
#8: ;
else
key:= chr(0);
end;
if key <> #8 then if (StrToInt(Edit4.Text+key) < StrToInt(Edit3.Text)) or (StrToInt(Edit4.Text+key) > 1001) then key:= chr(0);
end;
//формирование дерева вывода
procedure rec1(p : PTree; st : string; l : integer);
var
i : integer;
begin
if st = head.Rul+' ' then st:= '';
if StrComp(PChar(p.Str), PChar(Chain)) = 0 then
begin
Tree:= st+p.Rul;
find:= true;
Exit;
end;
if Len(p.Str) > Length(Chain) then Exit;
for i:= 0 to l-1 do
if not(find) then
if p.next[i] <> nil then
rec1(p.next[i], st+p.Rul+' ', p.next[i].Len);
end;
function Change(st1 : string; st2 : string; j : integer) : string;
var
i : integer;
st : string;
begin
st:= '';
for i:= 1 to j do
st:= st + st1[i];
Change:= st + st2;
end;
//выводит последовательность использованных правил
function Print(R : TAutomat) : string;
var
i : integer;
st : string;
begin
st:= '';
for i:= R.el-1 downto 0 do st:= st+ IntToStr(R.stack[i])+',';
Print:= '['+st+']';
end;
//откат q->b or b->q
procedure Back(var R : TAutomat);
var
i : integer;
p : PTRule;
begin
R.Cons:= 'b';
dec(R.el);
if R.el < 0 then Exit;
if R.stack[R.el] = 0 then
begin
R.stack[R.el]:= -1;
R.stack[R.el+1]:= -1;
dec(R.ind);
R.chain:= Change(R.chain, '', Length(R.chain)-1);
Consists:= Consists+'('+R.Cons+','+IntToStr(R.ind)+','+R.chain+','+Print(R)+') |- ';
end else
begin
for i:= 0 to Length(Index) - 1 do
begin
p:= Index[i].P;
while p <> nil do
begin
if p.number = R.stack[R.el] then
begin
R.chain:= Change(R.chain, p.rule, Length(R.chain)-1);
Consists:= Consists+'('+R.Cons+','+IntToStr(R.ind)+','+R.chain+','+Print(R)+') |- ';
R.Cons:= 'q';
Exit;
end;
p:= p.next;
end;
end;
end;
end;
// шаг свёртка
procedure Svertka(var R : TAutomat);
var
i : integer;
j : integer;
st : string;
p : PTRule;
begin
if R.Cons <> 'b' then
for j:= Length(R.chain) downto 1 do
begin
st:= '';
for i:= j to Length(R.chain) do
st:= st + R.chain[i];
for i:= 0 to Length(Index) - 1 do
begin
p:= Index[i].P;
while p <> nil do
begin
if p.number > R.stack[R.el] then
if StrComp(PChar(st), PChar(p.rule)) = 0 then
begin
R.chain:= Change(R.chain, Index[i].Ch, j-1);
R.stack[R.el]:= p.number;
R.Cons:= 'q';
inc(R.el);
Consists:= Consists+'('+R.Cons+','+IntToStr(R.ind)+','+R.chain+','+Print(R)+') |- ';
Exit;
end;
p:= p.next;
end;
end;
end;
R.stack[R.el]:= -1;
if (R.ind+1 <= Length(Chain)+1) and (R.Cons <> 'b') then
begin
inc(R.ind);
R.chain:= R.chain+Chain[R.ind - 1];
R.stack[R.el]:= 0;
inc(R.el);
Consists:= Consists+'('+R.Cons+','+IntToStr(R.ind)+','+R.chain+','+Print(R)+') |- ';
end else Back(R);
end;
//шаг "сдвиг"
procedure Sdvig(var R : TAutomat);
var
i : integer;
begin
if R.chain = '' then
begin
inc(R.ind);
R.chain:= R.chain+Chain[R.ind - 1];
R.stack[R.el]:= 0;
inc(R.el);
Consists:= Consists+'('+R.Cons+','+IntToStr(R.ind)+','+ R.chain+','+Print(R)+') |- ';
end;
repeat
Svertka(R);
if (R.Cons = 'q') and (R.ind = Length(Chain)+1) and (R.chain = Index[0].Ch) then
begin
for i:= R.el-1 downto 0 do RulChain:= RulChain + IntToStr(R.stack[i]);
Exit;
end;
if R.el = -1 then Exit;
until false;
end;
//получили цепочку в результате разбора или не получили
function SS : boolean;
var
i : integer;
begin
RulChain:= '';
Consists:= '';
for i:= 0 to 1000 do raspoz.stack[i]:= -1;
raspoz.Cons:= 'q';
raspoz.ind:= 1;
raspoz.chain:= '';
raspoz.el:= 0;
SS:= false;
Sdvig(raspoz);
Form4.Show;
ShowMessage(RulChain);
if RulChain <> '' then SS:= true;
end;
procedure TForm1.ListBox1Click(Sender: TObject);
var
i : integer;
st : string;
begin
Chain:= ListBox1.Items.Strings[ListBox1.ItemIndex];
if SS then
begin
find:= false;
Tree:= '';
rec1(head, '', head.Len);
if Form1.CheckBox1.Checked then Form2.Show;
st:= '';
for i:= 1 to Length(tree) do
if tree[i] = ' ' then st:= st+#13 else st:= st+ tree[i];
btnSaveResult.Enabled := True;
ShowMessage(st);
end else ShowMessage('Цепочка не принята!');
end;
//проверка цепочки по "Проверить"
procedure TForm1.Button2Click(Sender: TObject);
var
i : integer;
st : string;
j : integer;
p : PTRule;
q : PTRule;
begin
if Edit5.Text = '' then
begin
ShowMessage('Отсутствует цепочка на входе!!!');
Exit;
end;
head:= nil;
count:= 1;
p:= nil;
Form1.ListBox1.Items.Clear;
if Edit1.Text = '' then
begin
ShowMessage('Не указан алфавит терминальных символов!!!');
Exit;
end;
if Edit2.Text = '' then
begin
ShowMessage('Не указан алфавит нетерминальных символов!');
Exit;
end;
if Edit3.Text = '' then
begin
ShowMessage('НЕ указана минимальная длинна ципочки!');
Exit;
end;
if Edit4.Text = '' then
begin
ShowMessage('НЕ указана максимальная длинна ципочки!');
Exit;
end;
if (Memo1.Lines.Count = 0) or (Memo2.Lines.Count = 0) then
begin
ShowMessage('Отсутствуют правила вывода!');
Exit;
end;
if Memo1.Lines.Count <> Memo2.Lines.Count then
begin
ShowMessage('Ошибка в правилах вывода!');
Exit;
end;
if Edit1.Text = '' then
begin
ShowMessage('Отсутствует алфавит терминальных символов!');
Exit;
end;
if Edit2.Text = '' then
begin
ShowMessage('Отсутствует алфавит нетерминальных символов!');
Exit;
end;
for i:= 0 to Memo1.Lines.Count-1 do
if Length(Memo1.Lines.Strings[i]) > 1 then
begin
ShowMessage('Ошибка в правилах вывода! В левой части выражения указан неизвестный символ!');
Exit;
end;
for i:= 0 to Memo2.Lines.Count-1 do
if (Memo2.Lines.Strings[i][1] = '') or (Memo2.Lines.Strings[i][1] = '|') or (Memo2.Lines.Strings[i][1] = #13) then
begin
ShowMessage('Ошибка в правилах вывода! Правая часть выражения задана неверно!');
Exit;
end;
SetLength(Index, Length(Edit2.Text));
for i:= 0 to Length(index)-1 do index[i].P:= nil;
//-------------------------------------------------------------------------
btnSaveResult.Enabled := True;
SetLength(index, Memo1.Lines.Count);
for i:= 0 to Memo1.Lines.Count-1 do
begin
index[i].Ch:= Memo1.Lines.Strings[i][1];
index[i].Len:= 0;
new(q);
q.rule:= '';
for j:= 1 to Length(Memo2.Lines.Strings[i]) do
begin
if Memo2.Lines.Strings[i][j] = '|' then
begin
inc(index[i].Len);
if Index[i].P = nil then
begin
q.number:= count;
inc(count);
Index[i].P:= q;
if q.rule = '' then
begin
ShowMessage('Грамматика не должна содержать пустых правил!');
Exit;
end;
if (Length(q.rule) = 1) and (not(term(q.rule[1]))) then
begin
ShowMessage('Грамматика не должна содержать цепных правил!');
Exit;
end;
p:= q;
end else
begin
q.number:= count;
inc(count);
p.next:= q;
if q.rule = '' then
begin
ShowMessage('Грамматика не должна содержать пустых правил!');
Exit;
end;
if (Length(q.rule) = 1) and (not(term(q.rule[1]))) then
begin
ShowMessage('Грамматика не должна содержать цепных правил!');
Exit;
end;
p:= p.next;
end;
new(q);
q.rule:= '';
Continue;
end;
q.rule:= q.rule + Memo2.Lines.Strings[i][j];
end;
inc(index[i].Len);
if Index[i].P = nil then
begin
q.number:= count;
inc(count);
Index[i].P:= q;
if q.rule = '' then
begin
ShowMessage('Грамматика не должна содержать пустых правил!');
Exit;
end;
if (Length(q.rule) = 1) and (not(term(q.rule[1]))) then
begin
ShowMessage('Грамматика не должна содержать цепных правил!');
Exit;
end;
p:= q;
end else
begin
q.number:= count;
inc(count);
p.next:= q;
if q.rule = '' then
begin
ShowMessage('Грамматика не должна содержать пустых правил!');
Exit;
end;
if (Length(q.rule) = 1) and (not(term(q.rule[1]))) then
begin
ShowMessage('Грамматика не должна содержать цепных правил!');
Exit;
end;
p:= p.next;
end;
p.next:= nil;
end;
head:= rec(index[0].Ch, head, 0, index[0].Ch);
Chain:= Edit5.Text;
if SS then
begin
find:= false;
Tree:= '';
rec1(head, '', head.Len);
if Form1.CheckBox1.Checked then Form2.Show;
st:= '';
for i:= 1 to Length(tree) do
if tree[i] = ' ' then st:= st+#13 else st:= st+ tree[i];
st1 := st;
ShowMessage(st);
end else ShowMessage('Цепочка не принята!');
end;
procedure TForm1.Edit5KeyPress(Sender: TObject; var Key: Char);
begin
if key <> #8 then if not(term(key)) then key:= chr(0);
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
Form3.Show;
end;
procedure TForm1.Button4Click(Sender: TObject);
begin
Edit1.Text:= '';
Edit2.Text:= '';
Memo1.Clear;
Memo2.Clear;
end;
procedure TForm1.btnOpenClick(Sender: TObject);
var
f: TextFile;
fName: String[80];
buf: string[80];
begin
if OpenDialog1.Execute then
fName := OpenDialog1.FileName;
AssignFile(f, fName);
Reset(f);
readln(f, buf);
Edit1.Text := buf;
readln(f, buf);
Edit2.Text := buf;
readln(f, buf);
edtCel.Text := buf;
Memo1.Clear;
Memo2.Clear;
readln(f, buf);
while buf <> '[rules2]' do begin
Memo1.Lines.Add(buf);
readln(f, buf);
end;
while not EOF(f) do begin
readln(f, buf);
Memo2.Lines.Add(buf);
end;
CloseFile(f);
end;
procedure TForm1.btnSaveClick(Sender: TObject);
var
f: TextFile;
fName: String[80];
i: Integer;
begin
if SaveDialog1.Execute then
fName := SaveDialog1.FileName;
AssignFile(f, fName);
Rewrite(f);
writeln(f, Edit1.Text);
writeln(f, Edit2.Text);
writeln(f, edtCel.Text);
for i:= 0 to Memo1.Lines.Count do
begin
if Memo1.Lines[i] <> '' then
writeln(f, Memo1.Lines[i]);
end;
writeln(f, '[rules2]');
for i:= 0 to Memo2.Lines.Count do
begin
if Memo1.Lines[i] <> '' then
writeln(f, Memo2.Lines[i]);
end;
CloseFile(f);
end;
procedure TForm1.EditCelKeyPress(Sender: TObject; var Key: Char);
var
i : integer;
buf : Char;
begin
if (ord(key) >= 65) and (ord(key) <= 90) then
begin
buf := Key;
if Length(Edit2.Text) > 0 then
for i:= 0 to Length(Edit2.Text) do
begin
if buf = Edit2.Text[i] then
begin
Key:= buf;
break;
end
else
Key := chr(0);
end
end
else
key:= chr(0);
end;
procedure TForm1.btnSaveResultClick(Sender: TObject);
var
i: Integer;
f: TextFile;
fName: String[80];
begin
if dlgSaveRes.Execute then
fName := dlgSaveRes.FileName;
AssignFile(f, fName);
Rewrite(f);
Writeln(f, 'Терминальные символы:');
Writeln(f, Edit1.Text);
Writeln(f, 'Нетерминальные символы:');
Writeln(f, Edit2.Text);
Writeln(f, 'Проверяемая цепочка:');
Writeln(f, Edit5.Text);
Writeln(f, 'Правила:');
for i:=0 to MemoRules.Lines.count do
begin
writeln(f, MemoRules.Lines[i]);
end;
Writeln(f, 'Результат:');
write(f, Consists);
writeln(f, st1);
CloseFile(f);
end;
procedure TForm1.btnRulesFillClick(Sender: TObject);
var
i : integer;
st : string;
j : integer;
count : Integer;
p : PTRule;
q : PTRule;
begin
count := 1;
st := IntToStr(count) + ': ';
st := st + Memo1.Lines[0][1] + '->';
for i:= 0 to Memo2.Lines.Count-1 do
begin
for j:=1 to Length(Memo2.Lines[i]) do
begin
if Memo2.Lines[i][j] = '|' then
begin
count := count + 1;
MemoRules.Lines.Add(st);
st := IntToStr(count) + ': ';
st := st + Memo1.Lines[i][1] + '->';
end
else
begin
st := st + Memo2.Lines[i][j];
end;
end;
count := count + 1;
MemoRules.Lines.Add(st);
st := IntToStr(count) + ': ';
st := st + Memo1.Lines[i][1] + '->';
end;
end;
end.