Simple Tag Parser
Haskell, 111 characters
s@(d:z)§c|c>'^'=toEnum(fromEnum c-32):s++'(':[c]|d<'='=s|d==c=z++")"|1<3=(z++")")§c
p=tail.foldl(§)"$".(++"$")
This one's pretty golf'd for Haskell. Fun feature: The stack and the accumulating output are kept in the same string!
Test cases:
> 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))
- Edit: (113 → 111) used an
@
pattern as suggested by FUZxxl
Z80 Machine Code for TI-83+, 41 bytes
This is an implementation in hexadecimal machine code for a z80 cpu running on a TI-83+.
11XXXX131AFE61380F6FE53E28CD9DB47DCD9DB4188EE1BDC03E29CD9DB4189BEF4504E5214CE1C9
The XXXX (3 - 6 inclusive) is the 16-bit address of the string you are parsing, minus 1 byte.
Encoded in Z80-ASCII:
¹XX≤¯•⟙8o↥>(ˣïÑ}ˣïÑ≠á↑γ∊>)ˣïÑ≠Ì⬆︎E↥!₄L↑Φ
(Approximate, because TI calculators have their own character set.)
NOTE THAT THE AsmPrgm
IS NOT INCLUDED IN THE ABOVE
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"}})}
Some things to note: This is just a script block. It can be assigned to a variable or given a function name, if necessary. You can also run it by putting .
or &
in front of it and the arguments at the end. Uses a final space to terminate unclosed tags.
Passes all tests. Test script:
$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]]
}