Trình phân tích thẻ đơn giản


9

Đây là mô hình của trình phân tích cú pháp HTML dễ tha thứ. Thay vì phân tích cú pháp HTML và trích xuất các thuộc tính, trong mã golf này, trình phân tích cú pháp thẻ sẽ đơn giản.

Viết hàm phân tích cấu trúc thẻ và trả về dạng cha mẹ của nó. Thẻ mở bao gồm một chữ cái viết thường và thẻ đóng bao gồm một chữ cái viết hoa. Ví dụ: aAbaABphân tích cú pháp thành (a)(b(a))hoặc trong HTML , <a></a><b><a></a></b>. Tất nhiên, các thẻ có thể ở vị trí kề nhau và lồng nhau.

Các thẻ đóng "sớm" phải được xử lý. Ví dụ, trong abcA, Ađóng ngoài cùng a, vì vậy nó phân tích thành (a(b(c))).

Các thẻ đóng thêm chỉ đơn giản là bị bỏ qua: aABphân tích thành (a).

Thẻ chồng chéo KHÔNG được xử lý. Ví dụ: abABphân tích cú pháp thành (a(b)), không (a(b))(b), theo quy tắc trước đó của các thẻ đóng thêm ( abAB-> abA( (a(b))) + B(thêm)).

Giả sử không có khoảng trắng và các ký tự không hợp lệ khác trong đầu vào.

Bạn không được phép sử dụng bất kỳ thư viện.

Dưới đây là một triển khai tham khảo và một danh sách các trường hợp thử nghiệm:

#!/usr/bin/python

def pars(inpu):
  outp = ""
  stac = []
  i = 0
  for x in inpu:
    lowr = x.lower()
    if x == lowr:
      stac.append(x)
      outp += "(" + x
      i = i + 1
    else:
      while len(stac) > 1 and stac[len(stac) - 1] != lowr:
        outp += ")"
        stac.pop()
        i = i - 1
      if len(stac) > 0:
        outp += ")"
        stac.pop()
        i = i - 1
  outp += ")" * i
  return outp

tests = [
  ("aAaAbB", "(a)(a)(b)"),
  ("abBcdDCA", "(a(b)(c(d)))"),
  ("bisSsIB", "(b(i(s)(s)))"),
  ("aAabc", "(a)(a(b(c)))"),
  ("abcdDA", "(a(b(c(d))))"),
  ("abcAaA", "(a(b(c)))(a)"),
  ("acAC", "(a(c))"),
  ("ABCDEFG", ""),
  ("AbcBCabA", "(b(c))(a(b))")
]

for case, expe in tests:
  actu = pars(case)
  print "%s: C: [%s] E: [%s] A: [%s]" % (["FAIL", "PASS"][expe == actu], case, expe, actu)

Mã ngắn nhất sẽ thắng.


Giống như bất kỳ sân golf mã nào khác, thư viện tiêu chuẩn được phép
Ming-Tang

không giới hạn về chiều dài cũng như mức độ làm tổ
Ming-Tang

4
Bạn nên thêm trường hợp kiểm tra cho đầu vào có thẻ đóng, chẳng hạn như AbcBCabA(nên phân tích thành (b(c))(a(b)). Mã của tôi có thể ngắn hơn ngoại trừ trường hợp này.
MtnViewMark

Câu trả lời:


1

Golfscript, 54 ký tự

{[]:|\{.96>{.|+:|;40\}{32+|?).')'*\|>:|;}if}%|,')'*}:$

Xét nghiệm

;["aAaAbB" "abBcdDCA" "bisSsIB" "aAabc" "abcdDA" "abcAaA" "acAC" "aAB" "abAB" "AbcBCabA"]{.' '\$n}%

aAaAbBaAaAbB (a)(a)(b)
abBcdDCA (a(b)(c(d)))
bisSsIB (b(i(s)(s)))
aAabc (a)(a(b(c)))
abcdDA (a(b(c(d))))
abcAaA (a(b(c)))(a)
acAC (a(c))
aAB (a)
abAB (a(b))
AbcBCabA (b(c))(a(b))

6

Haskell, 111 ký tự

s@(d:z)§c|c>'^'=toEnum(fromEnum c-32):s++'(':[c]|d<'='=s|d==c=z++")"|1<3=(z++")")§c
p=tail.foldl(§)"$".(++"$")

Đây là một golf đẹp cho Haskell. Tính năng thú vị: Ngăn xếp và đầu ra tích lũy được giữ trong cùng một chuỗi!

Các trường hợp thử nghiệm:

> runTests 
Pass: aAbaAB parsed correctly as (a)(b(a))
Pass: abcA parsed correctly as (a(b(c)))
Pass: aAB parsed correctly as (a)
Pass: abAB parsed correctly as (a(b))
Pass: aAaAbB parsed correctly as (a)(a)(b)
Pass: abBcdDCA parsed correctly as (a(b)(c(d)))
Pass: bisSsIB parsed correctly as (b(i(s)(s)))
Pass: aAabc parsed correctly as (a)(a(b(c)))
Pass: abcdDA parsed correctly as (a(b(c(d))))
Pass: abcAaA parsed correctly as (a(b(c)))(a)
Pass: acAC parsed correctly as (a(c))
Pass: AbcBCabA parsed correctly as (b(c))(a(b))

  • Chỉnh sửa: (113 → 111) đã sử dụng một @mẫu theo đề xuất của FUZxxl

