forked from daKuleMune/nodebnf
-
Notifications
You must be signed in to change notification settings - Fork 0
/
TokenTree.js
120 lines (95 loc) · 2.78 KB
/
TokenTree.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
exports.TokenTree = class TokenTree{
constructor( rootToken, dataObject, compiler, parser ){
this.dataObject = dataObject;
this.compiler = compiler;
this.languageId = parser.language.name;
this.rootToken = rootToken;
this.currentToken = null;
this._PurgeRules( this.rootToken );
}
Execute(){
while( this.Eat() !== false ){
}
}
_PurgeRules( token ){
let filter = null;
while( ( filter = token.tokens.filter( x => x.name.startsWith( "&" ) ) ).length > 0 ){
if( filter[0].name === "&LITERAL" ){
filter[0].name = "GRAMMAR";
}
else{
let insertPoint = token.tokens.indexOf( filter[0] );
filter[0].tokens.map( x => x.parent = token );
if( filter[0]._value ){
filter[0].parent._value = ( filter[0].parent._value !== null ) ? filter[0].parent._value + filter[0]._value : filter[0]._value;
}
token.tokens.splice.apply( token.tokens, [ insertPoint, 1 ].concat( filter[0].tokens ) );
}
}
token.tokens.map( ( x ) => {
this._PurgeRules( x );
} );
}
Consume( untilTokenType ){
let token = null;
while( ( token = this.Eat() ) !== false && token.name !== untilTokenType ){
}
return token;
}
Read( untilTokenType ){
let token = this.currentToken;
while( ( token = this._GetTokenAfter( token ) ) !== false && token.name !== untilTokenType ){
}
if( token !== null && token.name === untilTokenType ){
return token;
}
return null;
}
Reset(){
}
_GetFirstToken( token ){
if( token.tokens.length > 0 ){
return this._GetFirstToken( token.tokens[0] );
}
return token;
}
_GetNextToken(){
if( this.currentToken === null ){
//First token
return this._GetFirstToken( this.rootToken );
}
else{
return this._GetTokenAfter( this.currentToken );
}
}
_GetTokenAfter( currentToken ){
if( currentToken.parent !== null ){
let tokenLocal = currentToken.parent.tokens.indexOf( currentToken );
if( currentToken.parent.tokens.length > tokenLocal + 1 ){
return this._GetFirstToken( currentToken.parent.tokens[tokenLocal + 1] );
}
else{
return currentToken.parent;
}
}
else{
return null;
}
}
Eat( trigger = true ){
let token = this._GetNextToken();
if( token !== null ){
this.currentToken = token;
token.expended = true;
if( token.parent !== null ){
token.parent.consumerIndex++;
}
this.compiler.Trigger( this.languageId, token, this.dataObject, this );
return token;
}
return false;
}
Peek(){
return this._GetNextToken();
}
};