Parser/ Interpreter

03/04/2010 - 07:41 von Karsten Sosna | Report spam
Hallo NG,
ich bin gerade dabei einen Interpreter für eine NC-Language zu schreiben. Im
Moment passiert aber immer ein "Rollback" anstelle das es vorwàrts geht. Als
Grundlage soll dieses dienen:

http://linuxcnc.org/handbook/RS274N...C_33a.html

Die hier vorgestellten Normen scheinen sich mit den meisten Interpretern
dieser Sprache zu decken(Ausnahmen bestàtigen die Regel).
Also meinen Parser habe ich soweit, da kann ich eine Menge mit regulàren
Ausdrücken abdecken. Den Rest bekommt man relativ gut mit LINQ hin. Ich habe
jetzt nur ein Problem bei der Interpretation. Also ein Anweisungszeile
besteht aus mehren Befehlen und Parametern, hier ein Beispiel:

N30 G98 G81 Z-0.25 R0.125 F5

Problem besteht in der Zuordnung, den alle Befehle und Parameter sind
optional. Optional muss aber einschrànken, Oftmals ist es so das alle
Parameter optional sind, es muss aber in vielen Fàllen mindestens einer
angeben werden. Ich habe das schon versucht mit Delagates zu realisieren,
doch dann bekomme ich unendlich viele. Für die Skalierbarkeit ist das eine
Katastrophe, da steigt kein Mensch mehr durch. Irgendwie fehlt mir nur ein
"Baustein" hierzu das obige Beispiel

Anstelle von
N30 G98 G81 Z-0.25 R0.125 F5
hàtte ich auch
R0.125 N30 Z-0.25 G81 F5 G98
eingeben können. Ich habe also alle Token nur etwas durcheinander gebracht.
Das geht, da die Reihenfolge keine Rolle spielt. Jeder Befehl, hier G81 und
G98 haben ein Prioritàt, so wird G98 immer vor G81 ausgeführt, egal in
welcher Reihenfolge es geschrieben wurde. Parameter mit gleicher Prioritàt
sind in einer Zeile nicht zugelassen und verursachen einen Syntaxfehler.
N-Parameter sind völlig überflüssig sie sind Zeilennummern. Nutzt man sie
ist es aber auch egal wo sie stehen. Andere Parameter, wie hier R, Z und F
kann es nur einmal in einer Zeile geben. F und R lassen wir mal für die
nàchste Betrachtung außen vor, den sie abhàngig vom angewendeten Befehl.
Hier ist es G81 der Parameter erwartet und zwar (neben F und R) mindestens
den Parameter Z. Daher ist es nicht möglich bspw. G01 und G81 in einer Zeile
zu verwenden, da beide Befehle Z interpretieren würden. Diesen Fall habe ich
aber schon ausgeschlossen.
Mein Problem besteht jetzt darin zu überprüfen ob alle notwendigen Parameter
vorhanden sind.
Leider hatte ich im Studium das Fach Compilerbau nicht, daher tue ich mich
hier etwas schwer. Vielleicht kann mir ja jemand ein bisschen auf die
Sprünge helfen(Bitte keine seitenlangen Abhandlungen die nur theoretisch
sind, davon habe ich schon etliche hinter mir) Vielleicht fehlt mir nur eine
Idee, ein Hinweis oder ein Tipp damit ich weiter komme.

P.S.: Es hat nur insofern etwas mit VB.Net zu tun, weil das Projekt in
VB.Net geschrieben wird. Es geht nur um das grundsàtzliche wie man an so
etwas herangeht.

Danke für jede Hilfe.
Gruß Scotty
 

Lesen sie die antworten

#1 Bernd Schend
03/04/2010 - 18:55 | Warnen spam
Hallo Scotty,

einen fertigen Parser kann ich dir leider nicht liefern ;-)

Hilfreich wàre z.B., wenn du die NC-Sprache in BNF (Backus-Naur-Form)
beschreibst. Evtl. handelt es sich ja nur um eine Typ 2-Sprache
regulàre Ausdrücke). Dann reicht ein endlicher Automat als Parser aus.
Wenn es sich hingegen um eine Typ 3-Sprache (kontextfrei)
handelt, wird's komplizierter.

Im Studium habe ich seinerzeit einen Compiler für ein Pascal-Subset
implementiert.
Das Subset war in BNF spezifiziert. Mit dieser Spezifikation wiederum
habe ich einen sog. LALR(1)-Parser-Generator gefüttert. Ausgabe des
Generators war eine Art von Zustands-Übergangstabelle, die den
Parse-Vorgang steuerte.

