| Author |
Message
|
KaBo_8 Poziom 9

Joined: 29 Mar 2006 Posts: 34
|
#1
23 Apr 2006 12:02 Delphi i HPGL |
|
|
|
Mam problem z napisaniem programu, który odczytywałby pliki zapisane w formacie hpgl (program ma obsługiwać ploter). Chodzi mi dokładniej o to ze nie mam zielonego pojęcia jak napisać część kodu która interpretowałaby coś takiego:
IN; IP 0,0,100,100; SC 0,100,0,100;
SP 2;
PA 1474,1299;
PD;
PA 1464,1289;
PA 1452,1289;
PA 1442,1299;
PA 1442,1921;
PA 1452,1931;
PA 1464,1931;
z tym żę sprawa jest troszkę ułatwiona, ponieważ program ma ignorować wszystkie linijki, które nie zaczynają się na literę "P". Chciałbym aby program (dla linijki PA 1474,1299;) podstawiał pod zmienną "a" najpierw wartość "PA" lub samo "A" dla zmiennej x=1474 dla y=1299 a po średniku przeszedł do następnej linijki... Nie oczekuję od państwa całego kodu.. ale wskazówek gdzie i czego powinienem szukać.. co powinienem wiedzieć.. z góry dziękuję!
|
|
| Back to top |
|
 |
Google

|
#
23 Apr 2006 12:02 |
|
|
|
|
|
| Back to top |
|
 |
Xitami Poziom 21

Joined: 10 Aug 2004 Posts: 1126 Location: Gliwice
|
#2
23 Apr 2006 14:11 Re: Delphi i HPGL |
|
|
|
| Code: |
function dwiewartosci(s, var x,y):errcode begin
err:=jednawartosc(s, x, idx)
...
err:=jednawartosc(copy(s, idx+1, 255), y, idx)
...
end;
pocedure PAproc(s) begin
dwiewartości(s, x, y)
...
end;
...
readln(fi, s) ..... albo jakoś tam po Delphiemu
if pos(‘PA’, s)=1 Paproc(copy(s,3,255))
else if pos(‘PD’, s)=1 then Pdproc(copy(s, 3, 255))
else ...
|
|
|
| Back to top |
|
 |
Google

|
#
23 Apr 2006 14:11 |
|
|
|
|
|
| Back to top |
|
 |
elektryk Poziom 26

Joined: 25 Apr 2002 Posts: 11092
|
#3
24 Apr 2006 00:51 Re: Delphi i HPGL |
|
|
|
Nie znam dokładnie składni HPGL, ale wydaje mi się że zestaw typu lekser i parser (np bison i flex) by zupełnie rozwiązały taki problem. Wszystko ograniczyłoby się do zaprojektowania odpowiedniej gramatyki i zdefiniowania akcji jakie mają być wykonane przy określonych instrukcjach (akcje mogą od razu operować na danych i argumentach). Nie wiem tylko czy to nie zabijanie much z armaty, wszystko zależy od skomplikowania gramatyki pliku HPGL, przy okazji wszystkie możliwe błedy składni (błedy w plikach) byłyby wychwytywane w czasie analizowania pliku, niejako automatycznie.
|
|
| Back to top |
|
 |
Google

|
#
24 Apr 2006 00:51 |
|
|
|
|
|
| Back to top |
|
 |
BoskiDialer Poziom 22

