Parsing of workout header

This commit is contained in:
Rene Saarsoo 2020-09-18 12:26:58 +03:00
parent 220ca26c97
commit 2a362e6362
3 changed files with 80 additions and 9 deletions

View File

@ -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);

70
src/parser.ts Normal file
View File

@ -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),
};
};

View File

@ -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);