Skip to content

Commit fdef6b2

Browse files
committed
some more parser bug fixing
1 parent 183bd53 commit fdef6b2

File tree

11 files changed

+269
-195
lines changed

11 files changed

+269
-195
lines changed

exampleVault/examples.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
slider1: 9
2+
slider1: 5
33
suggest: test
44
toggle1: false
55
Domestic_tasks:

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
"svelte-preprocess": "^4.10.7",
4242
"ts-jest": "^29.1.1",
4343
"tslib": "2.4.0",
44-
"typescript": "^4.9.3"
44+
"typescript": "^4.9.5"
4545
},
4646
"dependencies": {
4747
"@codemirror/language": "https://github.com/lishid/cm-language",
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { Abstract_PT_Node, ParsingTree, PT_Closure, PT_Literal } from './ParsingTree';
2+
import { InputFieldToken, InputFieldTokenType } from './InputFieldTokenizer';
3+
import { ValidationContext, ValidationContextEntry, ValidationGraph } from './validationGraph/ValidationGraph';
4+
import { StructureParserResult } from './StructureParser';
5+
6+
export type InputField_PT_Literal = PT_Literal<InputFieldTokenType, InputFieldToken>;
7+
export type InputField_PT_Closure = PT_Closure<InputFieldTokenType, InputFieldToken>;
8+
export type InputField_Abstract_PT_Node = Abstract_PT_Node<InputFieldTokenType, InputFieldToken>;
9+
export type InputField_ValidationGraph<Key extends string> = ValidationGraph<InputFieldTokenType, InputFieldToken, Key>;
10+
export type InputField_ValidationContext<Key extends string> = ValidationContext<InputFieldTokenType, InputFieldToken, Key>;
11+
export type InputField_ValidationContextLiteralEntry = ValidationContextEntry<InputFieldTokenType, InputFieldToken, InputField_PT_Literal>;
12+
export type InputField_ValidationContextClosureEntry = ValidationContextEntry<InputFieldTokenType, InputFieldToken, InputField_PT_Closure>;
13+
export type InputField_StructureParserResult = StructureParserResult<InputFieldTokenType, InputFieldToken>;
14+
export type InputField_ParsingTree = ParsingTree<InputFieldTokenType, InputFieldToken>;
Lines changed: 4 additions & 136 deletions
Original file line numberDiff line numberDiff line change
@@ -1,140 +1,8 @@
1-
import { ParsingError } from './ParsingError';
2-
import { ErrorLevel } from '../../utils/errors/MetaBindErrors';
3-
import { ParsingTree, PT_Closure, PT_Element, PT_Element_Type, PT_Literal } from './ParsingTree';
4-
import { AbstractToken, Closure } from './ParsingUtils';
51
import { InputFieldClosures, InputFieldToken, InputFieldTokenType } from './InputFieldTokenizer';
2+
import { ParsingTreeParser } from './ParsingTreeParser';
63

7-
export class InputFieldParsingTreeParser<TokenType extends string, Token extends AbstractToken<TokenType>> {
8-
private readonly tokens: Token[];
9-
private readonly closureStack: Closure<InputFieldTokenType>[];
10-
private readonly parsingTree: ParsingTree<TokenType, Token>;
11-
private position: number;
12-
13-
constructor(str: string, tokens: Token[]) {
14-
this.tokens = tokens;
15-
this.position = 0;
16-
this.closureStack = [];
17-
this.parsingTree = new ParsingTree(str, tokens);
18-
}
19-
20-
public parse(): ParsingTree<TokenType, Token> {
21-
while (this.getCurrentToken().type !== InputFieldTokenType.EOF) {
22-
const astel = this.parseCurrentToken();
23-
this.parsingTree.children.push(astel);
24-
25-
if (this.position >= this.tokens.length) {
26-
throw new Error('index to big');
27-
}
28-
}
29-
30-
return this.parsingTree;
31-
}
32-
33-
private parseCurrentToken(): PT_Element<TokenType, Token> {
34-
const token = this.getCurrentToken();
35-
36-
this.throwOnInvalidToken();
37-
38-
const ptLiteral = new PT_Literal(token, this.parsingTree.str);
39-
40-
for (const closure of InputFieldClosures) {
41-
const ptClosure = this.parseClosure(ptLiteral, closure);
42-
if (ptClosure) {
43-
return ptClosure;
44-
}
45-
}
46-
47-
// move the position to the next token
48-
this.position += 1;
49-
50-
return ptLiteral;
51-
}
52-
53-
private parseClosure(openingLiteral: PT_Literal<TokenType, Token>, closure: Closure<InputFieldTokenType>): PT_Element<TokenType, Token> | undefined {
54-
if (openingLiteral.token.type !== closure.openingTokenType) {
55-
return undefined;
56-
}
57-
58-
this.closureStack.push(closure);
59-
60-
let closingLiteral: PT_Literal<TokenType, Token> | undefined;
61-
const children: PT_Element<TokenType, Token>[] = [];
62-
63-
// skip the opening token
64-
this.position += 1;
65-
66-
while (this.getCurrentToken().type !== InputFieldTokenType.EOF) {
67-
const nestedRes = this.parseCurrentToken();
68-
69-
if (nestedRes.type === PT_Element_Type.LITERAL && (nestedRes as PT_Literal<TokenType, Token>).token.type === closure.closingTokenType) {
70-
closingLiteral = nestedRes as PT_Literal<TokenType, Token>;
71-
break;
72-
} else {
73-
children.push(nestedRes);
74-
}
75-
}
76-
77-
if (!closingLiteral) {
78-
throw new ParsingError(
79-
ErrorLevel.ERROR,
80-
'failed to parse',
81-
`Closure was not closed. You forgot a '${closure.closingTokenType}'.`,
82-
{},
83-
this.parsingTree.str,
84-
openingLiteral.token,
85-
'PT Parser'
86-
);
87-
}
88-
89-
this.closureStack.pop();
90-
91-
return new PT_Closure(this.parsingTree.str, openingLiteral, closingLiteral, children);
92-
}
93-
94-
private getCurrentToken(): Token {
95-
return this.tokens[this.position];
96-
}
97-
98-
throwOnInvalidToken(): void {
99-
const token = this.getCurrentToken();
100-
101-
// check for closure closing tokens that do not actually close a closure
102-
const currentClosure = this.closureStack.length > 0 ? this.closureStack[this.closureStack.length - 1] : undefined;
103-
104-
for (const closure of InputFieldClosures) {
105-
// if the closure is the current token
106-
if (
107-
currentClosure !== undefined &&
108-
closure.openingTokenType === currentClosure.openingTokenType &&
109-
closure.closingTokenType === currentClosure.closingTokenType
110-
) {
111-
continue;
112-
}
113-
114-
// if the current token is a closing token of a closure that is not the active closure
115-
if (token.type === closure.closingTokenType) {
116-
if (currentClosure !== undefined) {
117-
throw new ParsingError(
118-
ErrorLevel.ERROR,
119-
'failed to parse',
120-
`Encountered invalid token. Active closure is not the closure that this token closes. You probably forgot a '${currentClosure.closingTokenType}' somewhere in font of this token.`,
121-
{},
122-
this.parsingTree.str,
123-
token,
124-
'PT Parser'
125-
);
126-
} else {
127-
throw new ParsingError(
128-
ErrorLevel.ERROR,
129-
'failed to parse',
130-
`Encountered invalid token. Active closure is not the closure that this token closes. You probably forgot a '${closure.openingTokenType} somewhere in font of this token.'`,
131-
{},
132-
this.parsingTree.str,
133-
token,
134-
'PT Parser'
135-
);
136-
}
137-
}
138-
}
4+
export class InputFieldParsingTreeParser extends ParsingTreeParser<InputFieldTokenType, InputFieldToken> {
5+
constructor(str: string, tokens: InputFieldToken[]) {
6+
super(str, tokens, InputFieldClosures);
1397
}
1408
}

src/parsers/newInputFieldParser/InputFieldStructureParser.ts

Lines changed: 40 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import { Abstract_PT_Node, ParsingTree, PT_Closure, PT_Literal } from './ParsingTree';
22
import {
33
getClosureFromContext,
4+
getClosureOrUndefinedFromContext,
45
getEntryFromContext,
56
getLiteralFromContext,
7+
getLiteralOrUndefinedFromContext,
68
getSubContextArrayFromContext,
79
hasContextEntry,
810
ValidationContext,
@@ -18,21 +20,31 @@ import { UnvalidatedInputFieldDeclaration } from './InputFieldDeclarationValidat
1820
import { ITemplateSupplier } from './ITemplateSupplier';
1921
import { InputFieldValidationGraphSupplier } from './validationGraph/InputFieldValidationGraphSupplier';
2022
import { getTrimmedStructureParserResult, StructureParserResult } from './StructureParser';
23+
import {
24+
InputField_Abstract_PT_Node,
25+
InputField_ParsingTree,
26+
InputField_PT_Closure,
27+
InputField_StructureParserResult,
28+
InputField_ValidationContext,
29+
InputField_ValidationContextClosureEntry,
30+
InputField_ValidationContextLiteralEntry,
31+
InputField_ValidationGraph,
32+
} from './InputFieldParserHelperTypes';
2133

2234
export class InputFieldStructureParser {
2335
templateSupplier: ITemplateSupplier<UnvalidatedInputFieldDeclaration>;
2436
graphSupplier: InputFieldValidationGraphSupplier;
2537

2638
fullDeclaration: string;
2739
tokens: InputFieldToken[];
28-
parsingTree: ParsingTree<InputFieldTokenType, InputFieldToken>;
40+
parsingTree: InputField_ParsingTree;
2941

30-
inputFieldType?: StructureParserResult<InputFieldTokenType, InputFieldToken>;
31-
bindTargetFile?: StructureParserResult<InputFieldTokenType, InputFieldToken>;
32-
bindTargetPath?: StructureParserResult<InputFieldTokenType, InputFieldToken>;
42+
inputFieldType?: InputField_StructureParserResult;
43+
bindTargetFile?: InputField_StructureParserResult;
44+
bindTargetPath?: InputField_StructureParserResult;
3345
arguments: {
34-
name: StructureParserResult<InputFieldTokenType, InputFieldToken>;
35-
value?: StructureParserResult<InputFieldTokenType, InputFieldToken>;
46+
name: InputField_StructureParserResult;
47+
value?: InputField_StructureParserResult;
3648
}[];
3749
errorCollection: ErrorCollection;
3850

@@ -41,7 +53,7 @@ export class InputFieldStructureParser {
4153
graphSupplier: InputFieldValidationGraphSupplier,
4254
fullDeclaration: string,
4355
tokens: InputFieldToken[],
44-
parsingTree: ParsingTree<InputFieldTokenType, InputFieldToken>,
56+
parsingTree: InputField_ParsingTree,
4557
errorCollection: ErrorCollection
4658
) {
4759
this.templateSupplier = templateSupplier;
@@ -109,7 +121,7 @@ export class InputFieldStructureParser {
109121
return this.buildDeclaration();
110122
}
111123

112-
private parseTemplate(closure: PT_Closure<InputFieldTokenType, InputFieldToken>): void {
124+
private parseTemplate(closure: InputField_PT_Closure): void {
113125
const validationContext = this.validateNodeAndThrow(closure, this.graphSupplier.templateNameValidationGraph);
114126

115127
if (hasContextEntry(validationContext, 'templateName')) {
@@ -143,7 +155,7 @@ export class InputFieldStructureParser {
143155
}
144156
}
145157

146-
private parsePartialDeclaration(closure: PT_Closure<InputFieldTokenType, InputFieldToken>): void {
158+
private parsePartialDeclaration(closure: InputField_PT_Closure): void {
147159
const validationContext = this.validateNodeAndThrow(closure, this.graphSupplier.partialDeclarationValidationGraph);
148160

149161
if (hasContextEntry(validationContext, 'type')) {
@@ -159,7 +171,7 @@ export class InputFieldStructureParser {
159171
}
160172
}
161173

162-
private parseDeclaration(closure: PT_Closure<InputFieldTokenType, InputFieldToken>): void {
174+
private parseDeclaration(closure: InputField_PT_Closure): void {
163175
const validationContext = this.validateNodeAndThrow(closure, this.graphSupplier.declarationValidationGraph);
164176

165177
this.inputFieldType = this.parseInputFieldType(getLiteralFromContext(validationContext, 'type'));
@@ -183,18 +195,21 @@ export class InputFieldStructureParser {
183195
* @private
184196
*/
185197
private parseBindTarget(
186-
closure: PT_Closure<InputFieldTokenType, InputFieldToken>,
187-
validationContext: ValidationContext<InputFieldTokenType, InputFieldToken, string>,
188-
bindTargetSeparatorContextEntry: ValidationContextEntry<InputFieldTokenType, InputFieldToken, PT_Literal<InputFieldTokenType, InputFieldToken>>
198+
closure: InputField_PT_Closure,
199+
validationContext: InputField_ValidationContext<string>,
200+
bindTargetSeparatorContextEntry: InputField_ValidationContextLiteralEntry
189201
): void {
190202
const separatorIndex = bindTargetSeparatorContextEntry.inputIndex;
191203
if (closure.children[separatorIndex] === undefined) {
192204
// there is no bind target
193205
return;
194206
}
195207

196-
const bindTargetContextEntry = getLiteralFromContext(validationContext, 'bindTarget');
197-
const bindTargetFileContextEntry = getLiteralFromContext(validationContext, 'bindTargetFile');
208+
const bindTargetContextEntry: InputField_ValidationContextLiteralEntry = getLiteralFromContext(validationContext, 'bindTarget');
209+
const bindTargetFileContextEntry: InputField_ValidationContextLiteralEntry | undefined = getLiteralOrUndefinedFromContext(
210+
validationContext,
211+
'bindTargetFile'
212+
);
198213

199214
// parsing the bind target with this parser sucks
200215
let bindTargetLiteral = '';
@@ -209,7 +224,7 @@ export class InputFieldStructureParser {
209224
};
210225
}
211226

212-
private parseArguments(contextEntry: ValidationContextEntry<InputFieldTokenType, InputFieldToken, PT_Closure<InputFieldTokenType, InputFieldToken>>): void {
227+
private parseArguments(contextEntry: InputField_ValidationContextClosureEntry): void {
213228
const closure = contextEntry.element;
214229
if (closure.children.length === 0) {
215230
return;
@@ -220,23 +235,17 @@ export class InputFieldStructureParser {
220235
const subContextArray = getSubContextArrayFromContext(validationContext, 'arguments');
221236

222237
for (const x of subContextArray) {
223-
const typeContextEntry: ValidationContextEntry<
224-
InputFieldTokenType,
225-
InputFieldToken,
226-
PT_Literal<InputFieldTokenType, InputFieldToken>
227-
> = getLiteralFromContext(x, 'name');
228-
const valueContextEntry:
229-
| ValidationContextEntry<InputFieldTokenType, InputFieldToken, PT_Closure<InputFieldTokenType, InputFieldToken>>
230-
| undefined = getClosureFromContext(x, 'value');
238+
const typeContextEntry: InputField_ValidationContextLiteralEntry = getLiteralFromContext(x, 'name');
239+
const valueContextEntry: InputField_ValidationContextClosureEntry | undefined = getClosureOrUndefinedFromContext(x, 'value');
231240

232241
this.arguments.push(this.parseArgument(typeContextEntry, valueContextEntry));
233242
}
234243
}
235244

236245
private parseArgument(
237-
nameContextEntry: ValidationContextEntry<InputFieldTokenType, InputFieldToken, PT_Literal<InputFieldTokenType, InputFieldToken>>,
238-
valueContextEntry: ValidationContextEntry<InputFieldTokenType, InputFieldToken, PT_Closure<InputFieldTokenType, InputFieldToken>> | undefined
239-
): { name: StructureParserResult<InputFieldTokenType, InputFieldToken>; value?: StructureParserResult<InputFieldTokenType, InputFieldToken> } {
246+
nameContextEntry: InputField_ValidationContextLiteralEntry,
247+
valueContextEntry: InputField_ValidationContextClosureEntry | undefined
248+
): { name: InputField_StructureParserResult; value?: InputField_StructureParserResult } {
240249
if (valueContextEntry?.element) {
241250
let valueString = '';
242251
for (const child of valueContextEntry.element.children) {
@@ -258,9 +267,9 @@ export class InputFieldStructureParser {
258267
}
259268

260269
private validateNodeAndThrow<Key extends string>(
261-
astNode: Abstract_PT_Node<InputFieldTokenType, InputFieldToken>,
262-
validationGraph: ValidationGraph<InputFieldTokenType, InputFieldToken, Key>
263-
): ValidationContext<InputFieldTokenType, InputFieldToken, Key> {
270+
astNode: InputField_Abstract_PT_Node,
271+
validationGraph: InputField_ValidationGraph<Key>
272+
): InputField_ValidationContext<Key> {
264273
const valRes = validationGraph.validateParsingTreeAndExtractContext(astNode);
265274

266275
if (valRes.acceptedState === undefined) {
@@ -270,9 +279,7 @@ export class InputFieldStructureParser {
270279
return valRes.acceptedState.context;
271280
}
272281

273-
private parseInputFieldType(
274-
contextEntry: ValidationContextEntry<InputFieldTokenType, InputFieldToken, PT_Literal<InputFieldTokenType, InputFieldToken>>
275-
): StructureParserResult<InputFieldTokenType, InputFieldToken> {
282+
private parseInputFieldType(contextEntry: InputField_ValidationContextLiteralEntry): InputField_StructureParserResult {
276283
return getTrimmedStructureParserResult(contextEntry);
277284
}
278285
}

src/parsers/newInputFieldParser/InputFieldTokenizer.ts

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,21 @@
11
import { AbstractToken, Closure } from './ParsingUtils';
2-
3-
export enum InputFieldTokenType {
4-
EOF = 'EOF',
5-
WORD = 'WORD',
6-
L_PAREN = '(',
7-
R_PAREN = ')',
8-
L_SQUARE = '[',
9-
R_SQUARE = ']',
10-
COLON = ':',
11-
HASHTAG = '#',
12-
DOT = '.',
13-
COMMA = ',',
14-
QUOTE = "'",
15-
}
2+
import { EOF_TOKEN } from './validationGraph/ValidationGraph';
3+
4+
export const InputFieldTokenType = {
5+
EOF: EOF_TOKEN,
6+
WORD: 'WORD',
7+
L_PAREN: '(',
8+
R_PAREN: ')',
9+
L_SQUARE: '[',
10+
R_SQUARE: ']',
11+
COLON: ':',
12+
HASHTAG: '#',
13+
DOT: '.',
14+
COMMA: ',',
15+
QUOTE: "'",
16+
} as const;
17+
18+
export type InputFieldTokenType = typeof InputFieldTokenType[keyof typeof InputFieldTokenType];
1619

1720
export const InputFieldClosures: Closure<InputFieldTokenType>[] = [
1821
{

0 commit comments

Comments
 (0)