func()

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
}