[client] exeute command
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
client/bf.g4
|
||||
.vscode/**
|
||||
**/*.ts
|
||||
**/*.map
|
||||
|
49
client/bf.g4
Normal file
49
client/bf.g4
Normal file
@@ -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;
|
||||
|
27
client/package-lock.json
generated
27
client/package-lock.json
generated
@@ -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",
|
||||
|
@@ -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/"
|
||||
}
|
||||
}
|
||||
|
117
client/src/bfExecutor.ts
Normal file
117
client/src/bfExecutor.ts
Normal file
@@ -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<void>
|
||||
implements bfVisitor<void> {
|
||||
|
||||
/**
|
||||
*
|
||||
* @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<number, number> = 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);
|
||||
}
|
||||
}
|
56
client/src/bfGrammar.ts
Normal file
56
client/src/bfGrammar.ts
Normal file
@@ -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 };
|
||||
}
|
@@ -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(
|
||||
|
40
client/src/generated/bf.interp
Normal file
40
client/src/generated/bf.interp
Normal file
@@ -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]
|
19
client/src/generated/bf.tokens
Normal file
19
client/src/generated/bf.tokens
Normal file
@@ -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
|
50
client/src/generated/bfLexer.interp
Normal file
50
client/src/generated/bfLexer.interp
Normal file
@@ -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]
|
19
client/src/generated/bfLexer.tokens
Normal file
19
client/src/generated/bfLexer.tokens
Normal file
@@ -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
|
119
client/src/generated/bfLexer.ts
Normal file
119
client/src/generated/bfLexer.ts
Normal file
@@ -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<string | undefined> = [
|
||||
undefined, "'['", "']'", undefined, "','", "'.'", "'-'", "'+'", "'<'",
|
||||
"'>'",
|
||||
];
|
||||
private static readonly _SYMBOLIC_NAMES: Array<string | undefined> = [
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
638
client/src/generated/bfParser.ts
Normal file
638
client/src/generated/bfParser.ts
Normal file
@@ -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<string | undefined> = [
|
||||
undefined, "'['", "']'", undefined, "','", "'.'", "'-'", "'+'", "'<'",
|
||||
"'>'",
|
||||
];
|
||||
private static readonly _SYMBOLIC_NAMES: Array<string | undefined> = [
|
||||
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<Result>(visitor: bfVisitor<Result>): 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<Result>(visitor: bfVisitor<Result>): 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<Result>(visitor: bfVisitor<Result>): 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<Result>(visitor: bfVisitor<Result>): 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<Result>(visitor: bfVisitor<Result>): 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<Result>(visitor: bfVisitor<Result>): 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<Result>(visitor: bfVisitor<Result>): 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<Result>(visitor: bfVisitor<Result>): 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<Result>(visitor: bfVisitor<Result>): 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<Result>(visitor: bfVisitor<Result>): 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<Result>(visitor: bfVisitor<Result>): 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<Result>(visitor: bfVisitor<Result>): Result {
|
||||
if (visitor.visitOutputStmt) {
|
||||
return visitor.visitOutputStmt(this);
|
||||
} else {
|
||||
return visitor.visitChildren(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
126
client/src/generated/bfVisitor.ts
Normal file
126
client/src/generated/bfVisitor.ts
Normal file
@@ -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 <Result> The return type of the visit operation. Use `void` for
|
||||
* operations with no return type.
|
||||
*/
|
||||
export interface bfVisitor<Result> extends ParseTreeVisitor<Result> {
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
@@ -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",
|
||||
|
@@ -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<void> {
|
||||
@@ -174,15 +175,15 @@ async function validateTextDocument(textDocument: TextDocument): Promise<void> {
|
||||
let diagnostics: Diagnostic[] = [];
|
||||
const issues = validateBrackets(text);
|
||||
|
||||
diagnostics.push(...issues.map<Diagnostic>(e => ({
|
||||
message: 'Brackets unmatched',
|
||||
range:{
|
||||
start: textDocument.positionAt(e),
|
||||
end: textDocument.positionAt(e+1),
|
||||
},
|
||||
severity:DiagnosticSeverity.Error,
|
||||
code:'[ and ]',
|
||||
})));
|
||||
diagnostics.push(...issues.map<Diagnostic>(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',
|
||||
|
Reference in New Issue
Block a user