started working on parser

This commit is contained in:
Lauchmelder 2021-11-27 20:54:04 +01:00
parent 2558a548b3
commit d01cf5790b
5 changed files with 134 additions and 30 deletions

View file

@ -1,3 +1,2 @@
point(3 | 4)
point(6 | 7)
point(3, 4) -> A
line(A, point(7, 8))

View file

@ -1,5 +1,6 @@
/// <reference path="vector.ts" />
/// <reference path="shapes.ts" />
/// <reference path="parser/parser.ts" />
function loadScript(filepath: string): string
{
@ -32,33 +33,7 @@ class Geometry extends HTMLElement
let sourceFile = this.getAttribute("src");
let content = loadScript(sourceFile);
let lines = content.split("\n");
for(let line of lines)
{
if(line === "\r")
{
console.log("empty");
continue;
}
let instruction = line.split("(")[0];
switch(instruction)
{
case instruction:
{
let coords = line.split("(")[1].split("|");
console.log(coords);
break;
}
default:
{
console.log("something else");
break;
}
}
}
let parser = new Parser(content);
this.attachShadow({mode: "open"});
let canvas = document.createElement("canvas");

18
src/parser/instruction.ts Normal file
View file

@ -0,0 +1,18 @@
enum InstructionType
{
Point,
Line,
Circle
}
class Instruction
{
public fn: InstructionType;
public params :Parameter[];
constructor(type: InstructionType)
{
this.fn = type;
this.params = [];
}
}

35
src/parser/parameter.ts Normal file
View file

@ -0,0 +1,35 @@
enum ParameterType
{
Instruction,
Identifier,
Number
}
abstract class Parameter
{
public type: ParameterType;
constructor(type: ParameterType)
{
this.type = type;
}
abstract eval();
}
class NumberParameter extends Parameter
{
public val: number;
constructor(val: number)
{
super(ParameterType.Number);
this.val = val;
}
eval()
{
return this.val;
}
}

77
src/parser/parser.ts Normal file
View file

@ -0,0 +1,77 @@
/// <reference path="parameter.ts" />
/// <reference path="instruction.ts" />
class Parser
{
private instructions: Instruction[];
constructor(source: string)
{
this.instructions = [];
let lines = source.split(/\r?\n/);
for(let line of lines)
this.parseInstruction(line);
}
private parseInstruction(instruction: string): boolean
{
// If the instruction is an empty line, do nothing for now
if(instruction === "")
return false;
// match the pattern "text(text)"
let matches = instruction.match(/[A-Za-z]*\(.*\)/);
if(matches === null) // no match found
{
console.error("Invalid syntax");
return false;
}
if(matches.length > 1) // more than one match
{
console.error("Script may only contain one instruction per line");
return false;
}
let instr = matches[0]; // get the instruction
instr = instr.split(" ").join("");
let paranthesisPos = instr.search(/\(/); // Find the position of the first opening paranthesis
let symbol = instr.substr(0, paranthesisPos); // get function name
let paramlist = instr.substring(paranthesisPos + 1, instr.length - 1); // get parameter list
let match;
let params = [];
while((match = paramlist.search(/,(?![^\(]*\))/)) !== -1)
{
params.push(paramlist.substring(0, match));
paramlist = paramlist.substring(match + 1, paramlist.length);
}
params.push(paramlist);
this.instructions.push(new Instruction(InstructionType.Point));
for(let param of params)
{
if(!this.parseParameter(param))
{
console.error("Error during parameter parsing");
return false;
}
}
return true;
}
private parseParameter(parameter: string): boolean
{
let match = parameter.search(/\d*\.?\d*$/);
if(match === 0)
{
this.instructions[this.instructions.length - 1].params.push(new NumberParameter(4));
return true;
}
return false;
}
}