www.jammni.de

Logo - Kleiner Drache
Login
Username:

Passwort:

Daten merken
Auto-Login
Registrieren
 
Online
niemand
 
Forumsuche
Suche nach:

Logo - DracheHaskell-Forum

vorherige Seite 1 2  

arnold74

Gepostet:
06.05.2010 19:44

   
nub - Ok, werde diese gleich Testen, danke!
ja, passt, danke für den Hinweis,habe diesen Code nur schnell gepostet!

Habe aber schon wieder ein neues Problem, bzw. Fragen an Dich (wenn der Code fertig ist, werde ich Dich als Co-Programmierer erwähnen :-) )

Möchte nun eine einfache Funktion implementieren, die prüft ob ein Symbol ein Terminalsymbol ist, dazu habe ich eigentlich eine Liste implementiert


terminals = words "a,..,z,0..9,(,),[,],+,-,*,/"

Frage 1: Kann ich diese so definieren mit a,..,z usw. Scheint mir am einfachsten, denn es kommen ja auch andere Zeichen als nur Kleinbuchstaben vor

Frage2: Habe versucht eine einfache Funktion zu implementieren, die mir sagt ob ein übergebener Wert ein Terminalsymbol ist:

isTerminal::Symbol -> Bool
isTerminal x = (x `elem` words)

Leider scheint auch hier wieder was falsch zu sein. elem sollte doch boolean zurückgeben. Vielleicht kannst Du mir auch hier weiterhelfen.

danke,
Arnold
Zum Seitenanfang    
 
Siracusa

Gepostet:
06.05.2010 23:32

   
> terminals = words "a,..,z,0..9,(,),[,],+,-,*,/"

Also das klappt nicht so wie du dir das vorstellst. words teilt einen String in mehrere Teile, und zwar an jedem Block von Leerzeichen, z.B. words "Haskell ist cool!" = ["Haskell","ist","cool!"]. Heißt also, dein gesamter String wäre ein "Wort". Wenn du eine Liste von Chars (also ein String) willst, dann ohne Kommata dazwischen, z.B. "()[]+-*/" wären die Sonderzeichen. Die Zahlen kannst du mit ['0' .. '9'], die Buchstaben mit ['a' .. 'z'] erzeugen und alle Strings mit ++ zusammenketten.

> isTerminal x = (x `elem` words)

Das Prinzip ist richtig, words ist aber keine Liste sondern eine Funktion (siehe oben). da sollte also vermutlich terminals stehen.
Zum Seitenanfang    
 
arnold74

Gepostet:
08.05.2010 09:40

   
Guten Morgen,
sorry dass ich Dich schon wieder belästige; obwohl es im Internet heißt die FirstMenge zu ermitteln sei leicht, bin ich langsam der Verzweiflung nah! (Ja, so eine funktionale Programmiersprache hat es in sich)

meine erste Frage betrifft die Ausgabe der Produktionen
S {
S : AB
A :
A : a A
B :
B : b B
}
("S",[AB])
("A",[])
("A",[a,A])
("B",[])
("B",[b,B])
Wie Du siehst werden die Produktionen richtig in der Form (Variable,[Symbol]) abgebildet. Aber wieso werden in der Liste die Symbole und Terminale nicht in Hochkommas angezeigt. Ich möchte gerne eine Funktion erstellen, die mir nach Eingabe der Variable S, alle Produktionen dieser in einer Liste zurückgibt, aus welche ich dann die Firstmenge berechnen kann.


