jhipster-rasha-core
Version:
JHipster's own domain language and core objects
394 lines (350 loc) • 13.8 kB
Plain Text
/**
* This the grammar we use to generate the parser jhGrammar.js.
* We use the online tool http://pegjs.org/online to generate the parser.
* Modifying this file won't affect the program, this is just to have a more readable grammar.
*/
{
function addUniqueElements(array1, array2) {
if (array2) {
for (let i = 0; i < array2.length; i++) {
if (array1.indexOf(array2[i]) === -1) {
array1.push(array2[i]);
}
}
}
return array1;
}
function flattenArray(array) {
var newArray = [];
for (let i = 0; i < array.length; i ++) {
if (!array[i].length) {
newArray.push(array[i]);
} else {
for (let j = 0; j < array[i].length; j++) {
newArray.push(array[i][j]);
}
}
}
return newArray;
}
function addCardinalityToRelationships(cardinality, relationships) {
if (!relationships) {
return;
}
for (let i = 0; i < relationships.length; i++) {
relationships[i].cardinality = cardinality;
}
}
const parsed = {
constants: {},
entities: [],
relationships: [],
enums: [],
dto: {},
pagination: {},
service: {},
microservice: {},
searchEngine: {},
noClient: { list: [], excluded: [] },
noServer: { list: [], excluded: [] },
angularSuffix: {},
noFluentMethod: { list: [], excluded: [] }
};
}
start = p:prog { return p; }
prog
= SPACE* constantDecl:constantDecl SPACE* p:prog {
parsed.constants[constantDecl.name] = constantDecl.value;
return parsed;
}
/ SPACE* ed:entityDecl SPACE* p:prog {
parsed.entities = addUniqueElements([ed], parsed.entities);
return parsed;
}
/ SPACE* rd:relationDecl SPACE* p:prog {
parsed.relationships = flattenArray(addUniqueElements([rd], parsed.relationships));
return parsed;
}
/ SPACE* end:enumDecl SPACE* p:prog {
parsed.enums = addUniqueElements([end], parsed.enums);
return parsed;
}
/ SPACE* dto:dtoDecl SPACE* p:prog {
parsed.dto = dto;
return parsed;
}
/ SPACE* pagination:pagiDecl SPACE* p:prog {
parsed.pagination = pagination;
return parsed;
}
/ SPACE* service:serviceDecl SPACE* p:prog {
parsed.service = service;
return parsed;
}
/ SPACE* comment SPACE* p:prog { return parsed; }
/ SPACE* microservice:microserviceDecl1 SPACE* p:prog {
parsed.microservice = microservice;
return parsed;
}
/ SPACE* searchEngine:searchEngineDecl SPACE* p:prog {
parsed.searchEngine = searchEngine;
return parsed;
}
/ SPACE* noClient:noClientDecl SPACE* p:prog {
parsed.noClient = noClient;
return parsed;
}
/ SPACE* noServer:noServerDecl SPACE* p:prog {
parsed.noServer = noServer;
return parsed;
}
/ SPACE* angularSuffix:angularSuffixDecl SPACE* p:prog {
parsed.angularSuffix = angularSuffix;
return parsed;
}
/ SPACE* noFluentMethod:noFluentMethod SPACE* p:prog {
parsed.noFluentMethod = noFluentMethod;
return parsed;
}
/ '' { return parsed; }
constantDecl
= name:CONSTANT_NAME SPACE* '=' SPACE* value:INTEGER { return { name: name, value: value }; }
//Entities
entityDecl
= jd:comment? SPACE* ENTITY SPACE* e:ENTITY_NAME SPACE* tableName:entityTableNameDecl? SPACE* eb:entityBody? SPACE* {
return { name: e, tableName: tableName ? tableName: e, body: eb, javadoc: jd };
}
/ ENTITY SPACE* e:ENTITY_NAME SPACE* eb:entityBody? { return { name: e, body: eb, javadoc: '' }; }
entityTableNameDecl
= '(' SPACE* name:[A-z0-9_-]+ SPACE* ')' { return name.join(''); }
entityBody
= '{' SPACE* fdl:fieldDeclList SPACE* '}' { return fdl; }
/ '' { return []; }
fieldDeclList
= SPACE* com:comment? SPACE* f:FIELD_NAME SPACE_WITHOUT_NEWLINE* t:type SPACE_WITHOUT_NEWLINE* vl:validationList? SPACE_WITHOUT_NEWLINE* com2:comment? SPACE_WITHOUT_NEWLINE* ','? SPACE* fdl:fieldDeclList {
return addUniqueElements([{ name: f, type: t, validations: vl, javadoc: com || com2 }], fdl );
}
/ '' { return []; }
validationList
= v:validation SPACE_WITHOUT_NEWLINE* vl:validationList { return addUniqueElements([v], vl); }
/ '' { return []; }
//Relationship
relationDecl
= RELATIONSHIP SPACE rt:relationshipType SPACE* '{' SPACE* bodies:relationshipBodies SPACE* '}' {
addCardinalityToRelationships(rt, bodies);
return addUniqueElements([], bodies);
}
relationshipBodies
= rb:relationshipBody SPACE* ',' SPACE* morerb:relationshipBodies { return addUniqueElements([rb], morerb); }
/ rb:relationshipBody { return [rb]; }
relationshipBody
= from:relationshipSide SPACE* 'to' SPACE* to:relationshipSide SPACE* {
return { from: from , to: to };
}
relationshipSide
= jd:comment? SPACE* e:ENTITY_NAME SPACE* '{' SPACE* i:INJECTED_FIELD_NAME SPACE* required:'required'? '}' SPACE* {
return { name: e, injectedfield: i, javadoc: jd, required: required ? true : false };
}
/ jd:comment? SPACE* e:ENTITY_NAME SPACE* ('{' SPACE* '}')? SPACE* {
return { name: e, injectedfield: null, javadoc: jd };
}
/ e:ENTITY_NAME SPACE { return { name: e, injectedfield: null, javadoc: '' }; }
//Enum
enumDecl
= ENUM SPACE e:ENUMNAME SPACE* '{' SPACE* el:enumPropList SPACE* '}' {
return { name: e, values: el };
}
enumPropList
= e:ENUMPROP SPACE* ',' SPACE* el:enumPropList { return addUniqueElements([e], el); }
/ e:ENUMPROP { return [e]; }
exclusion
= EXCEPT SPACE+ sub:exclusionSub { return sub; }
exclusionSub
= e:ENTITY_NAME SPACE* ',' SPACE* sub:exclusionSub { return addUniqueElements([e], sub); }
/ e:ENTITY_NAME { return [e]; }
// noFluentMethod
noFluentMethod
= NO_FLUENT_METHOD SPACE FOR SPACE+ decl:subNoFluentMethod SPACE* ex:exclusion? SPACE* {
addUniqueElements(parsed.noFluentMethod.list, decl);
if (ex) {
addUniqueElements(parsed.noFluentMethod.excluded, ex);
}
return parsed.noFluentMethod;
}
subNoFluentMethod
= e:ENTITY_NAME SPACE* ',' SPACE* sub:subNoFluentMethod { return addUniqueElements([e], sub); }
/ STAR { return ['*']; }
/ ALL { return ['*']; }
/ e:ENTITY_NAME { return [e]; }
// DTO
dtoDecl
= DTO SPACE+ decl:entityList SPACE* ex:exclusion? SPACE* {
parsed.dto[decl[decl.length - 1]] = parsed.dto[decl[decl.length - 1]] || { list: [], excluded: [] };
addUniqueElements(parsed.dto[decl[decl.length - 1]].list, decl.slice(0, decl.length - 1));
if (ex) {
addUniqueElements(parsed.dto[decl[decl.length - 1]].excluded, ex);
}
return parsed.dto;
}
// Pagination
pagiDecl
= PAGINATE SPACE+ decl:entityList SPACE* ex:exclusion? SPACE* {
parsed.pagination[decl[decl.length - 1]] =
parsed.pagination[decl[decl.length - 1]] || { list: [], excluded: [] };
addUniqueElements(parsed.pagination[decl[decl.length - 1]].list, decl.slice(0, decl.length - 1));
if (ex) {
addUniqueElements(parsed.pagination[decl[decl.length - 1]].excluded, ex);
}
return parsed.pagination;
}
// Service
serviceDecl
= SERVICE SPACE+ decl:entityList SPACE* ex:exclusion? SPACE* {
parsed.service[decl[decl.length - 1]] =
parsed.service[decl[decl.length - 1]] || { list: [], excluded: [] };
addUniqueElements(parsed.service[decl[decl.length - 1]].list, decl.slice(0, decl.length - 1));
if (ex) {
addUniqueElements(parsed.service[decl[decl.length - 1]].excluded, ex);
}
return parsed.service;
}
// first way of declaring microservices
microserviceDecl1
= MICROSERVICE SPACE+ decl:entityList SPACE* ex:exclusion? SPACE* {
parsed.microservice[decl[decl.length - 1]] =
parsed.microservice[decl[decl.length - 1]] || { list: [], excluded: [] };
addUniqueElements(parsed.microservice[decl[decl.length - 1]].list, decl.slice(0, decl.length - 1));
if (ex) {
addUniqueElements(parsed.microservice[decl[decl.length - 1]].excluded, ex);
}
return parsed.microservice;
}
// searchEngine
searchEngineDecl
= SEARCH SPACE+ decl:entityList SPACE* ex:exclusion? SPACE* {
parsed.searchEngine[decl[decl.length - 1]] =
parsed.searchEngine[decl[decl.length - 1]] || { list: [], excluded: [] };
addUniqueElements(parsed.searchEngine[decl[decl.length - 1]].list, decl.slice(0, decl.length - 1));
if (ex) {
addUniqueElements(parsed.searchEngine[decl[decl.length - 1]].excluded, ex);
}
return parsed.searchEngine;
}
// skipClient option
noClientDecl
= SKIP_CLIENT SPACE FOR SPACE* decl:subNoClientDecl SPACE* ex:exclusion? SPACE* {
addUniqueElements(parsed.noClient.list, decl);
if (ex) {
addUniqueElements(parsed.noClient.excluded, ex);
}
return parsed.noClient;
}
subNoClientDecl
= e:ENTITY_NAME SPACE* ',' SPACE* sub:subNoClientDecl { return addUniqueElements([e], sub); }
/ STAR { return ['*']; }
/ ALL { return ['*']; }
/ e:ENTITY_NAME { return [e]; }
// skipServer option
noServerDecl
= SKIP_SERVER SPACE FOR SPACE* decl:subNoServerDecl SPACE* ex:exclusion? SPACE* {
addUniqueElements(parsed.noServer.list, decl);
if (ex) {
addUniqueElements(parsed.noServer.excluded, ex);
}
return parsed.noServer;
}
subNoServerDecl
= e:ENTITY_NAME SPACE* ',' SPACE* sub:subNoServerDecl { return addUniqueElements([e], sub); }
/ STAR { return ['*']; }
/ ALL { return ['*']; }
/ e:ENTITY_NAME { return [e]; }
// angularSuffix option
angularSuffixDecl
= ANGULAR_SUFFIX SPACE* decl:entityList SPACE* ex:exclusion? SPACE* {
parsed.angularSuffix[decl[decl.length - 1]] =
parsed.angularSuffix[decl[decl.length - 1]] || { list: [], excluded: [] };
addUniqueElements(parsed.angularSuffix[decl[decl.length - 1]].list, decl.slice(0, decl.length - 1));
if (ex) {
addUniqueElements(parsed.angularSuffix[decl[decl.length - 1]].excluded, ex);
}
return parsed.angularSuffix;
}
// common way to declare an entity list
entityList
= e:ENTITY_NAME SPACE* ',' SPACE* sub:entityList { return addUniqueElements([e], sub); }
/ STAR SPACE* WITH SPACE* method:([A-z0-9-]+) { return ['*', method.toString().replace(/,/g,'')]; }
/ ALL SPACE* WITH SPACE* method:([A-z0-9-]+) { return ['*', method.toString().replace(/,/g,'')]; }
/ e:ENTITY_NAME SPACE* WITH SPACE* method:([A-z0-9-]+) { return [e, method.toString().replace(/,/g,'')]; }
relationshipType
= ONE_TO_ONE { return 'one-to-one'; }
/ ONE_TO_MANY { return 'one-to-many'; }
/ MANY_TO_ONE { return 'many-to-one'; }
/ MANY_TO_MANY { return 'many-to-many'; }
type = head:[A-Z]tail:[A-z0-9]* { return `${head}${tail.join('')}`; }
validation
= REQUIRED { return { key: 'required', value: '' }; }
/ MINLENGTH SPACE* '(' SPACE* int:INTEGER SPACE* ')' { return { key: 'minlength', value: int }; }
/ MINLENGTH SPACE* '(' SPACE* constantName:CONSTANT_NAME SPACE* ')' { return { key: 'minlength', value: constantName, constant: true }; }
/ MAXLENGTH SPACE* '(' SPACE* int:INTEGER SPACE* ')' { return { key: 'maxlength', value: int }; }
/ MAXLENGTH SPACE* '(' SPACE* constantName:CONSTANT_NAME SPACE* ')' { return { key: 'maxlength', value: constantName, constant: true }; }
/ MINBYTES SPACE* '(' SPACE* int:INTEGER SPACE* ')' { return { key: 'minbytes', value: int }; }
/ MINBYTES SPACE* '(' SPACE* constantName:CONSTANT_NAME SPACE* ')' { return { key: 'minbytes', value: constantName, constant: true }; }
/ MAXBYTES SPACE* '(' SPACE* int:INTEGER SPACE* ')' { return { key: 'maxbytes', value: int }; }
/ MAXBYTES SPACE* '(' SPACE* constantName:CONSTANT_NAME SPACE* ')' { return { key: 'maxbytes', value: constantName, constant: true }; }
/ MIN SPACE* '(' SPACE* int:INTEGER SPACE* ')' { return { key: 'min', value: int };}
/ MIN SPACE* '(' SPACE* constantName:CONSTANT_NAME SPACE* ')' { return { key: 'min', value: constantName, constant: true };}
/ MAX SPACE* '(' SPACE* int:INTEGER SPACE* ')' { return { key: 'max', value: int };}
/ MAX SPACE* '(' SPACE* constantName:CONSTANT_NAME SPACE* ')' { return { key: 'max', value: constantName, constant: true };}
/ PATTERN SPACE* '(' APOSTROPHE regex:REGEX APOSTROPHE SPACE* ')' { return { key: 'pattern', value: regex }; }
// Comments
comment = commentStart notAComment:notAComment* commentStop { return notAComment.join(''); }
commentStart = '/*' [*]*
commentStop = [*]+ '/'
// a completely ignored comment, will not be a Javadoc comment
notAComment = !commentStop !commentStart char:. { return char; }
// Constants
ENTITY = 'entity'
RELATIONSHIP = 'relationship'
ENUM = 'enum'
// Relationship types
ONE_TO_ONE = 'OneToOne'
ONE_TO_MANY = 'OneToMany'
MANY_TO_ONE = 'ManyToOne'
MANY_TO_MANY = 'ManyToMany'
// Options
ALL = 'all'
STAR = '*'
FOR = 'for'
WITH = 'with'
EXCEPT = 'except'
NO_FLUENT_METHOD = 'noFluentMethod'
DTO = 'dto'
PAGINATE = 'paginate'
SERVICE = 'service'
MICROSERVICE = 'microservice'
SEARCH = 'search'
SKIP_CLIENT = 'skipClient'
SKIP_SERVER = 'skipServer'
ANGULAR_SUFFIX = 'angularSuffix'
// validations
REQUIRED = 'required'
MINLENGTH = 'minlength'
MAXLENGTH = 'maxlength'
MINBYTES = 'minbytes'
MAXBYTES = 'maxbytes'
MAX = 'max'
MIN = 'min'
PATTERN = 'pattern'
ENUMNAME = head:[A-Z]tail:[A-z0-9]* { return `${head}${tail.join('')}`; }
ENUMPROP = underscore:[_]*head:[A-Z0-9]tail:[A-Z0-9_]* {
return `${underscore.join('')}${head}${tail.join('')}`;
}
CONSTANT_NAME = name:[A-Z_]+ { return name.join(''); }
INTEGER = negative:'-'?int:[0-9]+ { return parseInt(`${(negative ? negative : '') + int.join('')}`, 10); }
INJECTED_FIELD_NAME = head:[a-zA-Z]tail:[A-z0-9()]* { return `${head}${tail.join('')}`; }
ENTITY_NAME = head:[A-Z]tail:[A-z0-9]* { return `${head}${tail.join('')}`; }
FIELD_NAME = head:[a-zA-Z]tail:[A-z0-9]* { return `${head}${tail.join('')}`; }
SPACE = ['\n'|'\t'|'\r'|' '|\u2028|\u2029]
SPACE_WITHOUT_NEWLINE = ['\t'|' '|\u2028|\u2029]
REGEX = word:[A-z0-9!@#$%^&*()_+\-=\[\]{};':\\|,.<>\/? ]* { return word.join('') }
APOSTROPHE = ["|']