generator-begcode
Version:
Spring Boot + Angular/React/Vue in one handy generator
53 lines (52 loc) • 2.7 kB
JavaScript
import { uniq } from 'lodash-es';
import { EOF } from 'chevrotain';
import { getDefaultRuntime } from '../runtime.js';
import { buildJDLAstBuilderVisitor } from './jdl-ast-builder-visitor.js';
import performAdditionalSyntaxChecks from './validator.js';
export function parse(input, startRule = 'prog', runtime = getDefaultRuntime()) {
const cst = getCst(input, startRule, runtime);
const astBuilderVisitor = buildJDLAstBuilderVisitor(runtime);
return astBuilderVisitor.visit(cst);
}
export function getCst(input, startRule = 'prog', runtime = getDefaultRuntime()) {
const lexResult = runtime.lexer.tokenize(input);
if (lexResult.errors.length > 0) {
throw Error(lexResult.errors[0].message);
}
runtime.parser.input = lexResult.tokens;
const cst = runtime.parser[startRule]();
if (runtime.parser.errors.length > 0) {
throwParserError(runtime.parser.errors);
}
const extraSyntaxErrors = performAdditionalSyntaxChecks(cst, runtime);
if (extraSyntaxErrors.length > 0) {
throwSyntaxError(extraSyntaxErrors);
}
return cst;
}
function throwParserError(errors) {
const parserError = errors[0];
if (parserError.name === 'MismatchedTokenException') {
throwErrorAboutInvalidToken(parserError);
}
const errorMessage = `${parserError.name}: ${parserError.message}`;
const { token } = parserError;
const errorMessageLocation = token.tokenType !== EOF ? `\n\tat line: ${token.startLine}, column: ${token.startColumn}` : '';
throw Error(`${errorMessage}${errorMessageLocation}`);
}
function throwErrorAboutInvalidToken(parserError) {
const { token } = parserError;
const errorMessageBeginning = `Found an invalid token '${token.image}'`;
const errorMessageLocation = token.tokenType !== EOF ? `, at line: ${token.startLine} and column: ${token.startColumn}` : '';
const errorMessageComplement = 'Please make sure your JDL content does not use invalid characters, keywords or options.';
throw Error(`${parserError.name}: ${errorMessageBeginning}${errorMessageLocation}.\n\t${errorMessageComplement}`);
}
function throwSyntaxError(errors) {
throw Error(errors.map(error => `${error.message}\n\tat line: ${error.token.startLine}, column: ${error.token.startColumn}`).join('\n'));
}
export function getSyntacticAutoCompleteSuggestions(input, startRule = 'prog', runtime = getDefaultRuntime()) {
const lexResult = runtime.lexer.tokenize(input);
runtime.parser.input = lexResult.tokens;
const syntacticSuggestions = runtime.parser.computeContentAssist(startRule, lexResult.tokens);
return uniq(syntacticSuggestions.map(suggestion => suggestion.nextTokenType));
}