88 lines
2.8 KiB
TypeScript
88 lines
2.8 KiB
TypeScript
![]() |
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;
|
||
|
}
|
||
|
}
|