scanner: change API for a better usage

This commit is contained in:
Fatih Arslan 2015-10-06 19:03:32 +03:00
parent 62a4ab3db7
commit da40013062
2 changed files with 15 additions and 10 deletions

View File

@ -46,7 +46,7 @@ type Scanner struct {
// If an error is reported (via Error) and Position is invalid, // If an error is reported (via Error) and Position is invalid,
// the scanner is not inside a token. Call Pos to obtain an error // the scanner is not inside a token. Call Pos to obtain an error
// position in that case. // position in that case.
Position tokPos Position
} }
// NewScanner returns a new instance of Lexer. Even though src is an io.Reader, // NewScanner returns a new instance of Lexer. Even though src is an io.Reader,
@ -138,17 +138,17 @@ func (s *Scanner) Scan() (tok token.Token) {
// token position, initial next() is moving the offset by one(size of rune // token position, initial next() is moving the offset by one(size of rune
// actually), though we are interested with the starting point // actually), though we are interested with the starting point
s.Position.Offset = s.srcPos.Offset - s.lastCharLen s.tokPos.Offset = s.srcPos.Offset - s.lastCharLen
if s.srcPos.Column > 0 { if s.srcPos.Column > 0 {
// common case: last character was not a '\n' // common case: last character was not a '\n'
s.Position.Line = s.srcPos.Line s.tokPos.Line = s.srcPos.Line
s.Position.Column = s.srcPos.Column s.tokPos.Column = s.srcPos.Column
} else { } else {
// last character was a '\n' // last character was a '\n'
// (we cannot be at the beginning of the source // (we cannot be at the beginning of the source
// since we have called next() at least once) // since we have called next() at least once)
s.Position.Line = s.srcPos.Line - 1 s.tokPos.Line = s.srcPos.Line - 1
s.Position.Column = s.lastLineLen s.tokPos.Column = s.lastLineLen
} }
switch { switch {
@ -446,9 +446,14 @@ func (s *Scanner) TokenText() string {
return s.tokBuf.String() return s.tokBuf.String()
} }
// Pos returns the position of the character immediately after the character or // Pos returns the successful position of the most recently scanned token.
// token returned by the last call to Scan.
func (s *Scanner) Pos() (pos Position) { func (s *Scanner) Pos() (pos Position) {
return s.tokPos
}
// recentPosition returns the position of the character immediately after the
// character or token returned by the last call to Scan.
func (s *Scanner) recentPosition() (pos Position) {
pos.Offset = s.srcPos.Offset - s.lastCharLen pos.Offset = s.srcPos.Offset - s.lastCharLen
switch { switch {
case s.srcPos.Column > 0: case s.srcPos.Column > 0:
@ -473,7 +478,7 @@ func (s *Scanner) Pos() (pos Position) {
// not defined, by default it prints them to os.Stderr // not defined, by default it prints them to os.Stderr
func (s *Scanner) err(msg string) { func (s *Scanner) err(msg string) {
s.ErrorCount++ s.ErrorCount++
pos := s.Pos() pos := s.recentPosition()
if s.Error != nil { if s.Error != nil {
s.Error(pos, msg) s.Error(pos, msg)

View File

@ -195,7 +195,7 @@ func TestPosition(t *testing.T) {
for _, listName := range orderedTokenLists { for _, listName := range orderedTokenLists {
for _, k := range tokenLists[listName] { for _, k := range tokenLists[listName] {
curPos := s.Position curPos := s.tokPos
// fmt.Printf("[%q] s = %+v:%+v\n", k.text, curPos.Offset, curPos.Column) // fmt.Printf("[%q] s = %+v:%+v\n", k.text, curPos.Offset, curPos.Column)
if curPos.Offset != pos.Offset { if curPos.Offset != pos.Offset {