Seite 1 von 1

Realisation eines Rechners mit Speicher?

Verfasst: Freitag 6. November 2009, 18:09
von mrlova
Hallo Zusammen

ich habe ein Problem bei Python. Ich muss einen vorgegebenen Quelltext mit folgendem abstakten Code editieren.

Ich weiss, es schaut nach sehr viel Code aus, aber es geht nur um eine Zeile...Bitte helft mir.

Abstrakter Code:
< command > = < assignment > | < expression >
< assignment > = < variable > ‘=’ < expression >
< expression > = < term >
| < expression > ‘+’ < term >
| < expression > ‘−’ < term > ;
< term > = < factor >
| < term > ‘×’ < factor > ;
< factor > = < number > | ‘(’ < expression > ‘)’ | < variable >
< number > = ( ‘0’ | ‘1’ | ‘2’ | ‘3’ | . . . | ‘9’ )+
< variable > = ‘a’ | ‘b’ | ‘c’
Folgende zeile bereitet mir Probleme:
< factor > = < number > | ‘(’ < expression > ‘)’ | < variable >
Ich weiss einfach nicht, wie ich die in Python Code umsetzten muss...

Folgendes habe ich bis jetzt selber geschafft:

Code: Alles auswählen

# Simple Calculator Parser
# 
#
# Description:
# This simple calculator parser evaluates any expression
# typed in, and outputs the result.
#
# Example:
#   > 2 + 3 - 1
#   Result: 4

def scanCommand():
        ok, x = assignment()
        if ok:
                print "Result:", x
        else:
                ok, x = scanExpression()
                if ok:
                        print "Result:", x
                else:
                        return False, 0
def assignment():
        global scanPosition
	
	ok, x = scanLetter()
	if not ok:
		return False, 0

	while True:
		lastPosition = scanPosition
		if scanChar('='):
			ok, y = scanExpression()
			if ok:
				x = y
			else:
				scanPosition = lastPosition
				break
		else:
			break

	return True, x


def scanExpression():
	global scanPosition
	
	ok, x = scanTerm()
	if not ok:
		return False, 0

	while True:
		lastPosition = scanPosition
		if scanChar('+'):
			ok, y = scanTerm()
			if ok:
				x = x + y
			else:
				scanPosition = lastPosition
				break
		elif scanChar('-'):
			ok, y = scanTerm()
			if ok:
				x = x - y
			else:
				scanPosition = lastPosition
				break
		else:
			break

	return True, x
	
def scanTerm():
	global scanPosition
	
	ok, x = scanFactor()
	if not ok:
		return False, 0
		
	while True:
		lastPosition = scanPosition
		if scanChar('x'):
			ok, y = scanFactor()
			if ok:
				x = x*y
			else:
				scanPosition = lastPosition
				break
		else:
			break

	return True, x
		


def scanFactor():
	global scanPosition
	
	ok, x = scanNumber()
	if ok:
		return True, x
	
	while True:
		lastPosition = scanPosition
		if scanChar('('):
			ok, y = scanExpression()	
		else:
			break
	return True, y

# Return whether the character 'char' could be scanned
def scanChar(char):
	skipWhitespace()
	ok, c = scanChars(char)
	return ok
	
# Return whether any sequence of digits could be scanned,
# together with its numerical value, as an integer number
def scanNumber():
	skipWhitespace()
	ok, c = scanDigit()
	if not ok: return False, 0
	s = ''
	while ok:
		s = s + c
		ok, c = scanDigit()
	return True, int(s)
	
# Return whether any digit could be scanned,
# together with the scanned digit
def scanDigit():
	return scanChars(['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'])

# Return whether any letter (a, b or c) could be scanned,
# together with the scanned letter
def scanLetter():
	skipWhitespace()
	return scanChars(['a', 'b', 'c'])

# Skip whitespace characters
def skipWhitespace():
	while True:
		ok, c = scanChars([' '])
		if not ok:
			break;

# Return whether any character from the list 'chars' could be scanned,
# together with the scanned character
def scanChars(chars):
	global scannedString, scanPosition
	if scanPosition >= len(scannedString):
		return False, ''
	for c in chars:
		if scannedString[scanPosition] == c:
			scanPosition += 1
			return True, c
	else:
		return False, ''

# Initialize the sttring to be scanned
def setScannedString(string):
	global scannedString, scanPosition
	scannedString = string
	scanPosition = 0
	
# Set the content of variable 'var' to x
def setVariable(var, x):
	global memory
	memory[var] = x
	
# Get the content of variable 'var'
def getVariable(var):
	global memory
	return memory[var]
	
memory = {}

# Main part of the program
print "(Type q to quit)"
while True:
	input = raw_input("> ")		# Prompt user for input
	if input[:1] == 'q':
		break					# Stop if user types 'q'
	elif len(input) > 0:		# If user typed something
		setScannedString(input)
		scanCommand()

Und dies ist die Vorlage(welche ich editieren musst, sodass der Rechner auch Speichern und Punkt vor Strich unterstützt):

Code: Alles auswählen

# Simple Calculator Parser
# FGII, Fall Semester 2008, Simon Bovet
#
# Description:
# This simple calculator parser evaluates any expression
# typed in, and outputs the result.
#
# Example:
#   > 2 + 3 - 1
#   Result: 4

def scanCommand():
	ok, x = scanExpression()
	if ok:
		print "Result:", x

def scanExpression():
	global scanPosition
	
	ok, x = scanFactor()
	if not ok:
		return False, 0

	while True:
		lastPosition = scanPosition
		if scanChar('+'):
			ok, y = scanFactor()
			if ok:
				x = x + y
			else:
				scanPosition = lastPosition
				break
		elif scanChar('-'):
			ok, y = scanFactor()
			if ok:
				x = x - y
			else:
				scanPosition = lastPosition
				break
		else:
			break

	return True, x

