CSci 150: Foundations of computer science I
Home Syllabus Assignments Tests

Random sentence template

[Assignment text]

import os
import random
import re

grammar = {}

# Returns a string randomly generated from the grammar, using 'symbol' as
# the starting symbol.

def generate(symbol):
    return '' # replace this line with your solution

#
# You should not modify any code below this point.
#

# Loads a grammar from the indicated filename into the global variable
# 'grammar', returning the start symbol for the grammar.

def load_grammar(filename):
    fin = open(filename)
    contents = fin.read()
    fin.close()

    start_symbol = ''
    for rule in re.findall(r'\{[^}]*\}', contents):
        rule = rule[1:len(rule) - 1].strip()
        rule = re.sub(r'[ \t\r\n]+', ' ', rule)
        found = re.search(r'<[^>]*>', rule)
        if found == None or found.start() != 0:
            print 'error: rule does not start with a symbol'
        elif found.group() in grammar:
            print 'error: symbol', found.group(), 'previously defined'
        else:
            symbol = found.group()
            rest = rule[found.end():].strip()
            options = re.split(' *; *', rest)
            if len(options) > 0 and options[-1] == '':
                options = options[:-1]
            if len(options) == 0:
                print 'error: symbol does not have expansion'
            grammar[symbol] = options
            if start_symbol == '':
                start_symbol = symbol
    return start_symbol

# Returns a string that contains basically the same characters as 'string'
# except some spaces are replaced line breaks so that no line contains more
# than 'columns' characters.

def wrap_lines(string, columns):
    lines = []
    remaining = string.strip()
    while len(remaining) > columns:
        index = remaining.rfind('\n', 0, columns)
        if index < 0:
            index = remaining.rfind(' ', 0, columns)
        if index < 0:
            index = columns
        lines.append(remaining[:index].strip())
        remaining = remaining[index + 1:].strip()
    if remaining != '':
        lines.append(remaining)
    return '\n'.join(lines)

def run():
    filename = raw_input('Grammar filename: ')
    while not os.access(filename, os.R_OK):
        print 'File', filename, 'is not available.'
        filename = raw_input('Grammar filename: ')

    start = load_grammar(filename)
    print len(grammar), 'symbols defined'

    again = 'y'
    while again in ['y', 'yes', 'Y']:
        print
        result = generate(start)
        print wrap_lines(result, 80)
        print
        again = raw_input('Generate a new string [y/n]? ')

run()