library-ts/browser/text/lexer/LexerSequence.ts

88 lines
2.8 KiB
TypeScript
Raw Permalink Normal View History

2025-03-08 08:16:54 +00:00
import { LexerEvent } from "./LexerEvent";
import { BooleanExpression } from "../../expressions/BooleanExpression";
import { LexerQuery } from "./LexerQuery";
export class LexerSequence
{
sequence:BooleanExpression<LexerEvent>[] = [];
ignore:BooleanExpression<LexerEvent> = null;
get( query:LexerQuery, tokenOffset:number, sequenceOffset:number ):number[]
{
let sequenceIndices:number[] = [];
for ( let s of this.sequence ){ sequenceIndices.push( -1 ); }
if ( ! this.sequence[ sequenceOffset ].evaluate( query.tokens[ tokenOffset ] ) )
{
//console.log( "Offset is not matching" );
return null;
}
sequenceIndices[ sequenceOffset ] = tokenOffset;
let previousSearchIndex = tokenOffset;
for ( let i = sequenceOffset - 1; i >= 0; i-- )
{
let matcher = this.sequence[ i ];
let index = query.searchIndex( previousSearchIndex, false, matcher, this.ignore, 2 );
if ( index === -1 )
{
let startTokenIndex = Math.max( 0, previousSearchIndex - 5 );
let previousTokens = query.tokens.slice( startTokenIndex, previousSearchIndex );
let infos = previousTokens.map(
( le )=>
{
let ignoreResult = this.ignore.evaluate( le );
let matchResult = matcher.evaluate( le );
return `'${le.match}' ${query.index(le)} ${le.type} ignore:${ignoreResult} match:${matchResult}`;
}
);
//console.log( `Sequence not matching at #${i}(${previousSearchIndex})`, matcher, "\n", `[${infos}]` );
return null;
}
sequenceIndices[ i ] = index;
previousSearchIndex = index;
let token = query.tokens[ index ];
}
let nextSearchIndex = tokenOffset;
for ( let i = sequenceOffset + 1; i < this.sequence.length; i++ )
{
let matcher = this.sequence[ i ];
let index = query.searchIndex( nextSearchIndex, true, matcher, this.ignore, 2 );
if ( index === -1 )
{
let endTokenIndex = Math.min( query.tokens.length, nextSearchIndex + 5 );
let nextTokens = query.tokens.slice( nextSearchIndex, endTokenIndex );
let infos = nextTokens.map(
( le )=>
{
let ignoreResult = this.ignore.evaluate( le );
let matchResult = matcher.evaluate( le );
return `'${le.match}' ${query.index(le)} ${le.type} ignore:${ignoreResult} match:${matchResult}`;
}
);
//console.log( `Sequence not at #${i}(${nextSearchIndex})`, matcher, "\n", `[${infos}]` );
return null;
}
sequenceIndices[ i ] = index;
nextSearchIndex = index;
let token = query.tokens[ index ];
}
return sequenceIndices;
}
}