occam-custom-grammars 5.0.1227 → 5.0.1229

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/example.js +904 -515
  2. package/lib/constants.js +17 -1
  3. package/lib/customGrammar/combined.js +37 -22
  4. package/lib/customGrammar/default.js +9 -9
  5. package/lib/customGrammar.js +56 -65
  6. package/lib/example/customGrammar/userDefined1.js +4 -4
  7. package/lib/example/customGrammar/userDefined2.js +4 -4
  8. package/lib/example/grammarNames.js +3 -3
  9. package/lib/example/select/{patternName.js → vocabularyName.js} +23 -23
  10. package/lib/example/{input/pattern.js → textarea/vocabulary.js} +23 -23
  11. package/lib/example/view.js +13 -13
  12. package/lib/index.js +5 -5
  13. package/lib/typesMap.js +45 -0
  14. package/lib/utilities/bnf.js +66 -0
  15. package/lib/utilities/grammar.js +31 -0
  16. package/lib/utilities/nominal.js +25 -0
  17. package/lib/utilities/query.js +36 -0
  18. package/lib/utilities/vocabulary.js +61 -0
  19. package/lib/vocabularyNames.js +29 -0
  20. package/package.json +4 -3
  21. package/src/constants.js +4 -0
  22. package/src/customGrammar/combined.js +46 -25
  23. package/src/customGrammar/default.js +5 -4
  24. package/src/customGrammar.js +49 -64
  25. package/src/example/customGrammar/userDefined1.js +10 -6
  26. package/src/example/customGrammar/userDefined2.js +6 -6
  27. package/src/example/grammarNames.js +1 -1
  28. package/src/example/select/vocabularyName.js +52 -0
  29. package/src/example/textarea/vocabulary.js +33 -0
  30. package/src/example/view.js +16 -16
  31. package/src/index.js +1 -1
  32. package/src/typesMap.js +50 -0
  33. package/src/utilities/bnf.js +88 -0
  34. package/src/utilities/grammar.js +12 -0
  35. package/src/utilities/nominal.js +9 -0
  36. package/src/utilities/query.js +25 -0
  37. package/src/utilities/vocabulary.js +74 -0
  38. package/src/vocabularyNames.js +9 -0
  39. package/lib/patternNames.js +0 -29
  40. package/src/example/input/pattern.js +0 -33
  41. package/src/example/select/patternName.js +0 -52
  42. package/src/patternNames.js +0 -9
@@ -11,13 +11,13 @@ import SubHeading from "./subHeading";
11
11
  import NameSelect from "./select/name";
12
12
  import SizeableDiv from "./div/sizeable";
13
13
  import BNFTextarea from "./textarea/bnf";
14
- import PatternInput from "./input/pattern";
15
14
  import RuleNameSelect from "./select/ruleName";
16
15
  import ContentTextarea from "./textarea/content";
17
- import PatternNameSelect from "./select/patternName";
18
16
  import ParseTreeTextarea from "./textarea/parseTree";
19
17
  import StartRuleNameInput from "./input/startRuleName";
20
18
  import NominalBNFTextarea from "./textarea/nominalBNF";
19
+ import VocabularyTextarea from "./textarea/vocabulary";
20
+ import VocabularyNameSelect from "./select/vocabularyName";
21
21
  import userDefinedCustomGrammar1 from "./customGrammar/userDefined1";
22
22
  import userDefinedCustomGrammar2 from "./customGrammar/userDefined2";
23
23
 
