Ok, vì vậy tôi đã hỏi một loạt các câu hỏi nhỏ hơn về dự án này, nhưng tôi vẫn không có nhiều tự tin trong các thiết kế mà tôi sắp đưa ra, vì vậy tôi sẽ đặt một câu hỏi trên quy mô rộng hơn .Cách tốt nhất để phân tích ngữ pháp đơn giản?
Tôi đang phân tích cú pháp mô tả trước khi cần thiết cho danh mục khóa học. Các mô tả hầu như luôn luôn tuân theo một hình thức nhất định, điều đó khiến tôi nghĩ rằng tôi có thể phân tích hầu hết chúng.
Từ văn bản, tôi muốn tạo biểu đồ các mối quan hệ tiền điều kiện tiên quyết. (Phần đó sẽ được dễ dàng, sau khi tôi đã phân tích dữ liệu.)
Một số đầu vào và đầu ra mẫu:
"CS 2110" => ("CS", 2110) # 0
"CS 2110 and INFO 3300" => [("CS", 2110), ("INFO", 3300)] # 1
"CS 2110, INFO 3300" => [("CS", 2110), ("INFO", 3300)] # 1
"CS 2110, 3300, 3140" => [("CS", 2110), ("CS", 3300), ("CS", 3140)] # 1
"CS 2110 or INFO 3300" => [[("CS", 2110)], [("INFO", 3300)]] # 2
"MATH 2210, 2230, 2310, or 2940" => [[("MATH", 2210), ("MATH", 2230), ("MATH", 2310)], [("MATH", 2940)]] # 3
Nếu mô tả toàn bộ chỉ là một khóa học, nó là kết quả trực tiếp.
Nếu khóa học là dính liền ("và"), họ là tất cả đầu ra trong cùng một danh sách
Nếu khóa học được disjoined ("hay"), họ đang có trong danh sách riêng biệt
Ở đây, chúng tôi có cả "và" và "hoặc".
Một caveat mà làm cho nó dễ dàng hơn: có vẻ là làm tổ của cụm từ "và"/"hoặc" không bao giờ lớn hơn như trong ví dụ 3.
cách tốt nhất để làm điều này là gì ? Tôi bắt đầu với PLY, nhưng tôi không thể tìm ra cách giải quyết các xung đột giảm/giảm. Ưu điểm của PLY là nó dễ dàng để thao tác những gì từng quy tắc phân tích cú pháp tạo:
def p_course(p):
'course : DEPT_CODE COURSE_NUMBER'
p[0] = (p[1], int(p[2]))
Với PyParse, đó là chưa rõ ràng làm thế nào để sửa đổi đầu ra của parseString()
. Tôi đang xem xét xây dựng theo ý tưởng của @Alex Martelli về giữ trạng thái trong một đối tượng và xây dựng đầu ra từ đó, nhưng tôi không chắc chắn chính xác cách thực hiện tốt nhất.
def addCourse(self, str, location, tokens):
self.result.append((tokens[0][0], tokens[0][1]))
def makeCourseList(self, str, location, tokens):
dept = tokens[0][0]
new_tokens = [(dept, tokens[0][1])]
new_tokens.extend((dept, tok) for tok in tokens[1:])
self.result.append(new_tokens)
Ví dụ, để xử lý "hoặc" trường hợp:
def __init__(self):
self.result = []
# ...
self.statement = (course_data + Optional(OR_CONJ + course_data)).setParseAction(self.disjunctionCourses)
def disjunctionCourses(self, str, location, tokens):
if len(tokens) == 1:
return tokens
print "disjunction tokens: %s" % tokens
Làm thế nào để biết được disjunctionCourses()
nhỏ cụm từ để disjoin? Tất cả nó được là thẻ, nhưng những gì được phân tích cú pháp cho đến nay được lưu trữ trong result
, vì vậy làm thế nào có thể chức năng cho biết dữ liệu trong result
tương ứng với các yếu tố của token
? Tôi đoán tôi có thể tìm kiếm thông qua các thẻ, sau đó tìm một phần tử của result
với cùng một dữ liệu, nhưng điều đó cảm thấy phức tạp ...
Ngoài ra, có rất nhiều mô tả mà bao gồm văn bản misc, như:
"CS 2110 or permission of instructor"
"INFO 3140 or equivalent experience"
"PYSCH 2210 and sophomore standing"
Nhưng điều quan trọng là tôi phân tích văn bản đó.
Cách nào tốt hơn để tiếp cận vấn đề này?
Việc đánh số trong đầu vào và đầu ra mẫu của bạn không khớp với số trong cuộc thảo luận của bạn về chúng. –