in src/ct/parser/parser.go [157:232]
func (p *Parser) parseIdentifier() *Item {
n := UnknownItem()
t := p.next()
if t.val == "to" {
n.Set(itemRange, t.val)
return n
}
variable := ""
unit := ""
candidate := t.val
variableMatchCnt := 0
unitMatchCnt := 0
identifierCnt := 0
variableCatalog := variables.Get()
unitCatalog := units.Get()
isIdentifier := true
loop:
for isIdentifier {
identifierCnt++
switch {
case variableCatalog.Match(candidate):
if name, ok := variableCatalog.Get(candidate); ok {
variable = name
variableMatchCnt = identifierCnt
}
fallthrough
case unitCatalog.Match(candidate):
if name, ok := unitCatalog.Get(candidate); ok {
unit = name
unitMatchCnt = identifierCnt
}
default:
break loop
}
t = p.peek(identifierCnt)
if t.typ == tokenLeftParenthesis {
for {
t = p.peek(identifierCnt)
identifierCnt++
if t.typ == tokenRightParenthesis || t.typ == tokenEOF {
break
}
}
if t.typ == tokenRightParenthesis {
t = p.peek(identifierCnt)
}
}
candidate += " " + t.val
isIdentifier = t.typ == tokenIdentifier || t.typ == tokenConjunction || t.typ == tokenSlash
}
switch {
case variableMatchCnt == 0 && unitMatchCnt == 0:
// swallow
case variableMatchCnt < unitMatchCnt:
n.Set(itemUnit, unit)
for i := 1; i < unitMatchCnt; i++ {
p.next()
}
default:
n.Set(itemVariable, variable)
for i := 1; i < variableMatchCnt; i++ {
p.next()
}
}
return n
}