From d7d48785aaebdeb08b22e19a428391760f7d2129 Mon Sep 17 00:00:00 2001 From: Atreya Bain Date: Sat, 17 Apr 2021 23:03:40 +0530 Subject: [PATCH] [client] exeute command --- .vscodeignore | 1 + client/bf.g4 | 49 +++ client/package-lock.json | 27 ++ client/package.json | 5 + client/src/bfExecutor.ts | 117 +++++ client/src/bfGrammar.ts | 56 +++ client/src/extension.ts | 12 +- client/src/generated/bf.interp | 40 ++ client/src/generated/bf.tokens | 19 + client/src/generated/bfLexer.interp | 50 +++ client/src/generated/bfLexer.tokens | 19 + client/src/generated/bfLexer.ts | 119 ++++++ client/src/generated/bfParser.ts | 638 ++++++++++++++++++++++++++++ client/src/generated/bfVisitor.ts | 126 ++++++ package.json | 7 +- server/src/server.ts | 29 +- 16 files changed, 1298 insertions(+), 16 deletions(-) create mode 100644 client/bf.g4 create mode 100644 client/src/bfExecutor.ts create mode 100644 client/src/bfGrammar.ts create mode 100644 client/src/generated/bf.interp create mode 100644 client/src/generated/bf.tokens create mode 100644 client/src/generated/bfLexer.interp create mode 100644 client/src/generated/bfLexer.tokens create mode 100644 client/src/generated/bfLexer.ts create mode 100644 client/src/generated/bfParser.ts create mode 100644 client/src/generated/bfVisitor.ts diff --git a/.vscodeignore b/.vscodeignore index 29882b9..4f8bb8a 100644 --- a/.vscodeignore +++ b/.vscodeignore @@ -1,3 +1,4 @@ +client/bf.g4 .vscode/** **/*.ts **/*.map diff --git a/client/bf.g4 b/client/bf.g4 new file mode 100644 index 0000000..9b3c009 --- /dev/null +++ b/client/bf.g4 @@ -0,0 +1,49 @@ +grammar bf; + +program + : statements EOF; + +statements + : eligibleStmt*; + +eligibleStmt + : stmt + | numberedStmt + ; + +numberedStmt + : stmt NUMBER + ; + +stmt + : basicStmt + | loopStmt + ; + + +loopStmt + : LOOPSTART statements LOOPEND + ; + +basicStmt + : INC # ptrIncr + | DEC # ptrDecr + | LEFT # ptrLeft + | RIGHT # ptrRight + | INPUT # inputStmt + | OUTPUT # outputStmt + ; + + +LOOPSTART: '['; +LOOPEND:']'; +NUMBER: [0-9]+; +INPUT: ','; +OUTPUT: '.'; +DEC: '-'; +INC: '+'; +LEFT: '<'; +RIGHT: '>'; +EVERYTHING_ELSE: . ->channel(HIDDEN); +WS: [ \r\n] -> skip; + diff --git a/client/package-lock.json b/client/package-lock.json index 212877f..363c734 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -9,10 +9,12 @@ "version": "0.0.1", "license": "MIT", "dependencies": { + "antlr4ts": "^0.5.0-alpha.4", "vscode-languageclient": "^6.1.3" }, "devDependencies": { "@types/vscode": "1.43.0", + "antlr4ts-cli": "^0.5.0-alpha.4", "vscode-test": "^1.3.0" }, "engines": { @@ -37,6 +39,20 @@ "node": ">= 4.0.0" } }, + "node_modules/antlr4ts": { + "version": "0.5.0-alpha.4", + "resolved": "https://registry.npmjs.org/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz", + "integrity": "sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ==" + }, + "node_modules/antlr4ts-cli": { + "version": "0.5.0-alpha.4", + "resolved": "https://registry.npmjs.org/antlr4ts-cli/-/antlr4ts-cli-0.5.0-alpha.4.tgz", + "integrity": "sha512-lVPVBTA2CVHRYILSKilL6Jd4hAumhSZZWA7UbQNQrmaSSj7dPmmYaN4bOmZG79cOy0lS00i4LY68JZZjZMWVrw==", + "dev": true, + "bin": { + "antlr4ts": "antlr4ts" + } + }, "node_modules/balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -275,6 +291,17 @@ "es6-promisify": "^5.0.0" } }, + "antlr4ts": { + "version": "0.5.0-alpha.4", + "resolved": "https://registry.npmjs.org/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz", + "integrity": "sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ==" + }, + "antlr4ts-cli": { + "version": "0.5.0-alpha.4", + "resolved": "https://registry.npmjs.org/antlr4ts-cli/-/antlr4ts-cli-0.5.0-alpha.4.tgz", + "integrity": "sha512-lVPVBTA2CVHRYILSKilL6Jd4hAumhSZZWA7UbQNQrmaSSj7dPmmYaN4bOmZG79cOy0lS00i4LY68JZZjZMWVrw==", + "dev": true + }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", diff --git a/client/package.json b/client/package.json index fa72812..bde5b78 100644 --- a/client/package.json +++ b/client/package.json @@ -13,10 +13,15 @@ "vscode": "^1.43.0" }, "dependencies": { + "antlr4ts": "^0.5.0-alpha.4", "vscode-languageclient": "^6.1.3" }, "devDependencies": { "@types/vscode": "1.43.0", + "antlr4ts-cli": "^0.5.0-alpha.4", "vscode-test": "^1.3.0" + }, + "scripts": { + "regen": "antlr4ts bf.g4 -no-listener -visitor -o src/generated/" } } diff --git a/client/src/bfExecutor.ts b/client/src/bfExecutor.ts new file mode 100644 index 0000000..0f71718 --- /dev/null +++ b/client/src/bfExecutor.ts @@ -0,0 +1,117 @@ +import { AbstractParseTreeVisitor } from 'antlr4ts/tree/AbstractParseTreeVisitor'; +import { LoopStmtContext, ProgramContext } from '../../client/src/generated/bfParser'; +import { bfVisitor } from '../../client/src/generated/bfVisitor'; +import {getTree} from './bfGrammar'; +import { DiagnosticSeverity } from 'vscode-languageserver-types'; + +/** + * Run BF code + * @param text + * @param fn + * @param input + * @returns + */ +export async function runBF(text:string,fn:string,input:string){ + //get tree and issues + const {tree,issues} = getTree(text,fn); + + //get only errors + const x = issues.filter(e=>e.type===DiagnosticSeverity.Error); + //if any error, drop + if(x.length>0) { + throw Error('Errors exist'); + } + // make visitor + const vis = new BFExecutor(input); + + //visit the tree + vis.visit(tree); + + //get output + return vis.outputStr; +} + + +class BFExecutor + extends AbstractParseTreeVisitor + implements bfVisitor { + + /** + * + * @param input Input string + * @param inputPtr Input pointer to start from + */ + constructor(protected input: string='', protected inputPtr: number = 0) { + super(); + } + /** + * The memory cells (Can work with negative cells this way) + */ + protected cells: Map = new Map(); + /** + * Pointer + */ + protected ptr: number = 0; + /** Output string */ + protected outputStrArray:string[]=[]; + + /** + * Output string (Available only after visiting) + */ + public get outputStr(){ + return this.outputStrArray.join(''); + } + + + defaultResult() {} + + visitLoopStmt(ctx:LoopStmtContext){ + while((this.cells.get(this.ptr)??0)!==0){ + this.visitChildren(ctx); + } + } + visitPtrLeft() { + + --this.ptr; + } + visitPtrRight() { + ++this.ptr; + } + visitPtrIncr() { + + const val = this.cells.get(this.ptr); + if (val === undefined) { + this.cells.set(this.ptr, 1); + } else if(val===255){ + this.cells.delete(this.ptr); + }else{ + this.cells.set(this.ptr, val + 1); + } + } + visitPtrDecr() { + // console.log('down',this.ptr,this.cells); + + const val = this.cells.get(this.ptr); + if (val === undefined || val === 0) { + this.cells.set(this.ptr, 255); + } else if(val===1){ + this.cells.delete(this.ptr); + }else{ + this.cells.set(this.ptr, val - 1); + } + } + visitOutputStmt() { + const val = this.cells.get(this.ptr)??0; + const str = String.fromCharCode(val); + // console.log('op',str); + this.outputStrArray.push(str); + } + + visitInputStmt(){ + //get char + const char = this.input.charCodeAt(this.inputPtr)??0; + //increment the input pointer after this + this.inputPtr++; + this.cells.set(this.ptr,char); + } +} diff --git a/client/src/bfGrammar.ts b/client/src/bfGrammar.ts new file mode 100644 index 0000000..f55fde3 --- /dev/null +++ b/client/src/bfGrammar.ts @@ -0,0 +1,56 @@ +import { CharStreams, CommonTokenStream, RecognitionException } from 'antlr4ts'; +import { DiagnosticSeverity } from 'vscode-languageserver-types'; +import { bfLexer } from './generated/bfLexer'; +import { bfParser } from './generated/bfParser'; + + +export interface TranslationError { + line: number; + charPositionInLine: number; + msg: string; + source?: any; + type: DiagnosticSeverity; + error?: RecognitionException; +} + +export function getTree(str: string, fn: string) { + const charStreams = CharStreams.fromString(str, fn); + const lexer = new bfLexer(charStreams); + // const errorListener = this.errorManager.newErrorListener(); + const issues: TranslationError[] = []; + // remove the error listener. We want to put our own + lexer.removeErrorListeners(); + lexer.addErrorListener({ + syntaxError(source, o, line, charPositionInLine, msg, error) { + issues.push({ + line, + charPositionInLine, + msg, + type: DiagnosticSeverity.Error, + source, + error, + }); + }, + }); + + const tokenStreams = new CommonTokenStream(lexer); + const parser = new bfParser(tokenStreams); + + // remove the error listener. We want to put our own + parser.removeErrorListeners(); + parser.addErrorListener({ + syntaxError(source, o, line, charPositionInLine, msg, error) { + issues.push({ + line, + charPositionInLine, + msg, + type: DiagnosticSeverity.Error, + source, + error, + }); + }, + }); + const tree = parser.program(); + + return { tree, issues, tokenStreams, charStreams }; +} diff --git a/client/src/extension.ts b/client/src/extension.ts index 6cf2bd0..90c458a 100644 --- a/client/src/extension.ts +++ b/client/src/extension.ts @@ -5,7 +5,7 @@ import * as path from 'path'; import { workspace, ExtensionContext,commands, window } from 'vscode'; - +import {runBF} from './bfExecutor'; import { LanguageClient, LanguageClientOptions, @@ -42,6 +42,16 @@ export function activate(context: ExtensionContext) { documentSelector: [{ scheme: 'file', language: 'bf' }] }; + const command = 'bf.execute'; + const commandHandler = async()=>{ + const text= window.activeTextEditor.document.getText(); + const fn = window.activeTextEditor.document.fileName; + const input = await window.showInputBox({prompt:'Enter input (If not enough, program will assume 0)'}); + const output = await runBF(text,fn,input); + await window.showInformationMessage(`Output: ${output}`); + }; + + context.subscriptions.push(commands.registerCommand(command,commandHandler)); // Create the language client and start the client. client = new LanguageClient( diff --git a/client/src/generated/bf.interp b/client/src/generated/bf.interp new file mode 100644 index 0000000..d0af5fe --- /dev/null +++ b/client/src/generated/bf.interp @@ -0,0 +1,40 @@ +token literal names: +null +'[' +']' +null +',' +'.' +'-' +'+' +'<' +'>' +null +null + +token symbolic names: +null +LOOPSTART +LOOPEND +NUMBER +INPUT +OUTPUT +DEC +INC +LEFT +RIGHT +EVERYTHING_ELSE +WS + +rule names: +program +statements +eligibleStmt +numberedStmt +stmt +loopStmt +basicStmt + + +atn: +[3, 51485, 51898, 1421, 44986, 20307, 1543, 60043, 49729, 3, 13, 49, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 3, 2, 3, 2, 3, 2, 3, 3, 7, 3, 21, 10, 3, 12, 3, 14, 3, 24, 11, 3, 3, 4, 3, 4, 5, 4, 28, 10, 4, 3, 5, 3, 5, 3, 5, 3, 6, 3, 6, 5, 6, 35, 10, 6, 3, 7, 3, 7, 3, 7, 3, 7, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 5, 8, 47, 10, 8, 3, 8, 2, 2, 2, 9, 2, 2, 4, 2, 6, 2, 8, 2, 10, 2, 12, 2, 14, 2, 2, 2, 2, 49, 2, 16, 3, 2, 2, 2, 4, 22, 3, 2, 2, 2, 6, 27, 3, 2, 2, 2, 8, 29, 3, 2, 2, 2, 10, 34, 3, 2, 2, 2, 12, 36, 3, 2, 2, 2, 14, 46, 3, 2, 2, 2, 16, 17, 5, 4, 3, 2, 17, 18, 7, 2, 2, 3, 18, 3, 3, 2, 2, 2, 19, 21, 5, 6, 4, 2, 20, 19, 3, 2, 2, 2, 21, 24, 3, 2, 2, 2, 22, 20, 3, 2, 2, 2, 22, 23, 3, 2, 2, 2, 23, 5, 3, 2, 2, 2, 24, 22, 3, 2, 2, 2, 25, 28, 5, 10, 6, 2, 26, 28, 5, 8, 5, 2, 27, 25, 3, 2, 2, 2, 27, 26, 3, 2, 2, 2, 28, 7, 3, 2, 2, 2, 29, 30, 5, 10, 6, 2, 30, 31, 7, 5, 2, 2, 31, 9, 3, 2, 2, 2, 32, 35, 5, 14, 8, 2, 33, 35, 5, 12, 7, 2, 34, 32, 3, 2, 2, 2, 34, 33, 3, 2, 2, 2, 35, 11, 3, 2, 2, 2, 36, 37, 7, 3, 2, 2, 37, 38, 5, 4, 3, 2, 38, 39, 7, 4, 2, 2, 39, 13, 3, 2, 2, 2, 40, 47, 7, 9, 2, 2, 41, 47, 7, 8, 2, 2, 42, 47, 7, 10, 2, 2, 43, 47, 7, 11, 2, 2, 44, 47, 7, 6, 2, 2, 45, 47, 7, 7, 2, 2, 46, 40, 3, 2, 2, 2, 46, 41, 3, 2, 2, 2, 46, 42, 3, 2, 2, 2, 46, 43, 3, 2, 2, 2, 46, 44, 3, 2, 2, 2, 46, 45, 3, 2, 2, 2, 47, 15, 3, 2, 2, 2, 6, 22, 27, 34, 46] \ No newline at end of file diff --git a/client/src/generated/bf.tokens b/client/src/generated/bf.tokens new file mode 100644 index 0000000..b69dc23 --- /dev/null +++ b/client/src/generated/bf.tokens @@ -0,0 +1,19 @@ +LOOPSTART=1 +LOOPEND=2 +NUMBER=3 +INPUT=4 +OUTPUT=5 +DEC=6 +INC=7 +LEFT=8 +RIGHT=9 +EVERYTHING_ELSE=10 +WS=11 +'['=1 +']'=2 +','=4 +'.'=5 +'-'=6 +'+'=7 +'<'=8 +'>'=9 diff --git a/client/src/generated/bfLexer.interp b/client/src/generated/bfLexer.interp new file mode 100644 index 0000000..aa965da --- /dev/null +++ b/client/src/generated/bfLexer.interp @@ -0,0 +1,50 @@ +token literal names: +null +'[' +']' +null +',' +'.' +'-' +'+' +'<' +'>' +null +null + +token symbolic names: +null +LOOPSTART +LOOPEND +NUMBER +INPUT +OUTPUT +DEC +INC +LEFT +RIGHT +EVERYTHING_ELSE +WS + +rule names: +LOOPSTART +LOOPEND +NUMBER +INPUT +OUTPUT +DEC +INC +LEFT +RIGHT +EVERYTHING_ELSE +WS + +channel names: +DEFAULT_TOKEN_CHANNEL +HIDDEN + +mode names: +DEFAULT_MODE + +atn: +[3, 51485, 51898, 1421, 44986, 20307, 1543, 60043, 49729, 2, 13, 54, 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 3, 2, 3, 2, 3, 3, 3, 3, 3, 4, 6, 4, 31, 10, 4, 13, 4, 14, 4, 32, 3, 5, 3, 5, 3, 6, 3, 6, 3, 7, 3, 7, 3, 8, 3, 8, 3, 9, 3, 9, 3, 10, 3, 10, 3, 11, 3, 11, 3, 11, 3, 11, 3, 12, 3, 12, 3, 12, 3, 12, 2, 2, 2, 13, 3, 2, 3, 5, 2, 4, 7, 2, 5, 9, 2, 6, 11, 2, 7, 13, 2, 8, 15, 2, 9, 17, 2, 10, 19, 2, 11, 21, 2, 12, 23, 2, 13, 3, 2, 4, 3, 2, 50, 59, 5, 2, 12, 12, 15, 15, 34, 34, 2, 54, 2, 3, 3, 2, 2, 2, 2, 5, 3, 2, 2, 2, 2, 7, 3, 2, 2, 2, 2, 9, 3, 2, 2, 2, 2, 11, 3, 2, 2, 2, 2, 13, 3, 2, 2, 2, 2, 15, 3, 2, 2, 2, 2, 17, 3, 2, 2, 2, 2, 19, 3, 2, 2, 2, 2, 21, 3, 2, 2, 2, 2, 23, 3, 2, 2, 2, 3, 25, 3, 2, 2, 2, 5, 27, 3, 2, 2, 2, 7, 30, 3, 2, 2, 2, 9, 34, 3, 2, 2, 2, 11, 36, 3, 2, 2, 2, 13, 38, 3, 2, 2, 2, 15, 40, 3, 2, 2, 2, 17, 42, 3, 2, 2, 2, 19, 44, 3, 2, 2, 2, 21, 46, 3, 2, 2, 2, 23, 50, 3, 2, 2, 2, 25, 26, 7, 93, 2, 2, 26, 4, 3, 2, 2, 2, 27, 28, 7, 95, 2, 2, 28, 6, 3, 2, 2, 2, 29, 31, 9, 2, 2, 2, 30, 29, 3, 2, 2, 2, 31, 32, 3, 2, 2, 2, 32, 30, 3, 2, 2, 2, 32, 33, 3, 2, 2, 2, 33, 8, 3, 2, 2, 2, 34, 35, 7, 46, 2, 2, 35, 10, 3, 2, 2, 2, 36, 37, 7, 48, 2, 2, 37, 12, 3, 2, 2, 2, 38, 39, 7, 47, 2, 2, 39, 14, 3, 2, 2, 2, 40, 41, 7, 45, 2, 2, 41, 16, 3, 2, 2, 2, 42, 43, 7, 62, 2, 2, 43, 18, 3, 2, 2, 2, 44, 45, 7, 64, 2, 2, 45, 20, 3, 2, 2, 2, 46, 47, 11, 2, 2, 2, 47, 48, 3, 2, 2, 2, 48, 49, 8, 11, 2, 2, 49, 22, 3, 2, 2, 2, 50, 51, 9, 3, 2, 2, 51, 52, 3, 2, 2, 2, 52, 53, 8, 12, 3, 2, 53, 24, 3, 2, 2, 2, 4, 2, 32, 4, 2, 3, 2, 8, 2, 2] \ No newline at end of file diff --git a/client/src/generated/bfLexer.tokens b/client/src/generated/bfLexer.tokens new file mode 100644 index 0000000..b69dc23 --- /dev/null +++ b/client/src/generated/bfLexer.tokens @@ -0,0 +1,19 @@ +LOOPSTART=1 +LOOPEND=2 +NUMBER=3 +INPUT=4 +OUTPUT=5 +DEC=6 +INC=7 +LEFT=8 +RIGHT=9 +EVERYTHING_ELSE=10 +WS=11 +'['=1 +']'=2 +','=4 +'.'=5 +'-'=6 +'+'=7 +'<'=8 +'>'=9 diff --git a/client/src/generated/bfLexer.ts b/client/src/generated/bfLexer.ts new file mode 100644 index 0000000..d8fb7d8 --- /dev/null +++ b/client/src/generated/bfLexer.ts @@ -0,0 +1,119 @@ +// Generated from bf.g4 by ANTLR 4.9.0-SNAPSHOT + + +import { ATN } from "antlr4ts/atn/ATN"; +import { ATNDeserializer } from "antlr4ts/atn/ATNDeserializer"; +import { CharStream } from "antlr4ts/CharStream"; +import { Lexer } from "antlr4ts/Lexer"; +import { LexerATNSimulator } from "antlr4ts/atn/LexerATNSimulator"; +import { NotNull } from "antlr4ts/Decorators"; +import { Override } from "antlr4ts/Decorators"; +import { RuleContext } from "antlr4ts/RuleContext"; +import { Vocabulary } from "antlr4ts/Vocabulary"; +import { VocabularyImpl } from "antlr4ts/VocabularyImpl"; + +import * as Utils from "antlr4ts/misc/Utils"; + + +export class bfLexer extends Lexer { + public static readonly LOOPSTART = 1; + public static readonly LOOPEND = 2; + public static readonly NUMBER = 3; + public static readonly INPUT = 4; + public static readonly OUTPUT = 5; + public static readonly DEC = 6; + public static readonly INC = 7; + public static readonly LEFT = 8; + public static readonly RIGHT = 9; + public static readonly EVERYTHING_ELSE = 10; + public static readonly WS = 11; + + // tslint:disable:no-trailing-whitespace + public static readonly channelNames: string[] = [ + "DEFAULT_TOKEN_CHANNEL", "HIDDEN", + ]; + + // tslint:disable:no-trailing-whitespace + public static readonly modeNames: string[] = [ + "DEFAULT_MODE", + ]; + + public static readonly ruleNames: string[] = [ + "LOOPSTART", "LOOPEND", "NUMBER", "INPUT", "OUTPUT", "DEC", "INC", "LEFT", + "RIGHT", "EVERYTHING_ELSE", "WS", + ]; + + private static readonly _LITERAL_NAMES: Array = [ + undefined, "'['", "']'", undefined, "','", "'.'", "'-'", "'+'", "'<'", + "'>'", + ]; + private static readonly _SYMBOLIC_NAMES: Array = [ + undefined, "LOOPSTART", "LOOPEND", "NUMBER", "INPUT", "OUTPUT", "DEC", + "INC", "LEFT", "RIGHT", "EVERYTHING_ELSE", "WS", + ]; + public static readonly VOCABULARY: Vocabulary = new VocabularyImpl(bfLexer._LITERAL_NAMES, bfLexer._SYMBOLIC_NAMES, []); + + // @Override + // @NotNull + public get vocabulary(): Vocabulary { + return bfLexer.VOCABULARY; + } + // tslint:enable:no-trailing-whitespace + + + constructor(input: CharStream) { + super(input); + this._interp = new LexerATNSimulator(bfLexer._ATN, this); + } + + // @Override + public get grammarFileName(): string { return "bf.g4"; } + + // @Override + public get ruleNames(): string[] { return bfLexer.ruleNames; } + + // @Override + public get serializedATN(): string { return bfLexer._serializedATN; } + + // @Override + public get channelNames(): string[] { return bfLexer.channelNames; } + + // @Override + public get modeNames(): string[] { return bfLexer.modeNames; } + + public static readonly _serializedATN: string = + "\x03\uC91D\uCABA\u058D\uAFBA\u4F53\u0607\uEA8B\uC241\x02\r6\b\x01\x04" + + "\x02\t\x02\x04\x03\t\x03\x04\x04\t\x04\x04\x05\t\x05\x04\x06\t\x06\x04" + + "\x07\t\x07\x04\b\t\b\x04\t\t\t\x04\n\t\n\x04\v\t\v\x04\f\t\f\x03\x02\x03" + + "\x02\x03\x03\x03\x03\x03\x04\x06\x04\x1F\n\x04\r\x04\x0E\x04 \x03\x05" + + "\x03\x05\x03\x06\x03\x06\x03\x07\x03\x07\x03\b\x03\b\x03\t\x03\t\x03\n" + + "\x03\n\x03\v\x03\v\x03\v\x03\v\x03\f\x03\f\x03\f\x03\f\x02\x02\x02\r\x03" + + "\x02\x03\x05\x02\x04\x07\x02\x05\t\x02\x06\v\x02\x07\r\x02\b\x0F\x02\t" + + "\x11\x02\n\x13\x02\v\x15\x02\f\x17\x02\r\x03\x02\x04\x03\x022;\x05\x02" + + "\f\f\x0F\x0F\"\"\x026\x02\x03\x03\x02\x02\x02\x02\x05\x03\x02\x02\x02" + + "\x02\x07\x03\x02\x02\x02\x02\t\x03\x02\x02\x02\x02\v\x03\x02\x02\x02\x02" + + "\r\x03\x02\x02\x02\x02\x0F\x03\x02\x02\x02\x02\x11\x03\x02\x02\x02\x02" + + "\x13\x03\x02\x02\x02\x02\x15\x03\x02\x02\x02\x02\x17\x03\x02\x02\x02\x03" + + "\x19\x03\x02\x02\x02\x05\x1B\x03\x02\x02\x02\x07\x1E\x03\x02\x02\x02\t" + + "\"\x03\x02\x02\x02\v$\x03\x02\x02\x02\r&\x03\x02\x02\x02\x0F(\x03\x02" + + "\x02\x02\x11*\x03\x02\x02\x02\x13,\x03\x02\x02\x02\x15.\x03\x02\x02\x02" + + "\x172\x03\x02\x02\x02\x19\x1A\x07]\x02\x02\x1A\x04\x03\x02\x02\x02\x1B" + + "\x1C\x07_\x02\x02\x1C\x06\x03\x02\x02\x02\x1D\x1F\t\x02\x02\x02\x1E\x1D" + + "\x03\x02\x02\x02\x1F \x03\x02\x02\x02 \x1E\x03\x02\x02\x02 !\x03\x02\x02" + + "\x02!\b\x03\x02\x02\x02\"#\x07.\x02\x02#\n\x03\x02\x02\x02$%\x070\x02" + + "\x02%\f\x03\x02\x02\x02&\'\x07/\x02\x02\'\x0E\x03\x02\x02\x02()\x07-\x02" + + "\x02)\x10\x03\x02\x02\x02*+\x07>\x02\x02+\x12\x03\x02\x02\x02,-\x07@\x02" + + "\x02-\x14\x03\x02\x02\x02./\v\x02\x02\x02/0\x03\x02\x02\x0201\b\v\x02" + + "\x021\x16\x03\x02\x02\x0223\t\x03\x02\x0234\x03\x02\x02\x0245\b\f\x03" + + "\x025\x18\x03\x02\x02\x02\x04\x02 \x04\x02\x03\x02\b\x02\x02"; + public static __ATN: ATN; + public static get _ATN(): ATN { + if (!bfLexer.__ATN) { + bfLexer.__ATN = new ATNDeserializer().deserialize(Utils.toCharArray(bfLexer._serializedATN)); + } + + return bfLexer.__ATN; + } + +} + diff --git a/client/src/generated/bfParser.ts b/client/src/generated/bfParser.ts new file mode 100644 index 0000000..e0e0749 --- /dev/null +++ b/client/src/generated/bfParser.ts @@ -0,0 +1,638 @@ +// Generated from bf.g4 by ANTLR 4.9.0-SNAPSHOT + + +import { ATN } from "antlr4ts/atn/ATN"; +import { ATNDeserializer } from "antlr4ts/atn/ATNDeserializer"; +import { FailedPredicateException } from "antlr4ts/FailedPredicateException"; +import { NotNull } from "antlr4ts/Decorators"; +import { NoViableAltException } from "antlr4ts/NoViableAltException"; +import { Override } from "antlr4ts/Decorators"; +import { Parser } from "antlr4ts/Parser"; +import { ParserRuleContext } from "antlr4ts/ParserRuleContext"; +import { ParserATNSimulator } from "antlr4ts/atn/ParserATNSimulator"; +import { ParseTreeListener } from "antlr4ts/tree/ParseTreeListener"; +import { ParseTreeVisitor } from "antlr4ts/tree/ParseTreeVisitor"; +import { RecognitionException } from "antlr4ts/RecognitionException"; +import { RuleContext } from "antlr4ts/RuleContext"; +//import { RuleVersion } from "antlr4ts/RuleVersion"; +import { TerminalNode } from "antlr4ts/tree/TerminalNode"; +import { Token } from "antlr4ts/Token"; +import { TokenStream } from "antlr4ts/TokenStream"; +import { Vocabulary } from "antlr4ts/Vocabulary"; +import { VocabularyImpl } from "antlr4ts/VocabularyImpl"; + +import * as Utils from "antlr4ts/misc/Utils"; + +import { bfVisitor } from "./bfVisitor"; + + +export class bfParser extends Parser { + public static readonly LOOPSTART = 1; + public static readonly LOOPEND = 2; + public static readonly NUMBER = 3; + public static readonly INPUT = 4; + public static readonly OUTPUT = 5; + public static readonly DEC = 6; + public static readonly INC = 7; + public static readonly LEFT = 8; + public static readonly RIGHT = 9; + public static readonly EVERYTHING_ELSE = 10; + public static readonly WS = 11; + public static readonly RULE_program = 0; + public static readonly RULE_statements = 1; + public static readonly RULE_eligibleStmt = 2; + public static readonly RULE_numberedStmt = 3; + public static readonly RULE_stmt = 4; + public static readonly RULE_loopStmt = 5; + public static readonly RULE_basicStmt = 6; + // tslint:disable:no-trailing-whitespace + public static readonly ruleNames: string[] = [ + "program", "statements", "eligibleStmt", "numberedStmt", "stmt", "loopStmt", + "basicStmt", + ]; + + private static readonly _LITERAL_NAMES: Array = [ + undefined, "'['", "']'", undefined, "','", "'.'", "'-'", "'+'", "'<'", + "'>'", + ]; + private static readonly _SYMBOLIC_NAMES: Array = [ + undefined, "LOOPSTART", "LOOPEND", "NUMBER", "INPUT", "OUTPUT", "DEC", + "INC", "LEFT", "RIGHT", "EVERYTHING_ELSE", "WS", + ]; + public static readonly VOCABULARY: Vocabulary = new VocabularyImpl(bfParser._LITERAL_NAMES, bfParser._SYMBOLIC_NAMES, []); + + // @Override + // @NotNull + public get vocabulary(): Vocabulary { + return bfParser.VOCABULARY; + } + // tslint:enable:no-trailing-whitespace + + // @Override + public get grammarFileName(): string { return "bf.g4"; } + + // @Override + public get ruleNames(): string[] { return bfParser.ruleNames; } + + // @Override + public get serializedATN(): string { return bfParser._serializedATN; } + + protected createFailedPredicateException(predicate?: string, message?: string): FailedPredicateException { + return new FailedPredicateException(this, predicate, message); + } + + constructor(input: TokenStream) { + super(input); + this._interp = new ParserATNSimulator(bfParser._ATN, this); + } + // @RuleVersion(0) + public program(): ProgramContext { + let _localctx: ProgramContext = new ProgramContext(this._ctx, this.state); + this.enterRule(_localctx, 0, bfParser.RULE_program); + try { + this.enterOuterAlt(_localctx, 1); + { + this.state = 14; + this.statements(); + this.state = 15; + this.match(bfParser.EOF); + } + } + catch (re) { + if (re instanceof RecognitionException) { + _localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } + finally { + this.exitRule(); + } + return _localctx; + } + // @RuleVersion(0) + public statements(): StatementsContext { + let _localctx: StatementsContext = new StatementsContext(this._ctx, this.state); + this.enterRule(_localctx, 2, bfParser.RULE_statements); + let _la: number; + try { + this.enterOuterAlt(_localctx, 1); + { + this.state = 20; + this._errHandler.sync(this); + _la = this._input.LA(1); + while ((((_la) & ~0x1F) === 0 && ((1 << _la) & ((1 << bfParser.LOOPSTART) | (1 << bfParser.INPUT) | (1 << bfParser.OUTPUT) | (1 << bfParser.DEC) | (1 << bfParser.INC) | (1 << bfParser.LEFT) | (1 << bfParser.RIGHT))) !== 0)) { + { + { + this.state = 17; + this.eligibleStmt(); + } + } + this.state = 22; + this._errHandler.sync(this); + _la = this._input.LA(1); + } + } + } + catch (re) { + if (re instanceof RecognitionException) { + _localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } + finally { + this.exitRule(); + } + return _localctx; + } + // @RuleVersion(0) + public eligibleStmt(): EligibleStmtContext { + let _localctx: EligibleStmtContext = new EligibleStmtContext(this._ctx, this.state); + this.enterRule(_localctx, 4, bfParser.RULE_eligibleStmt); + try { + this.state = 25; + this._errHandler.sync(this); + switch ( this.interpreter.adaptivePredict(this._input, 1, this._ctx) ) { + case 1: + this.enterOuterAlt(_localctx, 1); + { + this.state = 23; + this.stmt(); + } + break; + + case 2: + this.enterOuterAlt(_localctx, 2); + { + this.state = 24; + this.numberedStmt(); + } + break; + } + } + catch (re) { + if (re instanceof RecognitionException) { + _localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } + finally { + this.exitRule(); + } + return _localctx; + } + // @RuleVersion(0) + public numberedStmt(): NumberedStmtContext { + let _localctx: NumberedStmtContext = new NumberedStmtContext(this._ctx, this.state); + this.enterRule(_localctx, 6, bfParser.RULE_numberedStmt); + try { + this.enterOuterAlt(_localctx, 1); + { + this.state = 27; + this.stmt(); + this.state = 28; + this.match(bfParser.NUMBER); + } + } + catch (re) { + if (re instanceof RecognitionException) { + _localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } + finally { + this.exitRule(); + } + return _localctx; + } + // @RuleVersion(0) + public stmt(): StmtContext { + let _localctx: StmtContext = new StmtContext(this._ctx, this.state); + this.enterRule(_localctx, 8, bfParser.RULE_stmt); + try { + this.state = 32; + this._errHandler.sync(this); + switch (this._input.LA(1)) { + case bfParser.INPUT: + case bfParser.OUTPUT: + case bfParser.DEC: + case bfParser.INC: + case bfParser.LEFT: + case bfParser.RIGHT: + this.enterOuterAlt(_localctx, 1); + { + this.state = 30; + this.basicStmt(); + } + break; + case bfParser.LOOPSTART: + this.enterOuterAlt(_localctx, 2); + { + this.state = 31; + this.loopStmt(); + } + break; + default: + throw new NoViableAltException(this); + } + } + catch (re) { + if (re instanceof RecognitionException) { + _localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } + finally { + this.exitRule(); + } + return _localctx; + } + // @RuleVersion(0) + public loopStmt(): LoopStmtContext { + let _localctx: LoopStmtContext = new LoopStmtContext(this._ctx, this.state); + this.enterRule(_localctx, 10, bfParser.RULE_loopStmt); + try { + this.enterOuterAlt(_localctx, 1); + { + this.state = 34; + this.match(bfParser.LOOPSTART); + this.state = 35; + this.statements(); + this.state = 36; + this.match(bfParser.LOOPEND); + } + } + catch (re) { + if (re instanceof RecognitionException) { + _localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } + finally { + this.exitRule(); + } + return _localctx; + } + // @RuleVersion(0) + public basicStmt(): BasicStmtContext { + let _localctx: BasicStmtContext = new BasicStmtContext(this._ctx, this.state); + this.enterRule(_localctx, 12, bfParser.RULE_basicStmt); + try { + this.state = 44; + this._errHandler.sync(this); + switch (this._input.LA(1)) { + case bfParser.INC: + _localctx = new PtrIncrContext(_localctx); + this.enterOuterAlt(_localctx, 1); + { + this.state = 38; + this.match(bfParser.INC); + } + break; + case bfParser.DEC: + _localctx = new PtrDecrContext(_localctx); + this.enterOuterAlt(_localctx, 2); + { + this.state = 39; + this.match(bfParser.DEC); + } + break; + case bfParser.LEFT: + _localctx = new PtrLeftContext(_localctx); + this.enterOuterAlt(_localctx, 3); + { + this.state = 40; + this.match(bfParser.LEFT); + } + break; + case bfParser.RIGHT: + _localctx = new PtrRightContext(_localctx); + this.enterOuterAlt(_localctx, 4); + { + this.state = 41; + this.match(bfParser.RIGHT); + } + break; + case bfParser.INPUT: + _localctx = new InputStmtContext(_localctx); + this.enterOuterAlt(_localctx, 5); + { + this.state = 42; + this.match(bfParser.INPUT); + } + break; + case bfParser.OUTPUT: + _localctx = new OutputStmtContext(_localctx); + this.enterOuterAlt(_localctx, 6); + { + this.state = 43; + this.match(bfParser.OUTPUT); + } + break; + default: + throw new NoViableAltException(this); + } + } + catch (re) { + if (re instanceof RecognitionException) { + _localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } + finally { + this.exitRule(); + } + return _localctx; + } + + public static readonly _serializedATN: string = + "\x03\uC91D\uCABA\u058D\uAFBA\u4F53\u0607\uEA8B\uC241\x03\r1\x04\x02\t" + + "\x02\x04\x03\t\x03\x04\x04\t\x04\x04\x05\t\x05\x04\x06\t\x06\x04\x07\t" + + "\x07\x04\b\t\b\x03\x02\x03\x02\x03\x02\x03\x03\x07\x03\x15\n\x03\f\x03" + + "\x0E\x03\x18\v\x03\x03\x04\x03\x04\x05\x04\x1C\n\x04\x03\x05\x03\x05\x03" + + "\x05\x03\x06\x03\x06\x05\x06#\n\x06\x03\x07\x03\x07\x03\x07\x03\x07\x03" + + "\b\x03\b\x03\b\x03\b\x03\b\x03\b\x05\b/\n\b\x03\b\x02\x02\x02\t\x02\x02" + + "\x04\x02\x06\x02\b\x02\n\x02\f\x02\x0E\x02\x02\x02\x021\x02\x10\x03\x02" + + "\x02\x02\x04\x16\x03\x02\x02\x02\x06\x1B\x03\x02\x02\x02\b\x1D\x03\x02" + + "\x02\x02\n\"\x03\x02\x02\x02\f$\x03\x02\x02\x02\x0E.\x03\x02\x02\x02\x10" + + "\x11\x05\x04\x03\x02\x11\x12\x07\x02\x02\x03\x12\x03\x03\x02\x02\x02\x13" + + "\x15\x05\x06\x04\x02\x14\x13\x03\x02\x02\x02\x15\x18\x03\x02\x02\x02\x16" + + "\x14\x03\x02\x02\x02\x16\x17\x03\x02\x02\x02\x17\x05\x03\x02\x02\x02\x18" + + "\x16\x03\x02\x02\x02\x19\x1C\x05\n\x06\x02\x1A\x1C\x05\b\x05\x02\x1B\x19" + + "\x03\x02\x02\x02\x1B\x1A\x03\x02\x02\x02\x1C\x07\x03\x02\x02\x02\x1D\x1E" + + "\x05\n\x06\x02\x1E\x1F\x07\x05\x02\x02\x1F\t\x03\x02\x02\x02 #\x05\x0E" + + "\b\x02!#\x05\f\x07\x02\" \x03\x02\x02\x02\"!\x03\x02\x02\x02#\v\x03\x02" + + "\x02\x02$%\x07\x03\x02\x02%&\x05\x04\x03\x02&\'\x07\x04\x02\x02\'\r\x03" + + "\x02\x02\x02(/\x07\t\x02\x02)/\x07\b\x02\x02*/\x07\n\x02\x02+/\x07\v\x02" + + "\x02,/\x07\x06\x02\x02-/\x07\x07\x02\x02.(\x03\x02\x02\x02.)\x03\x02\x02" + + "\x02.*\x03\x02\x02\x02.+\x03\x02\x02\x02.,\x03\x02\x02\x02.-\x03\x02\x02" + + "\x02/\x0F\x03\x02\x02\x02\x06\x16\x1B\"."; + public static __ATN: ATN; + public static get _ATN(): ATN { + if (!bfParser.__ATN) { + bfParser.__ATN = new ATNDeserializer().deserialize(Utils.toCharArray(bfParser._serializedATN)); + } + + return bfParser.__ATN; + } + +} + +export class ProgramContext extends ParserRuleContext { + public statements(): StatementsContext { + return this.getRuleContext(0, StatementsContext); + } + public EOF(): TerminalNode { return this.getToken(bfParser.EOF, 0); } + constructor(parent: ParserRuleContext | undefined, invokingState: number) { + super(parent, invokingState); + } + // @Override + public get ruleIndex(): number { return bfParser.RULE_program; } + // @Override + public accept(visitor: bfVisitor): Result { + if (visitor.visitProgram) { + return visitor.visitProgram(this); + } else { + return visitor.visitChildren(this); + } + } +} + + +export class StatementsContext extends ParserRuleContext { + public eligibleStmt(): EligibleStmtContext[]; + public eligibleStmt(i: number): EligibleStmtContext; + public eligibleStmt(i?: number): EligibleStmtContext | EligibleStmtContext[] { + if (i === undefined) { + return this.getRuleContexts(EligibleStmtContext); + } else { + return this.getRuleContext(i, EligibleStmtContext); + } + } + constructor(parent: ParserRuleContext | undefined, invokingState: number) { + super(parent, invokingState); + } + // @Override + public get ruleIndex(): number { return bfParser.RULE_statements; } + // @Override + public accept(visitor: bfVisitor): Result { + if (visitor.visitStatements) { + return visitor.visitStatements(this); + } else { + return visitor.visitChildren(this); + } + } +} + + +export class EligibleStmtContext extends ParserRuleContext { + public stmt(): StmtContext | undefined { + return this.tryGetRuleContext(0, StmtContext); + } + public numberedStmt(): NumberedStmtContext | undefined { + return this.tryGetRuleContext(0, NumberedStmtContext); + } + constructor(parent: ParserRuleContext | undefined, invokingState: number) { + super(parent, invokingState); + } + // @Override + public get ruleIndex(): number { return bfParser.RULE_eligibleStmt; } + // @Override + public accept(visitor: bfVisitor): Result { + if (visitor.visitEligibleStmt) { + return visitor.visitEligibleStmt(this); + } else { + return visitor.visitChildren(this); + } + } +} + + +export class NumberedStmtContext extends ParserRuleContext { + public stmt(): StmtContext { + return this.getRuleContext(0, StmtContext); + } + public NUMBER(): TerminalNode { return this.getToken(bfParser.NUMBER, 0); } + constructor(parent: ParserRuleContext | undefined, invokingState: number) { + super(parent, invokingState); + } + // @Override + public get ruleIndex(): number { return bfParser.RULE_numberedStmt; } + // @Override + public accept(visitor: bfVisitor): Result { + if (visitor.visitNumberedStmt) { + return visitor.visitNumberedStmt(this); + } else { + return visitor.visitChildren(this); + } + } +} + + +export class StmtContext extends ParserRuleContext { + public basicStmt(): BasicStmtContext | undefined { + return this.tryGetRuleContext(0, BasicStmtContext); + } + public loopStmt(): LoopStmtContext | undefined { + return this.tryGetRuleContext(0, LoopStmtContext); + } + constructor(parent: ParserRuleContext | undefined, invokingState: number) { + super(parent, invokingState); + } + // @Override + public get ruleIndex(): number { return bfParser.RULE_stmt; } + // @Override + public accept(visitor: bfVisitor): Result { + if (visitor.visitStmt) { + return visitor.visitStmt(this); + } else { + return visitor.visitChildren(this); + } + } +} + + +export class LoopStmtContext extends ParserRuleContext { + public LOOPSTART(): TerminalNode { return this.getToken(bfParser.LOOPSTART, 0); } + public statements(): StatementsContext { + return this.getRuleContext(0, StatementsContext); + } + public LOOPEND(): TerminalNode { return this.getToken(bfParser.LOOPEND, 0); } + constructor(parent: ParserRuleContext | undefined, invokingState: number) { + super(parent, invokingState); + } + // @Override + public get ruleIndex(): number { return bfParser.RULE_loopStmt; } + // @Override + public accept(visitor: bfVisitor): Result { + if (visitor.visitLoopStmt) { + return visitor.visitLoopStmt(this); + } else { + return visitor.visitChildren(this); + } + } +} + + +export class BasicStmtContext extends ParserRuleContext { + constructor(parent: ParserRuleContext | undefined, invokingState: number) { + super(parent, invokingState); + } + // @Override + public get ruleIndex(): number { return bfParser.RULE_basicStmt; } + public copyFrom(ctx: BasicStmtContext): void { + super.copyFrom(ctx); + } +} +export class PtrIncrContext extends BasicStmtContext { + public INC(): TerminalNode { return this.getToken(bfParser.INC, 0); } + constructor(ctx: BasicStmtContext) { + super(ctx.parent, ctx.invokingState); + this.copyFrom(ctx); + } + // @Override + public accept(visitor: bfVisitor): Result { + if (visitor.visitPtrIncr) { + return visitor.visitPtrIncr(this); + } else { + return visitor.visitChildren(this); + } + } +} +export class PtrDecrContext extends BasicStmtContext { + public DEC(): TerminalNode { return this.getToken(bfParser.DEC, 0); } + constructor(ctx: BasicStmtContext) { + super(ctx.parent, ctx.invokingState); + this.copyFrom(ctx); + } + // @Override + public accept(visitor: bfVisitor): Result { + if (visitor.visitPtrDecr) { + return visitor.visitPtrDecr(this); + } else { + return visitor.visitChildren(this); + } + } +} +export class PtrLeftContext extends BasicStmtContext { + public LEFT(): TerminalNode { return this.getToken(bfParser.LEFT, 0); } + constructor(ctx: BasicStmtContext) { + super(ctx.parent, ctx.invokingState); + this.copyFrom(ctx); + } + // @Override + public accept(visitor: bfVisitor): Result { + if (visitor.visitPtrLeft) { + return visitor.visitPtrLeft(this); + } else { + return visitor.visitChildren(this); + } + } +} +export class PtrRightContext extends BasicStmtContext { + public RIGHT(): TerminalNode { return this.getToken(bfParser.RIGHT, 0); } + constructor(ctx: BasicStmtContext) { + super(ctx.parent, ctx.invokingState); + this.copyFrom(ctx); + } + // @Override + public accept(visitor: bfVisitor): Result { + if (visitor.visitPtrRight) { + return visitor.visitPtrRight(this); + } else { + return visitor.visitChildren(this); + } + } +} +export class InputStmtContext extends BasicStmtContext { + public INPUT(): TerminalNode { return this.getToken(bfParser.INPUT, 0); } + constructor(ctx: BasicStmtContext) { + super(ctx.parent, ctx.invokingState); + this.copyFrom(ctx); + } + // @Override + public accept(visitor: bfVisitor): Result { + if (visitor.visitInputStmt) { + return visitor.visitInputStmt(this); + } else { + return visitor.visitChildren(this); + } + } +} +export class OutputStmtContext extends BasicStmtContext { + public OUTPUT(): TerminalNode { return this.getToken(bfParser.OUTPUT, 0); } + constructor(ctx: BasicStmtContext) { + super(ctx.parent, ctx.invokingState); + this.copyFrom(ctx); + } + // @Override + public accept(visitor: bfVisitor): Result { + if (visitor.visitOutputStmt) { + return visitor.visitOutputStmt(this); + } else { + return visitor.visitChildren(this); + } + } +} + + diff --git a/client/src/generated/bfVisitor.ts b/client/src/generated/bfVisitor.ts new file mode 100644 index 0000000..4a2b145 --- /dev/null +++ b/client/src/generated/bfVisitor.ts @@ -0,0 +1,126 @@ +// Generated from bf.g4 by ANTLR 4.9.0-SNAPSHOT + + +import { ParseTreeVisitor } from "antlr4ts/tree/ParseTreeVisitor"; + +import { PtrIncrContext } from "./bfParser"; +import { PtrDecrContext } from "./bfParser"; +import { PtrLeftContext } from "./bfParser"; +import { PtrRightContext } from "./bfParser"; +import { InputStmtContext } from "./bfParser"; +import { OutputStmtContext } from "./bfParser"; +import { ProgramContext } from "./bfParser"; +import { StatementsContext } from "./bfParser"; +import { EligibleStmtContext } from "./bfParser"; +import { NumberedStmtContext } from "./bfParser"; +import { StmtContext } from "./bfParser"; +import { LoopStmtContext } from "./bfParser"; +import { BasicStmtContext } from "./bfParser"; + + +/** + * This interface defines a complete generic visitor for a parse tree produced + * by `bfParser`. + * + * @param The return type of the visit operation. Use `void` for + * operations with no return type. + */ +export interface bfVisitor extends ParseTreeVisitor { + /** + * Visit a parse tree produced by the `ptrIncr` + * labeled alternative in `bfParser.basicStmt`. + * @param ctx the parse tree + * @return the visitor result + */ + visitPtrIncr?: (ctx: PtrIncrContext) => Result; + + /** + * Visit a parse tree produced by the `ptrDecr` + * labeled alternative in `bfParser.basicStmt`. + * @param ctx the parse tree + * @return the visitor result + */ + visitPtrDecr?: (ctx: PtrDecrContext) => Result; + + /** + * Visit a parse tree produced by the `ptrLeft` + * labeled alternative in `bfParser.basicStmt`. + * @param ctx the parse tree + * @return the visitor result + */ + visitPtrLeft?: (ctx: PtrLeftContext) => Result; + + /** + * Visit a parse tree produced by the `ptrRight` + * labeled alternative in `bfParser.basicStmt`. + * @param ctx the parse tree + * @return the visitor result + */ + visitPtrRight?: (ctx: PtrRightContext) => Result; + + /** + * Visit a parse tree produced by the `inputStmt` + * labeled alternative in `bfParser.basicStmt`. + * @param ctx the parse tree + * @return the visitor result + */ + visitInputStmt?: (ctx: InputStmtContext) => Result; + + /** + * Visit a parse tree produced by the `outputStmt` + * labeled alternative in `bfParser.basicStmt`. + * @param ctx the parse tree + * @return the visitor result + */ + visitOutputStmt?: (ctx: OutputStmtContext) => Result; + + /** + * Visit a parse tree produced by `bfParser.program`. + * @param ctx the parse tree + * @return the visitor result + */ + visitProgram?: (ctx: ProgramContext) => Result; + + /** + * Visit a parse tree produced by `bfParser.statements`. + * @param ctx the parse tree + * @return the visitor result + */ + visitStatements?: (ctx: StatementsContext) => Result; + + /** + * Visit a parse tree produced by `bfParser.eligibleStmt`. + * @param ctx the parse tree + * @return the visitor result + */ + visitEligibleStmt?: (ctx: EligibleStmtContext) => Result; + + /** + * Visit a parse tree produced by `bfParser.numberedStmt`. + * @param ctx the parse tree + * @return the visitor result + */ + visitNumberedStmt?: (ctx: NumberedStmtContext) => Result; + + /** + * Visit a parse tree produced by `bfParser.stmt`. + * @param ctx the parse tree + * @return the visitor result + */ + visitStmt?: (ctx: StmtContext) => Result; + + /** + * Visit a parse tree produced by `bfParser.loopStmt`. + * @param ctx the parse tree + * @return the visitor result + */ + visitLoopStmt?: (ctx: LoopStmtContext) => Result; + + /** + * Visit a parse tree produced by `bfParser.basicStmt`. + * @param ctx the parse tree + * @return the visitor result + */ + visitBasicStmt?: (ctx: BasicStmtContext) => Result; +} + diff --git a/package.json b/package.json index b86062b..5116903 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,12 @@ "path": "./syntaxes/bf.tmLanguage.json" } ], - "commands": [], + "commands": [{ + "command": "bf.execute", + "title": "BF: Execute", + "when": "editorLangId == bf", + "enablement": "editorLangId == bf" + }], "configuration": { "type": "object", "title": "Configurable properties", diff --git a/server/src/server.ts b/server/src/server.ts index 4aaf214..beb1f66 100644 --- a/server/src/server.ts +++ b/server/src/server.ts @@ -21,6 +21,7 @@ import { // import * as path from 'path'; import { TextDocument } from 'vscode-languageserver-textdocument'; +// import { getTree } from './bfGrammar'; // Create a connection for the server. The connection uses Node's IPC as a transport. // Also include all preview / proposed LSP features. @@ -149,19 +150,19 @@ documents.onDidSave(change => { const validateBrackets = (text: string) => { let count = 0, lp: number[] = [],issues:number[]=[]; - const textsplit = text.split(``); + const textsplit = text.split(''); textsplit.forEach((x, i) => { - if (x == '[' || x == ']') { + if (x === '[' || x === ']') { - if (x == '[') lp.push(i); - if (x == ']') {if(lp.length==0) issues.push(i);lp.pop();} + if (x === '[') {lp.push(i);} + if (x === ']') {if(lp.length===0) {issues.push(i);}lp.pop();} } }); - return [...lp,...issues] + return [...lp,...issues]; }; async function validateTextDocument(textDocument: TextDocument): Promise { @@ -174,15 +175,15 @@ async function validateTextDocument(textDocument: TextDocument): Promise { let diagnostics: Diagnostic[] = []; const issues = validateBrackets(text); - diagnostics.push(...issues.map(e => ({ - message: 'Brackets unmatched', - range:{ - start: textDocument.positionAt(e), - end: textDocument.positionAt(e+1), - }, - severity:DiagnosticSeverity.Error, - code:'[ and ]', - }))); + diagnostics.push(...issues.map(e => ({ + message: 'Brackets unmatched', + range:{ + start: textDocument.positionAt(e), + end: textDocument.positionAt(e+1), + }, + severity:DiagnosticSeverity.Error, + code:'[ and ]', + }))); // diagnostics.push({ // message: 'Brackets not matched',