Signed-off-by: Izuru Yakumo <yakumo.izuru@chaotic.ninja> git-svn-id: file:///srv/svn/repo/aya/trunk@67 cec141ff-132a-4243-88a5-ce187bd62f94
116 lines
2.0 KiB
Go
116 lines
2.0 KiB
Go
package gcss
|
|
|
|
import "strings"
|
|
|
|
// Special characters
|
|
const (
|
|
cr = "\r"
|
|
lf = "\n"
|
|
crlf = "\r\n"
|
|
space = " "
|
|
colon = ":"
|
|
comma = ","
|
|
openBrace = "{"
|
|
closeBrace = "}"
|
|
semicolon = ";"
|
|
ampersand = "&"
|
|
atMark = "@"
|
|
dollarMark = "$"
|
|
openParenthesis = "("
|
|
closeParenthesis = ")"
|
|
slash = "/"
|
|
doubleSlash = slash + slash
|
|
)
|
|
|
|
// parse parses the string, generates the elements
|
|
// and returns the two channels: the first one returns
|
|
// the generated elements and the last one returns
|
|
// an error when it occurs.
|
|
func parse(lines []string) (<-chan element, <-chan error) {
|
|
elemc := make(chan element, len(lines))
|
|
errc := make(chan error)
|
|
|
|
go func() {
|
|
i := 0
|
|
l := len(lines)
|
|
|
|
for i < l {
|
|
// Fetch a line.
|
|
ln := newLine(i+1, lines[i])
|
|
i++
|
|
|
|
// Ignore the empty line.
|
|
if ln.isEmpty() {
|
|
continue
|
|
}
|
|
|
|
if ln.isTopIndent() {
|
|
elem, err := newElement(ln, nil)
|
|
|
|
if err != nil {
|
|
errc <- err
|
|
return
|
|
}
|
|
|
|
if err := appendChildren(elem, lines, &i, l); err != nil {
|
|
errc <- err
|
|
return
|
|
}
|
|
|
|
elemc <- elem
|
|
}
|
|
}
|
|
|
|
close(elemc)
|
|
}()
|
|
|
|
return elemc, errc
|
|
}
|
|
|
|
// appendChildren parses the lines and appends the child elements
|
|
// to the parent element.
|
|
func appendChildren(parent element, lines []string, i *int, l int) error {
|
|
for *i < l {
|
|
// Fetch a line.
|
|
ln := newLine(*i+1, lines[*i])
|
|
|
|
// Ignore the empty line.
|
|
if ln.isEmpty() {
|
|
*i++
|
|
return nil
|
|
}
|
|
|
|
ok, err := ln.childOf(parent)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if !ok {
|
|
return nil
|
|
}
|
|
|
|
child, err := newElement(ln, parent)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
parent.AppendChild(child)
|
|
|
|
*i++
|
|
|
|
if err := appendChildren(child, lines, i, l); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// formatLF replaces the line feed codes with LF and
|
|
// returns the result string.
|
|
func formatLF(s string) string {
|
|
return strings.Replace(strings.Replace(s, crlf, lf, -1), cr, lf, -1)
|
|
}
|