def scanFactor():
	ok, x = scanNumber()
	if ok:
		return True, x
	
	return False, 0

# Return whether the character 'char' could be scanned
def scanChar(char):
	skipWhitespace()
	ok, c = scanChars(char)
	return ok
	
# Return whether any sequence of digits could be scanned,
# together with its numerical value, as an integer number
def scanNumber():
	skipWhitespace()
	ok, c = scanDigit()
	if not ok: return False, 0
	s = ''
	while ok:
		s = s + c
		ok, c = scanDigit()
	return True, int(s)
	
# Return whether any digit could be scanned,
# together with the scanned digit
def scanDigit():
	return scanChars(['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'])

# Return whether any letter (a, b or c) could be scanned,
# together with the scanned letter
def scanLetter():
	skipWhitespace()
	return scanChars(['a', 'b', 'c'])

# Skip whitespace characters
def skipWhitespace():
	while True:
		ok, c = scanChars([' '])
		if not ok:
			break;

# Return whether any character from the list 'chars' could be scanned,
# together with the scanned character
def scanChars(chars):
	global scannedString, scanPosition
	if scanPosition >= len(scannedString):
		return False, ''
	for c in chars:
		if scannedString[scanPosition] == c:
			scanPosition += 1
			return True, c
	else:
		return False, ''

# Initialize the sttring to be scanned
def setScannedString(string):
	global scannedString, scanPosition
	scannedString = string
	scanPosition = 0
	
# Set the content of variable 'var' to x
def setVariable(var, x):
	global memory
	memory[var] = x
	
# Get the content of variable 'var'
def getVariable(var):
	global memory
	return memory[var]
	
memory = {}

# Main part of the program
print "(Type q to quit)"
while True:
	input = raw_input("> ")		# Prompt user for input
	if input[:1] == 'q':
		break					# Stop if user types 'q'
	elif len(input) > 0:		# If user typed something
		setScannedString(input)
		scanCommand()
Zur Vorlage gehört folgender abstrakter Code:
< command > = < expression > ;
< expression > = < factor >
| < expression > ‘+’ < factor >
| < expression > ‘−’ < factor > ;
< factor > = < number > ;
< number > = ( ‘0’ | ‘1’ | ‘2’ | ‘3’ | . . . | ‘9’ )+ ;
(

Verfasst: Freitag 6. November 2009, 18:18
von ms4py
Hab da mal was gebastelt mit ``ast``.
Hilft zwar nicht konkret bei deiner Implementierung, trotzdem mal zur Info.
http://www.python-forum.de/viewtopic.php?p=147443 (ziemlich unten)

P.S. Lager bitte nächstes Mal so großen Code aus, z.B. http://paste.pocoo.org

Edit: Sehr komischer Code, ich würde den neu machen, damit kannst du bestimmt punkten ;) "sma" hat da mal schon eine vernünftige Vorlage geliefert, konnte es auf die Schnelle aber nicht finden...

Verfasst: Samstag 7. November 2009, 09:49
von sma
Wie üblich bei Hausaufgaben nehme ich 10% der Punkte. Ich bitte den Lehrer dis bei der Bewertung zu berücksichtigen :)

Code: Alles auswählen

def scanFactor(): # ideomatisches Python nutzt "_" und kein CamelCase
    "scan <factor> | '(' <expression> ')' | <variable>"
    global scanPosition # manchmal, wie in diesem Fall, wären Objekte besser als Funktionen
    ok, x = scanNumber() # ich glaube, ein Option-Typ wäre hier einfacher
    if ok:
        return ok, x # denn jetzt muss man hier wieder tupel bauen
    lastPosition = scanPosition # manuell es backtracking... nun ja
    while True: # etwas verdrehte Logik, aber des einen while/break is des anderen goto
        ok, _ = scanChar('(')
        if not ok: break
        ok, x = scanExpression()
        if not ok: break
        ok, _ = scanChar(')')
        if not ok: break
        return ok, x
    scanPosition = lastPosition
    return scanVariable()
Stefan

Verfasst: Montag 9. November 2009, 18:22
von mrlova
sma hat geschrieben:Wie üblich bei Hausaufgaben nehme ich 10% der Punkte. Ich bitte den Lehrer dis bei der Bewertung zu berücksichtigen :)

Code: Alles auswählen

def scanFactor(): # ideomatisches Python nutzt "_" und kein CamelCase
    "scan <factor> | '(' <expression> ')' | <variable>"
    global scanPosition # manchmal, wie in diesem Fall, wären Objekte besser als Funktionen
    ok, x = scanNumber() # ich glaube, ein Option-Typ wäre hier einfacher
    if ok:
        return ok, x # denn jetzt muss man hier wieder tupel bauen
    lastPosition = scanPosition # manuell es backtracking... nun ja
    while True: # etwas verdrehte Logik, aber des einen while/break is des anderen goto
        ok, _ = scanChar('(')
        if not ok: break
        ok, x = scanExpression()
        if not ok: break
        ok, _ = scanChar(')')
        if not ok: break
        return ok, x
    scanPosition = lastPosition
    return scanVariable()
Stefan

Und der Rest was ich programmiert habe stimmt? Oder gibt es auch noch Fehler drinnen?

Verfasst: Mittwoch 11. November 2009, 10:28
von sma
mrlova hat geschrieben:Und der Rest was ich programmiert habe stimmt? Oder gibt es auch noch Fehler drinnen?
Keine Ahnung, habe ich nicht ausprobiert. Läuft's denn?

Stefan