簡體   English   中英

弄清楚如何擴展語法(Python)

[英]Figuring out how to expand a grammar (Python)

我試圖編寫將返回擴展語法的代碼。 所以在這個例子中我將指定長度為3,N = ND將自己擴展為N = NDD然后它將再次擴展到N = NDDD然后退出程序,任何建議實現這一點? 我目前嘗試在printGrammar中執行替換方法但是你可以看到當你運行它時由於某種原因NT(非終端被替換,在這個例子中為N)和item(字典中的值,在本例中為ND和D)不會更換,我留下一個帶有'N'的列表而不是我想要的NDD,有人可以幫助我嗎?

Binary.txt是:

N = N D
N = D
D = 0
D = 1

代碼是

import sys
import string
from collections import defaultdict

#default length of 3
stringLength = 3

#get last argument of command line(file)
if len(sys.argv) == 1:
    #get a length from user
    try:
        stringLength = int(input('Length? '))
        filename = input('Filename: ')
    except ValueError:
        print("Not a number")

elif len(sys.argv) == 2:
    #get a length from user
    try:
        stringLength = int(input('Length? '))
        filename = sys.argv[1]
    except ValueError:
        print("Not a number")

elif len(sys.argv) == 3:
    filename = sys.argv[2]
    stringLength  = sys.argv[1].split('l')[1]
else:
    print("Invalid input!")


#get start symbol
with open(filename, "r") as grammar:
    #read file 
    lines = grammar.readlines()
    start = lines[0].split('=')[0]
    start = start.replace(" ", "")


#checks

#print(stringLength)
#print(filename)
#print(start)
def str2dict(filename):
    result = defaultdict(list)
    with open(filename, "r") as grammar:
        #read file 
        lines = grammar.readlines()
        count = 0

        #loop through
        for line in lines:
            #append info 
            line = line.rstrip()

            result[line[0]].append(line.split('=')[1])

    return result


workingDict = str2dict("Binary.txt")
print(workingDict)


def strings(grammar, start):
    queue = [start]
    while len(queue):
        current = queue.pop(0)
        # for each symbol in the current string
        for n, sym in enumerate(current):
            # if this symbol is a non-terminal
            if sym in grammar:
                # for each rule for this symbol...
                for rhs in grammar[sym]:
                    # replace it with the right part
                    new = current[:n] + rhs + current[n+1:]
                    # does the result contain non-terminals
                    if any(s in grammar for s in new):
                        # yes, place it into the queue
                        queue.append(new)
                    else:
                        # no, return it
                        yield new

for x in strings(workingDict, stringLength):
    print (x)
    if len(x) > 4:
        break

假設你的語法是在形式

grammar = {
    'N': ['ND', 'D'],
    'D': ['0', '1']
}

該算法看起來很簡單:

  • 迭代當前字符串(最初只是一個符號)
  • 如果符號是非終端,則將其替換為其生產
  • 如果結果包含非終端,則將其放入隊列以進行進一步處理
  • 否則,返回結果(這是一串終端)
  • 從隊列頂部選擇下一個“當前”字符串並繼續

def strings(grammar, start):
    queue = [start]
    while len(queue):
        current = queue.pop(0)
        # for each symbol in the current string
        for n, sym in enumerate(current):
            # if this symbol is a non-terminal
            if sym in grammar:
                # for each rule for this symbol...
                for rhs in grammar[sym]:
                    # replace it with the right part
                    new = current[:n] + rhs + current[n+1:]
                    # does the result contain non-terminals
                    if any(s in grammar for s in new):
                        # yes, place it into the queue
                        queue.append(new)
                    else:
                        # no, return it
                        yield new

用法:

for x in strings(grammar, 'N'):
    print x
    if len(x) > 4:
        break

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM