Skip to content

Commit

Permalink
Ref
Browse files Browse the repository at this point in the history
  • Loading branch information
alkizer committed Aug 2, 2019
1 parent 0bbde67 commit 2ad2a4a
Showing 1 changed file with 86 additions and 14 deletions.
100 changes: 86 additions & 14 deletions lib/grammarParser/lineParser.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,26 @@
enum LineType {
ProductionLine
ProductionLine,
RawDerivationLine
};

class Line {
abstract class Line {
private _source: string;
private _type: LineType;

constructor (source: string, type: LineType) {
this._source = source;
public comment: string;

constructor (type: LineType) {
this._type = type;
}

get source () {
return this._source;
}

set source (value: string) {
this._source = value;
}

get type () {
return this._type;
}
Expand All @@ -25,8 +31,8 @@ class ProductionLine extends Line {
private _isAbstract: boolean;
private _isEntry: boolean;

constructor (source: string, name: string, isAbstract: boolean, isEntry: boolean) {
super(source, LineType.ProductionLine);
constructor (name: string, isAbstract: boolean, isEntry: boolean) {
super(LineType.ProductionLine);
this._name = name;
this._isAbstract = isAbstract;
this._isEntry = isEntry;
Expand All @@ -43,6 +49,19 @@ class ProductionLine extends Line {
get isEntry () {
return this._isEntry;
}
};

class RawDerivationLine extends Line {
private _unparsedTargets: string[];

constructor (unparsedTargets: string[]) {
super(LineType.ProductionLine);
this._unparsedTargets = unparsedTargets;
}

get unparsedTargets () {
return this._unparsedTargets;
}
}

interface ILineParserFunction {
Expand All @@ -51,31 +70,84 @@ interface ILineParserFunction {

const tryParseProduction: ILineParserFunction = (line) => {
let isAbstract = false,
isEntry = false,
originalLine = line + ``;
isEntry = false;
if (line.startsWith(`abstract`)) {
line = line.replace(`abstract`, ``).trim();
isAbstract = true;
}
if (line.charAt(0) === `$`) {
isEntry = true;
}
if (/[$A-Za-z]/.test(line)) {
const parsedLine = new ProductionLine(originalLine, line, isAbstract, isEntry);
if (/^[$A-Za-z]+$/.test(line)) {
const parsedLine = new ProductionLine(line, isAbstract, isEntry);
return parsedLine;
}
return false;
};

const tryParseRawDerivation: ILineParserFunction = (line) => {
let unparsedTargets = [];
if (line.startsWith(` |`)) {
line = line.replace(` |`, ``).trim();
unparsedTargets = line.split(` `); // TODO quoted strings
const parsedLine = new RawDerivationLine(unparsedTargets);
return parsedLine;
}
return false;
};

const lineParsers: ILineParserFunction[] = [
tryParseProduction,
tryParseRawDerivation,
];

const extractComment = (line: string) => {
let comment = null;
let commentMatch = line.match(/;([^\n]*)\n/g);
if (commentMatch[0]) {
comment = commentMatch[1];
line = line.replace(/;[^\n]*\n/g, `\n`);
}
return {
line,
comment
};
};

const isIgnorableLine = (line: string) => {
for (let character of line) {
if (character === `\n` || character === `` || character === ` ` || character === `\t`) {
continue;
}
return false;
}
return true;
}

const parseLine = (line: string, lineNumber: number) => {
let parsedLine = null;
if (parsedLine = tryParseProduction(line)) {
return parsedLine;
let { line: uncommentedLine, comment } = extractComment(line);
if (isIgnorableLine(line)) {
return false;
}
lineParsers.map((lineParser) => {
if (parsedLine = lineParser(uncommentedLine)) {
return;
}
});
if (!parsedLine) {
return new Error(`Syntax errror!`);
}
if (comment) {
parsedLine.comment = comment;
}
parsedLine.source = line;
return parsedLine;
};

const getLines = (grammarSourceCode: string) => {
//const lines = grammarSourceCode.replace(/;[^\n]*\n/g, `\n`).trim().split(`\n`);
const lines = grammarSourceCode.split(`\n`);
const parsedLines = lines.map(parseLine);
const parsedLines = lines.map(parseLine).filter(line => !!line);
return parsedLines;
};

0 comments on commit 2ad2a4a

Please sign in to comment.