@@ -31,22 +31,22 @@ const { rulesAsString } = rulesUtilities,
31
31
  class View extends Element {
32
32
  keyUpHandler = (event, element) => {
33
33
  try {
34
- const name = this.getName(),
35
- bnf = this.getBNF(),
36
- pattern = this.getPattern(),
34
+ const bnf = this.getBNF(),
35
+ name = this.getName(),
37
36
  ruleName = this.getRuleName(),
38
- patternName = this.getPatternName();
37
+ vocabulary = this.getVocabulary(),
38
+ vocabularyName = this.getVocabularyName();
39
39
 
40
40
  if (name === USER_DEFINED_CUSTOM_GRAMMAR_NAME_1) {
41
41
  userDefinedCustomGrammar1.setBNF(ruleName, bnf);
42
42
 
43
- userDefinedCustomGrammar1.setPattern(patternName, pattern);
43
+ userDefinedCustomGrammar1.setVocabulary(vocabularyName, vocabulary);
44
44
  }
45
45
 
46
46
  if (name === USER_DEFINED_CUSTOM_GRAMMAR_NAME_2) {
47
47
  userDefinedCustomGrammar2.setBNF(ruleName, bnf);
48
48
 
49
- userDefinedCustomGrammar2.setPattern(patternName, pattern);
49
+ userDefinedCustomGrammar2.setVocabulary(vocabularyName, vocabulary);
50
50
  }
51
51
 
52
52
  const customGrammars = [
@@ -92,7 +92,7 @@ class View extends Element {
92
92
 
93
93
  const name = this.getName(),
94
94
  ruleName = this.getRuleName(),
95
- patternName = this.getPatternName();
95
+ vocabularyName = this.getVocabularyName();
96
96
 
97
97
  switch (name) {
98
98
  case DEFAULT_CUSTOM_GRAMMAR_NAME:
@@ -112,11 +112,11 @@ class View extends Element {
112
112
  }
113
113
 
114
114
  const bnf = customGrammar.getBNF(ruleName),
115
- pattern = customGrammar.getPattern(patternName);
115
+ vocabulary = customGrammar.getVocabulary(vocabularyName);
116
116
 
117
117
  this.setBNF(bnf);
118
118
 
119
- this.setPattern(pattern);
119
+ this.setVocabulary(vocabulary);
120
120
  }
121
121
 
122
122
  childElements() {
@@ -132,16 +132,16 @@ class View extends Element {
132
132
  Custom grammar
133
133
  </SubHeading>
134
134
  <NameSelect onChange={changeHandler} />
135
+ <SubHeading>
136
+ Vocabulary
137
+ </SubHeading>
138
+ <VocabularyNameSelect onChange={changeHandler} />
139
+ <VocabularyTextarea onKeyUp={keyUpHandler} />
135
140
  <SubHeading>
136
141
  BNF
137
142
  </SubHeading>
138
143
  <RuleNameSelect onChange={changeHandler} />
139
144
  <BNFTextarea onKeyUp={keyUpHandler} />
140
- <SubHeading>
141
- Pattern
142
- </SubHeading>
143
- <PatternNameSelect onChange={changeHandler} />
144
- <PatternInput onKeyUp={keyUpHandler} />
145
145
  <SubHeading>
146
146
  Start rule
147
147
  </SubHeading>
package/src/index.js CHANGED
@@ -3,7 +3,7 @@
3
3
  export { DEFAULT_CUSTOM_GRAMMAR_NAME } from "./grammarNames";
4
4
 
5
5
  export { default as ruleNames } from "./ruleNames";
6
- export { default as patternNames } from "./patternNames";
6
+ export { default as vocabularyNames } from "./vocabularyNames";
7
7
 
8
8
  export { default as CustomGrammar } from "./customGrammar";
9
9
  export { default as lexersUtilities } from "./utilities/lexers";
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+
3
+ import { arrayUtilities } from "necessary";
4
+
5
+ import { nominalParser } from "./utilities/nominal";
6
+ import { TERM_RULE_NAME, STATEMENT_RULE_NAME } from "./ruleNames";
7
+ import { STUFF_RULE_NAME, NONSENSE_RULE_NAME } from "./constants";
8
+
9
+ const { first } = arrayUtilities;
10
+
11
+ const ruleMap = nominalParser.getRuleMap(),
12
+ stuffRule = ruleMap[STUFF_RULE_NAME],
13
+ nonsenseRule = ruleMap[NONSENSE_RULE_NAME],
14
+ stuffTypes = typesFromRule(stuffRule),
15
+ nonsenseTypes = typesFromRule(nonsenseRule),
16
+ termTypes = stuffTypes, ///
17
+ statementTypes = nonsenseTypes,
18
+ typesMap = {
19
+ [TERM_RULE_NAME]: termTypes,
20
+ [STATEMENT_RULE_NAME]: statementTypes
21
+ };
22
+
23
+ export default typesMap;
24
+
25
+ function typesFromRule(rule) {
26
+ let parts;
27
+
28
+ const definitions = rule.getDefinitions(),
29
+ firstDDefinition = first(definitions),
30
+ definition = firstDDefinition; ///
31
+
32
+ parts = definition.getParts();
33
+
34
+ const firstPart = first(parts),
35
+ oneOrMorePartsPart = firstPart, ///
36
+ part = oneOrMorePartsPart.getPart(),
37
+ choiceOrPartsPart = part; ///
38
+
39
+ parts = choiceOrPartsPart.getParts();
40
+
41
+ const types = parts.map((part) => {
42
+ const significantTokenTypePart = part, ///
43
+ significantTokenType = significantTokenTypePart.getSignificantTokenType(),
44
+ type = significantTokenType; ///
45
+
46
+ return type;
47
+ });
48
+
49
+ return types;
50
+ }
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+
3
+ import { arrayUtilities } from "necessary";
4
+
5
+ import typesMap from "../typesMap";
6
+
7
+ import { nodesQuery } from "../utilities/query";
8
+ import { nominalLexer } from "../utilities/nominal";
9
+ import { EMPTY_STRING, UNDERSCORE_CHARACTER } from "../constants";
10
+ import { customGrammarBNFLexer, customGrammarBNFParser } from "../utilities/grammar";
11
+
12
+ const { first, second } = arrayUtilities;
13
+
14
+ const stringLiteralTerminalNodesQuery = nodesQuery("//stringLiteral/@*!"),
15
+ significantTokenTypeTerminalNodesQuery = nodesQuery("//significantTokenType/@*!");
16
+
17
+ export function validateBNF(bnf, ruleName) {
18
+ if ((bnf === null) || (bnf === EMPTY_STRING)) {
19
+ return;
20
+ }
21
+
22
+ const content = bnf,
23
+ tokens = customGrammarBNFLexer.tokenise(content),
24
+ node = customGrammarBNFParser.parse(tokens);
25
+
26
+ const types = typesMap[ruleName],
27
+ significantTokenTypeTerminalNodes = significantTokenTypeTerminalNodesQuery(node);
28
+
29
+ significantTokenTypeTerminalNodes.forEach((significantTokenTypeTerminalNode) => {
30
+ const type = typeFromSignificantTokenTypeTerminalNode(significantTokenTypeTerminalNode),
31
+ typesIncludeType = types.includes(type);
32
+
33
+ if (!typesIncludeType) {
34
+ throw new Error(`The '${type}' type is not included in the '${ruleName}' rule's types.`)
35
+ }
36
+ });
37
+
38
+ const stringLiteralTerminalNodes = stringLiteralTerminalNodesQuery(node);
39
+
40
+ stringLiteralTerminalNodes.forEach((stringLiteralTerminalNode) => {
41
+ const content = contentFromStringLiteralTerminalNode(stringLiteralTerminalNode);
42
+
43
+ if (content === UNDERSCORE_CHARACTER) {
44
+ throw new Error(`The "${content}" string literal cannot be an underscore.`);
45
+ }
46
+
47
+ const tokens = nominalLexer.tokenise(content),
48
+ tokensLength = tokens.length;
49
+
50
+ if (tokensLength !== 1) {
51
+ throw new Error(`Tokenising the "${content}" string literal does not result in a single token.`);
52
+ }
53
+
54
+ const firstToken = first(tokens),
55
+ token = firstToken, ///
56
+ type = token.getType(),
57
+ typesIncludeType = types.includes(type);
58
+
59
+ if (!typesIncludeType) {
60
+ throw new Error(`The "${content}" string literal's token's '${type}' type is not included in the '${ruleName}' rule's types.`)
61
+ }
62
+ });
63
+ }
64
+
65
+ function contentFromStringLiteralTerminalNode(stringLiteralTerminalNode) {
66
+ let content;
67
+
68
+ content = stringLiteralTerminalNode.getContent();
69
+
70
+ const matches = content.match(/"([^"]+)"/),
71
+ secondMatch = second(matches);
72
+
73
+ content = secondMatch; ///
74
+
75
+ return content;
76
+ }
77
+
78
+ function typeFromSignificantTokenTypeTerminalNode(significantTokenTypeTerminalNode) {
79
+ let type;
80
+
81
+ const content = significantTokenTypeTerminalNode.getContent(),
82
+ matches = content.match(/\[([^\]]+)\]/),
83
+ secondMatch = second(matches);
84
+
85
+ type = secondMatch; ///
86
+
87
+ return type;
88
+ }
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+
3
+ import { CustomGrammarBNFLexer, CustomGrammarBNFParser } from "occam-grammars";
4
+ import { CustomGrammarVocabularyLexer, CustomGrammarVocabularyParser } from "occam-grammars";
5
+
6
+ export const customGrammarBNFLexer = CustomGrammarBNFLexer.fromNothing();
7
+
8
+ export const customGrammarBNFParser = CustomGrammarBNFParser.fromNothing();
9
+
10
+ export const customGrammarVocabularyLexer = CustomGrammarVocabularyLexer.fromNothing();
11
+
12
+ export const customGrammarVocabularyParser = CustomGrammarVocabularyParser.fromNothing();
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+
3
+ import { CommonLexer } from "occam-lexers";
4
+ import { CommonParser } from "occam-parsers";
5
+ import { NominalLexer, NominalParser } from "occam-grammars";
6
+
7
+ export const nominalLexer = CommonLexer.fromNothing(NominalLexer);
8
+
9
+ export const nominalParser = CommonParser.fromNothing(NominalParser);
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+
3
+ import { Query } from "occam-query";
4
+
5
+ export function nodeQuery(expressionString) {
6
+ const query = Query.fromExpressionString(expressionString);
7
+
8
+ return function(node) {
9
+ const nodes = query.execute(node);
10
+
11
+ node = nodes.shift() || null; ///
12
+
13
+ return node;
14
+ };
15
+ }
16
+
17
+ export function nodesQuery(expressionString) {
18
+ const query = Query.fromExpressionString(expressionString);
19
+
20
+ return function(node) {
21
+ const nodes = query.execute(node);
22
+
23
+ return nodes;
24
+ };
25
+ }
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+
3
+ import { arrayUtilities } from "necessary";
4
+
5
+ import { nodesQuery } from "../utilities/query";
6
+ import { nominalLexer } from "../utilities/nominal";
7
+ import { EMPTY_STRING, UNASSIGNED_TYPE, UNDERSCORE_CHARACTER } from "../constants";
8
+ import { customGrammarVocabularyLexer, customGrammarVocabularyParser } from "../utilities/grammar"
9
+
10
+ const { first, second } = arrayUtilities;
11
+
12
+ const expressionNodesQuery = nodesQuery("//expression")
13
+
14
+ export function validateVocabulary(vocabulary) {
15
+ if ((vocabulary === null) || (vocabulary === EMPTY_STRING)) {
16
+ return;
17
+ }
18
+
19
+ const content = vocabulary, ///
20
+ tokens = customGrammarVocabularyLexer.tokenise(content),
21
+ node = customGrammarVocabularyParser.parse(tokens);
22
+
23
+ const expressionNodes = expressionNodesQuery(node);
24
+
25
+ expressionNodes.forEach((expressionNode) => {
26
+ const content = contentFromExpressionNode(expressionNode),
27
+ tokens = nominalLexer.tokenise(content),
28
+ tokensLength = tokens.length;
29
+
30
+ if (tokensLength > 1) {
31
+ throw new Error(`Tokenising the '${content}' content results in more than one token.`);
32
+ }
33
+
34
+ const firstToken = first(tokens),
35
+ token = firstToken,
36
+ type = token.getType();
37
+
38
+ if (type !== UNASSIGNED_TYPE) {
39
+ throw new Error(`The '${type}' type of the '${content}' token is not 'unassigned'.`);
40
+ }
41
+
42
+ if (content === UNDERSCORE_CHARACTER) {
43
+ throw new Error(`The '${content}' token cannot be an underscore.`);
44
+ }
45
+ });
46
+ }
47
+
48
+ export function expressionsFromVocabulary(vocabulary, expressions) {
49
+ if ((vocabulary === null) || (vocabulary === EMPTY_STRING)) {
50
+ return;
51
+ }
52
+
53
+ const content = vocabulary, ///
54
+ tokens = customGrammarVocabularyLexer.tokenise(content),
55
+ node = customGrammarVocabularyParser.parse(tokens),
56
+ expressionNodes = expressionNodesQuery(node);
57
+
58
+ expressionNodes.forEach((expressionNode) => {
59
+ const content = contentFromExpressionNode(expressionNode),
60
+ expression = content; ///
61
+
62
+ expressions.push(expression);
63
+ });
64
+ }
65
+
66
+ function contentFromExpressionNode(expressionNode) {
67
+ const nonTerminalNode = expressionNode, ///
68
+ childNodes = nonTerminalNode.getChildNodes(),
69
+ secondChildNode = second(childNodes),
70
+ unassignedTerminalNode = secondChildNode, ///
71
+ content = unassignedTerminalNode.getContent();
72
+
73
+ return content;
74
+ }
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+
3
+ export const TYPE_VOCABULARY_NAME = "type";
4
+ export const SYMBOL_VOCABULARY_NAME = "symbol";
5
+
6
+ export default {
7
+ TYPE_VOCABULARY_NAME,
8
+ SYMBOL_VOCABULARY_NAME
9
+ };
@@ -1,29 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", {
3
- value: true
4
- });
5
- function _export(target, all) {
6
- for(var name in all)Object.defineProperty(target, name, {
7
- enumerable: true,
8
- get: Object.getOwnPropertyDescriptor(all, name).get
9
- });
10
- }
11
- _export(exports, {
12
- get SYMBOL_PATTERN_NAME () {
13
- return SYMBOL_PATTERN_NAME;
14
- },
15
- get TYPE_PATTERN_NAME () {
16
- return TYPE_PATTERN_NAME;
17
- },
18
- get default () {
19
- return _default;
20
- }
21
- });
22
- var TYPE_PATTERN_NAME = "type";
23
- var SYMBOL_PATTERN_NAME = "symbol";
24
- var _default = {
25
- TYPE_PATTERN_NAME: TYPE_PATTERN_NAME,
26
- SYMBOL_PATTERN_NAME: SYMBOL_PATTERN_NAME
27
- };
28
-
29
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9wYXR0ZXJuTmFtZXMuanMiXSwic291cmNlc0NvbnRlbnQiOlsiXCJ1c2Ugc3RyaWN0XCI7XG5cbmV4cG9ydCBjb25zdCBUWVBFX1BBVFRFUk5fTkFNRSA9IFwidHlwZVwiO1xuZXhwb3J0IGNvbnN0IFNZTUJPTF9QQVRURVJOX05BTUUgPSBcInN5bWJvbFwiO1xuXG5leHBvcnQgZGVmYXVsdCB7XG4gIFRZUEVfUEFUVEVSTl9OQU1FLFxuICBTWU1CT0xfUEFUVEVSTl9OQU1FXG59O1xuIl0sIm5hbWVzIjpbIlNZTUJPTF9QQVRURVJOX05BTUUiLCJUWVBFX1BBVFRFUk5fTkFNRSJdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7O1FBR2FBO2VBQUFBOztRQURBQztlQUFBQTs7UUFHYjtlQUFBOzs7QUFITyxJQUFNQSxvQkFBb0I7QUFDMUIsSUFBTUQsc0JBQXNCO0lBRW5DLFdBQWU7SUFDYkMsbUJBQUFBO0lBQ0FELHFCQUFBQTtBQUNGIn0=
@@ -1,33 +0,0 @@
1
- "use strict";
2
-
3
- import Input from "../input";
4
-
5
- export default class PatternInput extends Input {
6
- getPattern() {
7
- const value = this.getValue(),
8
- pattern = value; ///
9
-
10
- return pattern;
11
- }
12
-
13
- setPattern(pattern) {
14
- const value = pattern; ///
15
-
16
- this.setValue(value);
17
- }
18
-
19
- parentContext() {
20
- const getPattern = this.getPattern.bind(this),
21
- setPattern = this.setPattern.bind(this);
22
-
23
- return ({
24
- getPattern,
25
- setPattern
26
- });
27
- }
28
-
29
- static defaultProperties = {
30
- className: "pattern",
31
- spellCheck: "false"
32
- };
33
- }
@@ -1,52 +0,0 @@
1
- "use strict";
2
-
3
- import Select from "../select";
4
-
5
- import { TYPE_PATTERN_NAME, SYMBOL_PATTERN_NAME } from "../../patternNames";
6
-
7
- export default class PatternNameSelect extends Select {
8
- getPatternName() {
9
- const value = this.getValue(),
10
- patternName = value; ///
11
-
12
- return patternName;
13
- }
14
-
15
- childElements() {
16
- const patternNames = [
17
- TYPE_PATTERN_NAME,
18
- SYMBOL_PATTERN_NAME
19
- ],
20
- options = patternNames.map((patternName, index) => {
21
- const value = patternName,
22
- selected = (index === 0);
23
-
24
- return (
25
-
26
- <option value={value} selected={selected} >
27
- {patternName}
28
- </option>
29
-
30
- );
31
- }),
32
- childElements = [
33
- ...options
34
- ];
35
-
36
-
37
- return childElements;
38
- }
39
-
40
- parentContext() {
41
- const getPatternName = this.getPatternName.bind(this); ///
42
-
43
- return ({
44
- getPatternName
45
- });
46
- }
47
-
48
- static defaultProperties = {
49
- className: "rule-name",
50
- spellCheck: "false"
51
- }
52
- }
@@ -1,9 +0,0 @@
1
- "use strict";
2
-
3
- export const TYPE_PATTERN_NAME = "type";
4
- export const SYMBOL_PATTERN_NAME = "symbol";
5
-
6
- export default {
7
- TYPE_PATTERN_NAME,
8
- SYMBOL_PATTERN_NAME
9
- };