fix: buffer reader

test: add InputReader test
This commit is contained in:
Chen Asraf
2023-05-02 00:17:13 +03:00
committed by Chen Asraf
parent 1545665fce
commit dc2fde1da4
2 changed files with 67 additions and 4 deletions

36
__tests__/reader_test.ts Normal file
View File

@@ -0,0 +1,36 @@
import { Parser } from '../src/parser'
import { BufferReader } from '../src/reader'
import { Lexer } from '../src/lexer'
test('Buffer reader should work', () => {
const reader = new BufferReader(Buffer.from('(apple OR orange) AND (drink OR juice)'))
const lexer = new Lexer(reader)
const parser = new Parser(lexer)
const tokens = parser.parse()
expect(tokens[0]).toEqual({
type: 'operator',
value: 'and',
left: {
type: 'group',
children: [
{
type: 'operator',
value: 'or',
left: { type: 'word', value: 'apple' },
right: { type: 'word', value: 'orange' },
},
],
},
right: {
type: 'group',
children: [
{
type: 'operator',
value: 'or',
left: { type: 'word', value: 'drink' },
right: { type: 'word', value: 'juice' },
},
],
},
})
})

View File

@@ -15,7 +15,20 @@ export abstract class InputReader<T> {
}
/**
* Buffer Input Reader
* This reader is used to read from a buffer instead of a string, which is useful for reading from
* files, or for better performance as buffer indexes are loaded lazily.
*
* In most cases, you would want to use the regular `parse` function, which uses a dynamic reader from the input.
*
* If you still want to create a buffer reader, you can do so by using the `BufferReader` class.
*
* @example
* ```ts
* const reader = new BufferReader(Buffer.from('(apple OR orange) AND (drink OR juice)'))
* const lexer = new Lexer(reader)
* const parser = new Parser(lexer)
* const tokens = parser.parse()
* ```
*/
export class BufferReader implements InputReader<string> {
#buffer: Buffer
@@ -27,11 +40,11 @@ export class BufferReader implements InputReader<string> {
}
public peek(n = 0): string {
return this.#buffer.subarray(this.index + n, 1).toString()
return this.#buffer.subarray(this.index + n, this.index + n + 1).toString()
}
public consume(n = 0): string {
const result = this.#buffer.subarray(this.index + n, 1).toString()
const result = this.#buffer.subarray(this.index + n, this.index + n + 1).toString()
this.index++
return result
}
@@ -46,7 +59,21 @@ export class BufferReader implements InputReader<string> {
}
/**
* String Input Reader
* This reader is used to read from a string. This is usually worse for performance than reading
* from a buffer, as buffer indexes are loaded lazily, but for most cases it is good enough.
*
* In most cases, you would want to use the regular `parse` function, which uses a dynamic reader
* from the input.
*
* If you still want to create a string reader, you can do so by using the `StringReader` class.
*
* @example
* ```ts
* const reader = new StringReader('(apple OR orange) AND (drink OR juice)')
* const lexer = new Lexer(reader)
* const parser = new Parser(lexer)
* const tokens = parser.parse()
* ```
*/
export class StringReader implements InputReader<string> {
#string: string