Parsing of workout header
This commit is contained in:
parent
220ca26c97
commit
2a362e6362
|
|
@ -1,4 +1,5 @@
|
|||
import * as fs from "fs";
|
||||
import { parse } from "./parser";
|
||||
import { tokenizeFile } from "./tokenizer";
|
||||
|
||||
const filename = process.argv[2];
|
||||
|
|
@ -7,6 +8,6 @@ console.log(`Parsing: ${filename}`);
|
|||
|
||||
const file = fs.readFileSync(filename, "utf8");
|
||||
|
||||
tokenizeFile(file).forEach((token) => {
|
||||
console.log(token.type, token.value);
|
||||
});
|
||||
const workout = parse(tokenizeFile(file));
|
||||
|
||||
console.log(workout);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,70 @@
|
|||
import { Interval, Workout } from "./ast";
|
||||
import { LabelTokenValue, Token } from "./tokenizer";
|
||||
|
||||
type Header = {
|
||||
name?: string;
|
||||
author?: string;
|
||||
description?: string;
|
||||
};
|
||||
|
||||
const extractText = (tokens: Token[]): [string, Token[]] => {
|
||||
let text;
|
||||
while (tokens[0] && tokens[0].type === "text") {
|
||||
if (text === undefined) {
|
||||
text = tokens[0].value;
|
||||
} else {
|
||||
text += "\n" + tokens[0].value;
|
||||
}
|
||||
tokens.shift();
|
||||
}
|
||||
return [text || "", tokens];
|
||||
};
|
||||
|
||||
const parseHeader = (tokens: Token[]): [Header, Token[]] => {
|
||||
const header: Header = {};
|
||||
|
||||
while (tokens[0]) {
|
||||
const token = tokens[0];
|
||||
if (token.type === "label" && token.value === LabelTokenValue.Name) {
|
||||
tokens.shift();
|
||||
const [name, rest] = extractText(tokens);
|
||||
header.name = name;
|
||||
tokens = rest;
|
||||
} else if (
|
||||
token.type === "label" &&
|
||||
token.value === LabelTokenValue.Author
|
||||
) {
|
||||
tokens.shift();
|
||||
const [author, rest] = extractText(tokens);
|
||||
header.author = author;
|
||||
tokens = rest;
|
||||
} else if (
|
||||
token.type === "label" &&
|
||||
token.value === LabelTokenValue.Description
|
||||
) {
|
||||
tokens.shift();
|
||||
const [description, rest] = extractText(tokens);
|
||||
header.description = description;
|
||||
tokens = rest;
|
||||
} else {
|
||||
// End of header
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return [header, tokens];
|
||||
};
|
||||
|
||||
const parseIntervals = (tokens: Token[]): Interval[] => {
|
||||
return [];
|
||||
};
|
||||
|
||||
export const parse = (tokens: Token[]): Workout => {
|
||||
const [header, intervalTokens] = parseHeader(tokens);
|
||||
return {
|
||||
name: header.name || "",
|
||||
author: header.author || "",
|
||||
description: header.description || "",
|
||||
intervals: parseIntervals(intervalTokens),
|
||||
};
|
||||
};
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
enum LabelTokenValue {
|
||||
export enum LabelTokenValue {
|
||||
Name = "Name",
|
||||
Author = "Author",
|
||||
Description = "Description",
|
||||
|
|
@ -7,23 +7,23 @@ enum LabelTokenValue {
|
|||
Interval = "Interval",
|
||||
Cooldown = "Cooldown",
|
||||
}
|
||||
type LabelToken = {
|
||||
export type LabelToken = {
|
||||
type: "label";
|
||||
value: LabelTokenValue;
|
||||
};
|
||||
type TextToken = {
|
||||
export type TextToken = {
|
||||
type: "text";
|
||||
value: string;
|
||||
};
|
||||
type NumberToken = {
|
||||
export type NumberToken = {
|
||||
type: "power" | "cadence" | "duration";
|
||||
value: number;
|
||||
};
|
||||
type PowerRangeToken = {
|
||||
export type PowerRangeToken = {
|
||||
type: "power-range";
|
||||
value: [number, number];
|
||||
};
|
||||
type Token = LabelToken | TextToken | NumberToken | PowerRangeToken;
|
||||
export type Token = LabelToken | TextToken | NumberToken | PowerRangeToken;
|
||||
|
||||
const toInteger = (str: string): number => {
|
||||
return parseInt(str.replace(/[^0-9]/, ""), 10);
|
||||
|
|
|
|||
Loading…
Reference in New Issue