type item … func (i item) String() string { … } type itemType … const itemError … const itemBool … const itemChar … const itemCharConstant … const itemComment … const itemComplex … const itemAssign … const itemDeclare … const itemEOF … const itemField … const itemIdentifier … const itemLeftDelim … const itemLeftParen … const itemNumber … const itemPipe … const itemRawString … const itemRightDelim … const itemRightParen … const itemSpace … const itemString … const itemText … const itemVariable … const itemKeyword … const itemBlock … const itemBreak … const itemContinue … const itemDot … const itemDefine … const itemElse … const itemEnd … const itemIf … const itemNil … const itemRange … const itemTemplate … const itemWith … var key … const eof … const spaceChars … const trimMarker … const trimMarkerLen … type stateFn … type lexer … type lexOptions … // next returns the next rune in the input. func (l *lexer) next() rune { … } // peek returns but does not consume the next rune in the input. func (l *lexer) peek() rune { … } // backup steps back one rune. func (l *lexer) backup() { … } // thisItem returns the item at the current input point with the specified type // and advances the input. func (l *lexer) thisItem(t itemType) item { … } // emit passes the trailing text as an item back to the parser. func (l *lexer) emit(t itemType) stateFn { … } // emitItem passes the specified item to the parser. func (l *lexer) emitItem(i item) stateFn { … } // ignore skips over the pending input before this point. // It tracks newlines in the ignored text, so use it only // for text that is skipped without calling l.next. func (l *lexer) ignore() { … } // accept consumes the next rune if it's from the valid set. func (l *lexer) accept(valid string) bool { … } // acceptRun consumes a run of runes from the valid set. func (l *lexer) acceptRun(valid string) { … } // errorf returns an error token and terminates the scan by passing // back a nil pointer that will be the next state, terminating l.nextItem. func (l *lexer) errorf(format string, args ...any) stateFn { … } // nextItem returns the next item from the input. // Called by the parser, not in the lexing goroutine. func (l *lexer) nextItem() item { … } // lex creates a new scanner for the input string. func lex(name, input, left, right string) *lexer { … } const leftDelim … const rightDelim … const leftComment … const rightComment … // lexText scans until an opening action delimiter, "{{". func lexText(l *lexer) stateFn { … } // rightTrimLength returns the length of the spaces at the end of the string. func rightTrimLength(s string) Pos { … } // atRightDelim reports whether the lexer is at a right delimiter, possibly preceded by a trim marker. func (l *lexer) atRightDelim() (delim, trimSpaces bool) { … } // leftTrimLength returns the length of the spaces at the beginning of the string. func leftTrimLength(s string) Pos { … } // lexLeftDelim scans the left delimiter, which is known to be present, possibly with a trim marker. // (The text to be trimmed has already been emitted.) func lexLeftDelim(l *lexer) stateFn { … } // lexComment scans a comment. The left comment marker is known to be present. func lexComment(l *lexer) stateFn { … } // lexRightDelim scans the right delimiter, which is known to be present, possibly with a trim marker. func lexRightDelim(l *lexer) stateFn { … } // lexInsideAction scans the elements inside action delimiters. func lexInsideAction(l *lexer) stateFn { … } // lexSpace scans a run of space characters. // We have not consumed the first space, which is known to be present. // Take care if there is a trim-marked right delimiter, which starts with a space. func lexSpace(l *lexer) stateFn { … } // lexIdentifier scans an alphanumeric. func lexIdentifier(l *lexer) stateFn { … } // lexField scans a field: .Alphanumeric. // The . has been scanned. func lexField(l *lexer) stateFn { … } // lexVariable scans a Variable: $Alphanumeric. // The $ has been scanned. func lexVariable(l *lexer) stateFn { … } // lexFieldOrVariable scans a field or variable: [.$]Alphanumeric. // The . or $ has been scanned. func lexFieldOrVariable(l *lexer, typ itemType) stateFn { … } // atTerminator reports whether the input is at valid termination character to // appear after an identifier. Breaks .X.Y into two pieces. Also catches cases // like "$x+2" not being acceptable without a space, in case we decide one // day to implement arithmetic. func (l *lexer) atTerminator() bool { … } // lexChar scans a character constant. The initial quote is already // scanned. Syntax checking is done by the parser. func lexChar(l *lexer) stateFn { … } // lexNumber scans a number: decimal, octal, hex, float, or imaginary. This // isn't a perfect number scanner - for instance it accepts "." and "0x0.2" // and "089" - but when it's wrong the input is invalid and the parser (via // strconv) will notice. func lexNumber(l *lexer) stateFn { … } func (l *lexer) scanNumber() bool { … } // lexQuote scans a quoted string. func lexQuote(l *lexer) stateFn { … } // lexRawQuote scans a raw quoted string. func lexRawQuote(l *lexer) stateFn { … } // isSpace reports whether r is a space character. func isSpace(r rune) bool { … } // isAlphaNumeric reports whether r is an alphabetic, digit, or underscore. func isAlphaNumeric(r rune) bool { … } func hasLeftTrimMarker(s string) bool { … } func hasRightTrimMarker(s string) bool { … }