mirror of
https://github.com/ceph/ceph-csi.git
synced 2024-12-24 05:50:22 +00:00
158 lines
3.7 KiB
Go
158 lines
3.7 KiB
Go
|
// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
|
||
|
// Use of this file is governed by the BSD 3-clause license that
|
||
|
// can be found in the LICENSE.txt file in the project root.
|
||
|
|
||
|
package antlr
|
||
|
|
||
|
import (
|
||
|
"bufio"
|
||
|
"io"
|
||
|
)
|
||
|
|
||
|
type InputStream struct {
|
||
|
name string
|
||
|
index int
|
||
|
data []rune
|
||
|
size int
|
||
|
}
|
||
|
|
||
|
// NewIoStream creates a new input stream from the given io.Reader reader.
|
||
|
// Note that the reader is read completely into memory and so it must actually
|
||
|
// have a stopping point - you cannot pass in a reader on an open-ended source such
|
||
|
// as a socket for instance.
|
||
|
func NewIoStream(reader io.Reader) *InputStream {
|
||
|
|
||
|
rReader := bufio.NewReader(reader)
|
||
|
|
||
|
is := &InputStream{
|
||
|
name: "<empty>",
|
||
|
index: 0,
|
||
|
}
|
||
|
|
||
|
// Pre-build the buffer and read runes reasonably efficiently given that
|
||
|
// we don't exactly know how big the input is.
|
||
|
//
|
||
|
is.data = make([]rune, 0, 512)
|
||
|
for {
|
||
|
r, _, err := rReader.ReadRune()
|
||
|
if err != nil {
|
||
|
break
|
||
|
}
|
||
|
is.data = append(is.data, r)
|
||
|
}
|
||
|
is.size = len(is.data) // number of runes
|
||
|
return is
|
||
|
}
|
||
|
|
||
|
// NewInputStream creates a new input stream from the given string
|
||
|
func NewInputStream(data string) *InputStream {
|
||
|
|
||
|
is := &InputStream{
|
||
|
name: "<empty>",
|
||
|
index: 0,
|
||
|
data: []rune(data), // This is actually the most efficient way
|
||
|
}
|
||
|
is.size = len(is.data) // number of runes, but we could also use len(data), which is efficient too
|
||
|
return is
|
||
|
}
|
||
|
|
||
|
func (is *InputStream) reset() {
|
||
|
is.index = 0
|
||
|
}
|
||
|
|
||
|
// Consume moves the input pointer to the next character in the input stream
|
||
|
func (is *InputStream) Consume() {
|
||
|
if is.index >= is.size {
|
||
|
// assert is.LA(1) == TokenEOF
|
||
|
panic("cannot consume EOF")
|
||
|
}
|
||
|
is.index++
|
||
|
}
|
||
|
|
||
|
// LA returns the character at the given offset from the start of the input stream
|
||
|
func (is *InputStream) LA(offset int) int {
|
||
|
|
||
|
if offset == 0 {
|
||
|
return 0 // nil
|
||
|
}
|
||
|
if offset < 0 {
|
||
|
offset++ // e.g., translate LA(-1) to use offset=0
|
||
|
}
|
||
|
pos := is.index + offset - 1
|
||
|
|
||
|
if pos < 0 || pos >= is.size { // invalid
|
||
|
return TokenEOF
|
||
|
}
|
||
|
|
||
|
return int(is.data[pos])
|
||
|
}
|
||
|
|
||
|
// LT returns the character at the given offset from the start of the input stream
|
||
|
func (is *InputStream) LT(offset int) int {
|
||
|
return is.LA(offset)
|
||
|
}
|
||
|
|
||
|
// Index returns the current offset in to the input stream
|
||
|
func (is *InputStream) Index() int {
|
||
|
return is.index
|
||
|
}
|
||
|
|
||
|
// Size returns the total number of characters in the input stream
|
||
|
func (is *InputStream) Size() int {
|
||
|
return is.size
|
||
|
}
|
||
|
|
||
|
// Mark does nothing here as we have entire buffer
|
||
|
func (is *InputStream) Mark() int {
|
||
|
return -1
|
||
|
}
|
||
|
|
||
|
// Release does nothing here as we have entire buffer
|
||
|
func (is *InputStream) Release(_ int) {
|
||
|
}
|
||
|
|
||
|
// Seek the input point to the provided index offset
|
||
|
func (is *InputStream) Seek(index int) {
|
||
|
if index <= is.index {
|
||
|
is.index = index // just jump don't update stream state (line,...)
|
||
|
return
|
||
|
}
|
||
|
// seek forward
|
||
|
is.index = intMin(index, is.size)
|
||
|
}
|
||
|
|
||
|
// GetText returns the text from the input stream from the start to the stop index
|
||
|
func (is *InputStream) GetText(start int, stop int) string {
|
||
|
if stop >= is.size {
|
||
|
stop = is.size - 1
|
||
|
}
|
||
|
if start >= is.size {
|
||
|
return ""
|
||
|
}
|
||
|
|
||
|
return string(is.data[start : stop+1])
|
||
|
}
|
||
|
|
||
|
// GetTextFromTokens returns the text from the input stream from the first character of the start token to the last
|
||
|
// character of the stop token
|
||
|
func (is *InputStream) GetTextFromTokens(start, stop Token) string {
|
||
|
if start != nil && stop != nil {
|
||
|
return is.GetTextFromInterval(NewInterval(start.GetTokenIndex(), stop.GetTokenIndex()))
|
||
|
}
|
||
|
|
||
|
return ""
|
||
|
}
|
||
|
|
||
|
func (is *InputStream) GetTextFromInterval(i Interval) string {
|
||
|
return is.GetText(i.Start, i.Stop)
|
||
|
}
|
||
|
|
||
|
func (*InputStream) GetSourceName() string {
|
||
|
return ""
|
||
|
}
|
||
|
|
||
|
// String returns the entire input stream as a string
|
||
|
func (is *InputStream) String() string {
|
||
|
return string(is.data)
|
||
|
}
|