find :: Variable -> [(Variable,[Symbol])] ->[Symbol]
find k t = [v|(k',[v])<-t, k ==k']

Ich möche nach Eingabe von "A" die Mengen [[],[a,A]] erhalten! Habe es mit GHCI getestet, aber leider ohne Erfolg, Not in Scope Data Constructor 'AB'. Vielleicht kannst Du mir ja weiterhelfen.

Versuche in der ZwischenZeit den Algorithmus auf Blatt in Haskell zu erstellen.

danke
arnold
Zum Seitenanfang    
 
Siracusa

Gepostet:
09.05.2010 18:30

   
> Aber wieso werden in der Liste die Symbole und Terminale nicht in Hochkommas angezeigt

Das liegt vermutlich an der Show-Instanz des Typs Symbol. Dort gibt es eine Funktion show, die bestimmt wie das Symbol ausgegeben werden soll. Entweder ergänzt du da die Hochkommata, oder du schreibst eine Funktion die das tut und rufst die nach dem Aufruf von show auf.

> find k t = [v|(k',[v])<-t, k ==k']

Wenn du (k',[v]) <- t schreibst, heißt das du holst dir nur alle Paare, wo der zweite Wert eine Liste mit genau einem Symbol x ist. Es sollte besser (k', vs) heißen, dann ist vs die Liste mit allen Symbolen. Natürlich bekommst du dann als Resultat für find eine Liste von Listen, die du aber mit der Funktion concat zu einer "flachen" Liste verbinden kannst (wenn das erforderlich ist).

> Not in Scope Data Constructor 'AB'

Das heißt du hast vermutlich die Hochkommata um AB vergessen.
Zum Seitenanfang    
 
arnold74

Gepostet:
10.05.2010 14:30

   
danke für deine Tipps.
Vielleicht kannst Du mir auch sagen wie ich ein find direkt auf [Productions] anwenden kann. Habe folgendes versucht, doch leider ohne Erfolg:

find :: Variable -> [(Variable,[Symbol])] ->[[Symbol]]
find k t = [vs|(k',vs)<-t, k ==k']

find2 :: Variable -> [Production] -> [Symbol]
find2 k ((Production x xs):rest) = [vs | vs <- xs, x==k]++ find2 k rest


Es geht um find2. Ich denke es ist vielleicht sinnvoller direkt laut Grammatik-Def zu suchen, denn sonst muss ich ja zuerst immer die Grammatik zuvor in meine Liste von Tuples konvertieren oder was meinst Du? Somit möchte ich einfach die Produktionen filtern und zwar nach all jenen wo ein bestimmtes Symbol vorkommt. Denke mal es sollte auch über die Funktion filter funktionieren,(ist für mich zur Zeit noch zu schwierig); habe ja schon bei einfachen Sachen meine Probleme, somit wollte ich es so ähnlich lösen wie das normale find, aber auch das klappt nicht. Oder ist dieser Code für find2 richtig? Werden hier schon alle Produktionen durchsucht und nur jene des entsprechenden Symbols zurückgegeben? Fehlermeldung bekomme ich keine wenn ich das Modul lade, aber ob das so auch klappt, ich habe mein Zweifel!

danke und grüsse
arnold


Zum Seitenanfang    
 
Siracusa

Gepostet:
11.05.2010 16:19

   
Hallo,

ehrlich gesagt habe ich jetzt etwas den Überblick verloren, was du genau vorhast z.B. bei find2 :-) Aber mal ein allgemeiner Tipp: Wenn du eine Funktion schreibst, überleg dir grob wie sie mathematisch funktionieren würde und versuche dann deine Funktion in kleinen Schritten im Interpreter aufzubauen. Der GHCi eignet sich bestens zum experimentieren. Lass dir z.B. den Typ von Standardfunktionen mit :t im GHCi anzeigen, dann füge einzelne Argumente hinzu und probiere kleine Beispielausdrücke aus. Mag vielleicht komisch klingen, m.E. ist der Lerneffekt so aber größer, als wenn man die "fertige" Funktion in die Datei schreibt und sich dann durch die Fehlermeldungen kämpfen muss.


Viele Grüße,

Siracusa
Zum Seitenanfang    
 
arnold74

Gepostet:
11.05.2010 18:33

   
danke,
teste schon seit einiger Zeit mit ghci. Doch das Problem liegt mit :t kann ich mir die Standardfunktionen durchschauen. Ich muss ja direkt auf der Grammatik arbeiten und nicht auf den Beispielen in den Büchern, leider. Werde aber deinen Ratschlag befolgen und werde nochmals versuchen direkt im ghci main aufzurufen, dort eine Grammatik zu übergeben und dann mit GHCI testen.
Vielen Dank in der Zwischenzeit,
ps mit find2 möchte ich einfach alle Produktionen einer Grammatik einer Variablen auslesen:

S : AB
A:
A:aA
B:
B:bB , wenn ich dann B übergebe sollte ich alle Produktionen von B erhalten!

danke nochmals für deine Geduld
arnold
Zum Seitenanfang    
 
Siracusa

Gepostet:
11.05.2010 21:48

   
Du brauchst ja die main nicht unbedingt zum Testen, du kannst dir ja auch in der Datei oder direkt im GHCi einfach Werte vom Typ Grammatik erstellen, direkt durch Verwendung der Konstruktoren für Grammatik, Production, etc. Für find2 ist dann sicher "filter" sehr hilfreich. Die übergebene Filterfunktion würde dann schauen, ob das Nonterminal das gleiche ist wie das übergebene Nonteminal. Damit hättest du schonmal alle Produktionen, mit "map" könnstest du dann nur die Liste der Symbole aus allen Produktionen holen (ließe sich beides zusammen auch nur durch List Comprehensions erreichen).
Zum Seitenanfang    
 
arnold74

Gepostet:
13.05.2010 08:29

   
Hallo,
Ja wäre super wenn ich es direkt in GHCI testen könnte, oder vielleicht eine Beispielgrammatik in FirstFollow.hs einfügen könnte. Leider gelingt mir das nicht. Habe durch kompilieren gesehen, dass bis jetzt die einzelnen Funktionen korrekt sind.Aber vielleicht kannst Du mir ja sagen wie ich das machen soll?
Hier meine Fehlermeldung direkt im GHCI (idealer wäre es die Grammatik direkt im hs-File zu deklarieren)

Prelude FirstFollow> find2 "A" ["A" ["A","+","B"],"B" []]

<interactive>:1:11:
Couldn't match expected type `t -> Grammar.Production'
against inferred type `[Char]'
In the expression: "A" ["A", "+", "B"]
In the second argument of `find2', namely
`["A" ["A", "+", ....], "B" []]'
In the expression: find2 "A" ["A" ["A", "+", ....], "B" []]
Die Grammatikd ist ja folgendermaßen definiert:

type Variable = String
type Terminal = Char
data Symbol = V Variable | T Terminal
deriving (Eq, Ord)

data Grammar = Grammar Variable [Production]

data Production = Production Variable [Symbol]
deriving Eq


danke
Zum Seitenanfang    
 
Siracusa

Gepostet:
14.05.2010 17:22

   
Hallo,

also die Grammatik ist falsch. Laut Definition muss jede Grammatik auch mit dem Datenkonstruktor Grammar beginnen, analog gilt dies auch für alle anderen Typen. Eine einfache Grammatik für S ::= aS | a könnte so aussehen (ungetestet):
gram1 :: Grammar
gram1 = Grammar "S" [Production "S" [T 'a', V "S"], Production "S" [T 'a']]


Viele Grüße

Siracusa
Zum Seitenanfang    
 

vorherige Seite 1 2