@@ -35,106 +35,113 @@ const EOF rune = -1
3535type LexState interface {
3636 // Run returns the next state to transition to or an error. If the returned
3737 // error is io.EOF then the Lexer finishes processing normally.
38- Run (ctx * CustomLexerContext ) (LexState , error )
38+ Run (ctx context. Context , cursor * CustomLexerCursor ) (LexState , error )
3939}
4040
4141type lexFnState struct {
42- f func (* CustomLexerContext ) (LexState , error )
42+ f func (context. Context , * CustomLexerCursor ) (LexState , error )
4343}
4444
4545// Run implements [LexState.Run].
4646//
4747//nolint:ireturn // Returning interface required to satisfy [LexState.Run]
48- func (s * lexFnState ) Run (ctx * CustomLexerContext ) (LexState , error ) {
49- return s .f (ctx )
48+ func (s * lexFnState ) Run (ctx context. Context , cursor * CustomLexerCursor ) (LexState , error ) {
49+ return s .f (ctx , cursor )
5050}
5151
5252// LexStateFn creates a State from the given Run function.
5353//
5454//nolint:ireturn // Returning interface required to satisfy [LexState.Run]
55- func LexStateFn (f func (* CustomLexerContext ) (LexState , error )) LexState {
55+ func LexStateFn (f func (context. Context , * CustomLexerCursor ) (LexState , error )) LexState {
5656 return & lexFnState {f }
5757}
5858
59- // CustomLexerContext is a context that carries a reference to the current
60- // CustomLexer. It is passed to [LexState.Run] method to allow the state
61- // implementation to interact with the lexer.
62- type CustomLexerContext struct {
63- //nolint:containedctx // Embedding context required for interface compliance.
64- context.Context
65-
59+ // CustomLexerCursor is a type that allows for processing the input for the
60+ // CustomLexer. It provides methods to advance the reader, emit tokens, and
61+ // manage the current token being processed. It is designed to be used within
62+ // the [LexState.Run] method to allow the state implementation to interact with
63+ // the lexer without exposing the full CustomLexer implementation.
64+ type CustomLexerCursor struct {
6665 l * CustomLexer
6766}
6867
68+ // NewCustomLexerCursor creates a new CustomLexerCursor with the given context
69+ // and CustomLexer.
70+ func NewCustomLexerCursor (l * CustomLexer ) * CustomLexerCursor {
71+ return & CustomLexerCursor {
72+ l : l ,
73+ }
74+ }
75+
6976// Advance attempts to advance the underlying reader a single rune and returns
7077// true if actually advanced. The current token cursor position is not updated.
71- func (ctx * CustomLexerContext ) Advance () bool {
72- return ctx .l .advance (1 , false ) == 1
78+ func (c * CustomLexerCursor ) Advance () bool {
79+ return c .l .advance (1 , false ) == 1
7380}
7481
7582// AdvanceN attempts to advance the underlying reader n runes and returns the
7683// number actually advanced. The current token cursor position is not updated.
77- func (ctx * CustomLexerContext ) AdvanceN (n int ) int {
78- return ctx .l .advance (n , false )
84+ func (c * CustomLexerCursor ) AdvanceN (n int ) int {
85+ return c .l .advance (n , false )
7986}
8087
8188// Cursor returns the current position of the underlying cursor marking the
8289// beginning of the current token being processed.
83- func (ctx * CustomLexerContext ) Cursor () Position {
84- return ctx .l .cursor
90+ func (c * CustomLexerCursor ) Cursor () Position {
91+ return c .l .cursor
8592}
8693
8794// Discard attempts to discard the next rune, advancing the current token
8895// cursor, and returns true if actually discarded.
89- func (ctx * CustomLexerContext ) Discard () bool {
90- return ctx .l .advance (1 , true ) == 1
96+ func (c * CustomLexerCursor ) Discard () bool {
97+ return c .l .advance (1 , true ) == 1
9198}
9299
93100// DiscardN attempts to discard n runes, advancing the current token cursor
94101// position, and returns the number actually discarded.
95- func (ctx * CustomLexerContext ) DiscardN (n int ) int {
96- return ctx .l .advance (n , true )
102+ func (c * CustomLexerCursor ) DiscardN (n int ) int {
103+ return c .l .advance (n , true )
97104}
98105
99106// DiscardTo searches the input for one of the given search strings, advancing
100107// the reader, and stopping when one of the strings is found. The token cursor
101108// is advanced and data prior to the search string is discarded. The string
102109// found is returned. If no match is found an empty string is returned.
103- func (ctx * CustomLexerContext ) DiscardTo (query []string ) string {
104- return ctx .l .discardTo (query )
110+ func (c * CustomLexerCursor ) DiscardTo (query []string ) string {
111+ return c .l .discardTo (query )
105112}
106113
107114// Emit emits the token between the current cursor position and reader
108115// position and returns the token. If the lexer is not currently active, this
109116// is a no-op. This advances the current token cursor.
110- func (ctx * CustomLexerContext ) Emit (typ TokenType ) * Token {
111- return ctx .l .emit (typ )
117+ func (c * CustomLexerCursor ) Emit (typ TokenType ) * Token {
118+ return c .l .emit (typ )
112119}
113120
114121// Find searches the input for one of the given search strings, advancing the
115122// reader, and stopping when one of the strings is found. The token cursor is
116123// not advanced. The string found is returned. If no match is found an empty
117124// string is returned.
118- func (ctx * CustomLexerContext ) Find (query []string ) string {
119- return ctx .l .find (query )
125+ func (c * CustomLexerCursor ) Find (query []string ) string {
126+ return c .l .find (query )
120127}
121128
122129// Ignore ignores the previous input and resets the token start position to
123130// the current reader position.
124- func (ctx * CustomLexerContext ) Ignore () {
125- ctx .l .ignore ()
131+ func (c * CustomLexerCursor ) Ignore () {
132+ c .l .ignore ()
126133}
127134
128135// NextRune returns the next rune of input, advancing the reader while not
129136// advancing the token cursor.
130- func (ctx * CustomLexerContext ) NextRune () rune {
131- return ctx .l .nextRune ()
137+ func (c * CustomLexerCursor ) NextRune () rune {
138+ return c .l .nextRune ()
132139}
133140
134141// Peek returns the next rune from the buffer without advancing the reader or
135142// current token cursor.
136- func (ctx * CustomLexerContext ) Peek () rune {
137- p := ctx .PeekN (1 )
143+ func (c * CustomLexerCursor ) Peek () rune {
144+ p := c .PeekN (1 )
138145 if len (p ) < 1 {
139146 return EOF
140147 }
@@ -145,24 +152,24 @@ func (ctx *CustomLexerContext) Peek() rune {
145152// PeekN returns the next n runes from the buffer without advancing the reader
146153// or current token cursor. PeekN may return fewer runes than requested if an
147154// error occurs or at end of input.
148- func (ctx * CustomLexerContext ) PeekN (n int ) []rune {
149- return ctx .l .peekN (n )
155+ func (c * CustomLexerCursor ) PeekN (n int ) []rune {
156+ return c .l .peekN (n )
150157}
151158
152159// Pos returns the current position of the underlying reader.
153- func (ctx * CustomLexerContext ) Pos () Position {
154- return ctx .l .pos
160+ func (c * CustomLexerCursor ) Pos () Position {
161+ return c .l .pos
155162}
156163
157164// Token returns the current token value.
158- func (ctx * CustomLexerContext ) Token () string {
159- return ctx .l .b .String ()
165+ func (c * CustomLexerCursor ) Token () string {
166+ return c .l .b .String ()
160167}
161168
162169// Width returns the current width of the token being processed. It is
163170// equivalent to l.Pos().Offset - l.Cursor().Offset.
164- func (ctx * CustomLexerContext ) Width () int {
165- return ctx .l .pos .Offset - ctx .l .cursor .Offset
171+ func (c * CustomLexerCursor ) Width () int {
172+ return c .l .pos .Offset - c .l .cursor .Offset
166173}
167174
168175// CustomLexer lexically processes a byte stream. It is implemented as a
@@ -240,10 +247,7 @@ func (l *CustomLexer) NextToken(ctx context.Context) *Token {
240247 return l .newToken (TokenTypeEOF )
241248 }
242249
243- lexerCtx := & CustomLexerContext {
244- Context : ctx ,
245- l : l ,
246- }
250+ cursor := NewCustomLexerCursor (l )
247251
248252 // If we have no tokens to return, we need to run the current state.
249253 for len (l .buf ) == 0 && l .state != nil {
@@ -258,7 +262,7 @@ func (l *CustomLexer) NextToken(ctx context.Context) *Token {
258262
259263 var err error
260264
261- l .state , err = l .state .Run (lexerCtx )
265+ l .state , err = l .state .Run (ctx , cursor )
262266 l .setErr (err )
263267
264268 if l .err != nil {
0 commit comments