Joined: 28 Nov 2003 Posts: 1533 Location: Żory
|
#4
24 Apr 2006 21:45 Delphi i HPGL |
|
|
|
ja bym to zrobił mniej więcej tak:
najpierw bym wyszukał średnika ";" oraz wyciął daną linie (bez średnika).
wyszukał pierwszą spacje lub eol
text od początku do spacji lub eol to polecenie, dalej mogą sie znajdować argumenty..
z argumentami: poszukać przecinka, rozciąć dane na 2 części i zamienić na liczby.
coś typu:
| Code: |
program hpglparser;
{$APPTYPE CONSOLE}
uses
SysUtils, Classes, StrUtils;
var
OnPenUp: procedure;
OnPenDown: procedure;
OnPenMove: procedure(X,Y: Integer);
OnUnknownCmd: procedure(Cmd: String; Args: String);
procedure ParseHpgl(AFileName: String);
var
Cmds: TStrings;
vI,vO: Integer;
vCmd,vArg: String;
procedure LoadHpglFile;
var
vFile: File;
vRaw: String;
vLastPos, vPos: Integer;
begin
// wczytanie pliku do vRaw
AssignFile(vFile,AFileName);
Reset(vFile,1);
SetLength(vRaw,FileSize(vFile));
try
BlockRead(vFile,vRaw[1],Length(vRaw));
finally
CloseFile(vFile);
end;
vRaw := AnsiReplaceStr(vRaw,#13#10,'');
// podzielenie textu na polecenia
vLastPos := 1;
for vPos := 1 to Length(vRaw) do
if vRaw[vPos] = ';' then
begin
Cmds.Add(Trim(Copy(vRaw,vLastPos,vPos-vLastPos)));
vLastPos := vPos+1; { +1 by uciac znak ; }
end;
end;
procedure ParsePA(APos: String);
var
vX,vY,vI: Integer;
begin
for vI := 1 to Length(APos) do
if APos[vI] = ',' then
begin
vX := StrToInt(Copy(APos,1,vI-1));
vY := StrToInt(Copy(APos,vI+1,Length(APos)-vI));
OnPenMove(vX,vY);
break;
end;
end;
begin
Cmds := TStringList.Create;
try
LoadHpglFile;
// wykonanie wszystkich poleceń
for vI := 0 to Cmds.Count-1 do
begin
// pierwotna skladnia
vCmd := Cmds[vI];
vArg := '';
// wydobycie argumentu
for vO := 1 to Length(vCmd) do
if vCmd[vO] = ' ' then
begin
vArg := Copy(vCmd,vO+1,Length(vCmd)-1);
vCmd := Copy(vCmd,1,vO-1);
break;
end;
writeln(vCmd+' -> '+vArg);
if (vCmd = 'PD') and Assigned(OnPenDown) then
OnPenDown
else if (vCmd = 'PU') and Assigned(OnPenUp) then
OnPenUp
else if (vCmd = 'PA') and Assigned(OnPenMove) then
ParsePA(vArg)
else if Assigned(OnUnknownCmd) then
OnUnknownCmd(vCmd,vArg);
end;
finally
Cmds.Free;
end;
end;
procedure MyFuncPenUp;
begin
writeln(' Pen Up!');
end;
procedure MyFuncPenDown;
begin
writeln(' Pen Down!');
end;
procedure MyFuncPenMove(X,Y: Integer);
begin
writeln(Format(' Pen Move to x:%d y:%d',[X,Y]));
end;
procedure MyFuncUnknownCmd(Cmd: String; Args: String);
begin
writeln(Format(' Unknown cmd... %s %s',[Cmd,Args]));
end;
begin
try
OnPenUp := MyFuncPenUp;
OnPenDown := MyFuncPenDown;
OnPenMove := MyFuncPenMove;
OnUnknownCmd := MyFuncUnknownCmd;
ParseHpgl('testhpgl.txt');
except
on E:Exception do
writeln('ERROR '+E.Message);
end;
readln;
end. |
| Quote: |
IN ->
Unknown cmd... IN
IP -> 0,0,100,100
Unknown cmd... IP 0,0,100,100
SC -> 0,100,0,100
Unknown cmd... SC 0,100,0,100
SP -> 2
Unknown cmd... SP 2
PA -> 1474,1299
Pen Move to x:1474 y:1299
PD ->
Pen Down!
PA -> 1464,1289
Pen Move to x:1464 y:1289
PA -> 1452,1289
Pen Move to x:1452 y:1289
PA -> 1442,1299
Pen Move to x:1442 y:1299
PA -> 1442,1921
Pen Move to x:1442 y:1921
PA -> 1452,1931
Pen Move to x:1452 y:1931
PA -> 1464,1931
Pen Move to x:1464 y:1931 |
|
|
| Back to top |
|
 |
KaBo_8 Poziom 9

Joined: 29 Mar 2006 Posts: 34
|
#5
07 May 2006 12:57 Re: Delphi i HPGL |
|
|
|
Dobra.. tylko to jest pod konsolę.... a o to raczej nie chodziło.... :/ W normalnym programie to mi sie nie wykona... A poza tym to problem polega na rozdzieleniu tych DANYCH i gotowiec mi raczej nic nie daje ... JAKIEGOŚ nauczyciela bym potrzebował.. co mi to wytłumaczy... :/:(
|
|
| Back to top |
|
 |