Sử dụng một mô hình @ cho d: z có thể lưu hai ký tự.
FUZxxl

4

Mã máy Z80 cho TI-83 +, 41 byte

Đây là một triển khai trong mã máy thập lục phân cho cpu z80 chạy trên TI-83 +.

11XXXX131AFE61380F6FE53E28CD9DB47DCD9DB4188EE1BDC03E29CD9DB4189BEF4504E5214CE1C9

XXXX (đã bao gồm 3 - 6) là địa chỉ 16 bit của chuỗi bạn đang phân tích cú pháp, trừ đi 1 byte.

Được mã hóa trong Z80-ASCII:

¹XX≤¯•⟙8𝑭o↥>(ˣïÑ}ˣïÑ≠á↑γ∊>)ˣïÑ≠Ì⬆︎E𝑤↥!₄L↑Φ

(Gần đúng, vì máy tính TI có bộ ký tự riêng.)

LƯU Ý R ISNG AsmPrgmKHÔNG BAO GỒM Ở TRÊN


2

Windows PowerShell, 142 146 147 152 156 169

{$s=''
-join([char[]]"$args "|%{if(90-ge$_){')'*(($x=$s.indexOf("$_".ToLower())+1)+$s.Length*!$x)
$s=$s.substring($x)}else{"($_"
$s="$_$s"}})}

Một số điều cần lưu ý: Đây chỉ là một khối kịch bản. Nó có thể được gán cho một biến hoặc được đặt tên hàm, nếu cần thiết. Bạn cũng có thể chạy nó bằng cách đặt .hoặc &ở phía trước của nó và các đối số ở cuối. Sử dụng một không gian cuối cùng để chấm dứt các thẻ không được tiết lộ.

Vượt qua tất cả các bài kiểm tra. Kịch bản thử nghiệm:

$tests = ("aAaAbB","(a)(a)(b)"),("abBcdDCA","(a(b)(c(d)))"),("bisSsIB","(b(i(s)(s)))"),("aAabc","(a)(a(b(c)))"),("abcdDA","(a(b(c(d))))"),("abcAaA", "(a(b(c)))(a)"),("acAC","(a(c))")
"function f " + ((gc ./tags.ps1)-join"`n") | iex
$tests | %{
    $result = f $_[0]
    ("FAIL: $($_[0]):$($_[1]) - $result", 'PASS')[$result -ceq $_[1]]
}

2

Python - 114 113 153 192 174 159 ký tự

from sys import *
s="";c=a=argv[1]
for f in a:
 o=c.find;p=f.lower
 if '@'<f<'\\':
\td=o(f)-o(p())
\ts+=")"*d
\tc=(c[:o(p())]+c[o(f)+1:])
 else:s+=("("+f)
print s

Lạm dụng trình phân tích cú pháp thụt đầu dòng của python để sử dụng một khoảng trắng cho một tab đầy đủ, năm cho hai tab.

Chỉnh sửa 1 - đã lưu một không gian không cần thiết trong hàm phạm vi ()

Chỉnh sửa 2 - cố định để xử lý các ngữ pháp phân tích cú pháp không đúng, các thẻ bị lỗi.

Chỉnh sửa 3 - đã sửa một lỗi trong đó các phân tích "không chính xác" có thể được tạo bởi sự không rõ ràng trong cây thẻ. Thực hiện chiến lược dựa trên ngăn xếp, thay vì truy cập.

Chỉnh sửa 4 - đổi tên s.find thành o để ngăn lưu các ký tự được sử dụng để gọi nó nhiều lần. đã làm tương tự cho f.lower.

Chỉnh sửa 5 - thêm hack không gian / tab, lưu ba ký tự.

Chỉnh sửa 6 - bỏ vòng lặp có lợi cho ")" * d.


1
thay vì ord(f)...bạn có thể sử dụng '@'<f<'\\'Nếu bạn không cần kiểm tra, '\\'bạn có thể sử dụng ']'thay thế
gnibbler

1
bạn có thể sử dụng một tab duy nhất thay vì 5 dấu cách. Đánh dấu mã SO không thể xử lý mặc dù :(. Trong trường hợp của bạn, chỉ cần bỏ hoàn toàn dòng mới và khoảng trắng, ví dụ if ...:s+=")";c-=1else:s+="("+f;c+=1
gnibbler

1
for i in range(d):s+=")"có thể được viết lại như s+=")"*d. Và bạn có 174 ký tự.
cemper93

@cemper - Điểm hay đó. Tôi làm "_" * 80 cả ngày và quên nó khi chơi golf .... Ngoài ra, cảm ơn @gnibbler vì những gợi ý!
arthem

Thực ra, tôi có nghĩa là bạn đã có 174 ký tự trước . Vì vậy, bạn đang ở mức 159 bây giờ.
cemper93
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.