Schau mal bei Wikipedia nach. Vielleicht findest du dort auch einen
geeigneten Parser-Generator. Ansinsten kannst du einen Parser auch
auf Basis der BNF auch als Top-Down-Parser selbst implementieren.

Prüfe aber bitte voher, ob nicht regulàre Ausdrücke ausreichend sind.

Gruß
Bernd

P.S.: Die Tatsache, das manchmal mindestens ein Parameter vorhanden
sein muss, làsst sich evtl. mit einer kontextfreien Grammatik nicht
ausdrücken. Dies muss von deinem Compiler dann auf der semantischen
Ebene ( = explizit) abgeprüft werden.


Am 03.04.2010 07:41, schrieb Karsten Sosna:
Hallo NG,
ich bin dabei einen Interpreter für eine NC-Language zu
schreiben. Im Moment passiert aber immer ein "Rollback" anstelle das es
vorwàrts geht. Als Grundlage soll dieses dienen:

http://linuxcnc.org/handbook/RS274N...C_33a.html

Die hier vorgestellten Normen scheinen sich mit den meisten Interpretern
dieser Sprache zu decken(Ausnahmen bestàtigen die Regel).
Also meinen Parser habe ich soweit, da kann ich eine Menge mit regulàren
Ausdrücken abdecken. Den Rest bekommt man relativ gut mit LINQ hin. Ich
habe jetzt nur ein Problem bei der Interpretation. Also ein
Anweisungszeile besteht aus mehren Befehlen und Parametern, hier ein
Beispiel:

N30 G98 G81 Z-0.25 R0.125 F5

Problem besteht in der Zuordnung, den alle Befehle und Parameter sind
optional. Optional muss aber einschrànken, Oftmals ist es so das alle
Parameter optional sind, es muss aber in vielen Fàllen mindestens einer
angeben werden. Ich habe das schon versucht mit Delagates zu
realisieren, doch dann bekomme ich unendlich viele. Für die
Skalierbarkeit ist das eine Katastrophe, da steigt kein Mensch mehr
durch. Irgendwie fehlt mir nur ein "Baustein" hierzu das obige Beispiel

Anstelle von
N30 G98 G81 Z-0.25 R0.125 F5
hàtte ich auch
R0.125 N30 Z-0.25 G81 F5 G98
eingeben können. Ich habe also alle Token nur etwas durcheinander
gebracht. Das geht, da die Reihenfolge keine Rolle spielt. Jeder Befehl,
hier G81 und G98 haben ein Prioritàt, so wird G98 immer vor G81
ausgeführt, egal in welcher Reihenfolge es geschrieben wurde. Parameter
mit gleicher Prioritàt sind in einer Zeile nicht zugelassen und
verursachen einen Syntaxfehler. N-Parameter sind völlig überflüssig sie
sind Zeilennummern. Nutzt man sie ist es aber auch egal wo sie stehen.
Andere Parameter, wie hier R, Z und F kann es nur einmal in einer Zeile
geben. F und R lassen wir mal für die nàchste Betrachtung außen vor, den
sie abhàngig vom angewendeten Befehl. Hier ist es G81 der Parameter
erwartet und zwar (neben F und R) mindestens den Parameter Z. Daher ist
es nicht möglich bspw. G01 und G81 in einer Zeile zu verwenden, da beide
Befehle Z interpretieren würden. Diesen Fall habe ich aber schon
ausgeschlossen.
Mein Problem besteht jetzt darin zu überprüfen ob alle notwendigen
Parameter vorhanden sind.
Leider hatte ich im Studium das Fach Compilerbau nicht, daher tue ich
mich hier etwas schwer. Vielleicht kann mir ja jemand ein bisschen auf
die Sprünge helfen(Bitte keine seitenlangen Abhandlungen die nur
theoretisch sind, davon habe ich schon etliche hinter mir) Vielleicht
fehlt mir nur eine Idee, ein Hinweis oder ein Tipp damit ich weiter komme.

P.S.: Es hat nur insofern etwas mit VB.Net zu tun, weil das Projekt in
VB.Net geschrieben wird. Es geht nur um das grundsàtzliche wie man an so
etwas herangeht.

Danke für jede Hilfe.
Gruß Scotty

Ähnliche fragen