in src/ct/parser/parser.go [62:133]
func (p *Parser) parseSegment(tokenEnd tokenType) List {
list := make(List, 0)
nodes := NewItems()
loop:
for {
switch p.peek(1).typ {
case tokenLeftParenthesis:
p.next()
if tokenEnd == tokenRightParenthesis {
break loop
}
newNodes := p.parseSegment(tokenRightParenthesis)
for i := 0; i < len(newNodes); i++ {
if newNodes[i].Len() == 1 {
// Skip one-token segment which most likely is an abbreviation.
} else {
list = append(list, newNodes[i])
}
}
case tokenIdentifier:
n := p.parseIdentifier()
nodes.Add(n)
case tokenNumber:
if n := p.parseNumber(); n.Valid() {
nodes.Add(n)
}
case tokenUnit:
if n := p.parseUnit(); n.Valid() {
nodes.Add(n)
}
case tokenNegation, tokenComparison, tokenLessComparison, tokenGreaterComparison:
if n := p.parseComparison(); n.Valid() {
nodes.Add(n)
}
case tokenConjunction:
if n := p.parseConjunction(); n.Valid() {
nodes.Add(n)
}
case tokenSlash:
if nodes.LastType() == itemNumber {
// Because a number preceded the slash, these tokens
// may compose to a unit, such as '/ul'.
n := p.parseIdentifier()
nodes.Add(n)
} else {
if n := p.parseSlash(); n.Valid() {
nodes.Add(n)
}
}
case tokenDash:
if n := p.parseDash(); n.Valid() {
nodes.Add(n)
}
case tokenPunctuation:
if n := p.parsePunctuation(); n.Valid() {
nodes.Add(n)
}
case tokenEOF:
break loop
case tokenEnd:
p.next()
break loop
default:
p.next()
}
}
if !nodes.Empty() {
list = append(list, nodes)
}
return list
}