forked from jhipster/prettier-java
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathparser.js
More file actions
129 lines (119 loc) · 4.6 KB
/
parser.js
File metadata and controls
129 lines (119 loc) · 4.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import { CstParser, isRecognitionException } from "chevrotain";
import { LLStarLookaheadStrategy } from "chevrotain-allstar";
import { allTokens, tokens as t } from "./tokens.js";
import * as lexicalStructure from "./productions/lexical-structure.js";
import * as typesValuesVariables from "./productions/types-values-and-variables.js";
import * as names from "./productions/names.js";
import * as packagesModules from "./productions/packages-and-modules.js";
import * as classes from "./productions/classes.js";
import * as interfaces from "./productions/interfaces.js";
import * as arrays from "./productions/arrays.js";
import * as blocksStatements from "./productions/blocks-and-statements.js";
import * as expressions from "./productions/expressions.js";
import { getSkipValidations } from "./utils.js";
import { shouldNotFormat } from "./comments.js";
/**
* This parser attempts to strongly align with the specs style at:
* - https://docs.oracle.com/javase/specs/jls/se11/html/jls-19.html
*
* Deviations from the spec will be marked.
*
* Note that deviations from the spec do not mean deviations from Java Grammar.
* Rather it means an **equivalent** grammar which was written differently, e.g:
* - LL(k) vs LR(K)
* - Left Recursions vs Repetitions
* - NonTerminals combined together or divided to sub-NonTerminals
* - ...
*
* A special type of spec deviations are the "super grammar" kind.
* This means that the parser has been defined in such a way that it accept a
* **strict superset** of the inputs the official grammar accepts.
*
* This technique is used to simplify the parser when narrowing the set
* of accepted inputs can more easily be done in a post parsing phase.
*
* TODO: document guide lines for using back tracking
*
*/
export default class JavaParser extends CstParser {
constructor() {
super(allTokens, {
lookaheadStrategy: new LLStarLookaheadStrategy({
logging: getSkipValidations() ? () => {} : undefined
}),
nodeLocationTracking: "full",
// traceInitPerf: 2,
skipValidations: getSkipValidations()
});
const $ = this;
this.mostEnclosiveCstNodeByStartOffset = {};
this.mostEnclosiveCstNodeByEndOffset = {};
// ---------------------
// Productions from §3 (Lexical Structure)
// ---------------------
// TODO: move this rule to the correct file
$.RULE("typeIdentifier", () => {
// TODO: implement: Identifier but not var in the lexer
$.CONSUME(t.Identifier);
});
// Include the productions from all "chapters".
lexicalStructure.defineRules.call(this, $, t);
typesValuesVariables.defineRules.call(this, $, t);
names.defineRules.call(this, $, t);
classes.defineRules.call(this, $, t);
packagesModules.defineRules.call(this, $, t);
interfaces.defineRules.call(this, $, t);
arrays.defineRules.call(this, $, t);
blocksStatements.defineRules.call(this, $, t);
expressions.defineRules.call(this, $, t);
this.firstForUnaryExpressionNotPlusMinus = [];
this.performSelfAnalysis();
this.firstForUnaryExpressionNotPlusMinus =
expressions.computeFirstForUnaryExpressionNotPlusMinus.call(this);
}
cstPostNonTerminal(ruleCstResult, ruleName) {
if (this.isBackTracking()) {
return;
}
super.cstPostNonTerminal(ruleCstResult, ruleName);
this.mostEnclosiveCstNodeByStartOffset[ruleCstResult.location.startOffset] =
ruleCstResult;
this.mostEnclosiveCstNodeByEndOffset[ruleCstResult.location.endOffset] =
ruleCstResult;
shouldNotFormat(ruleCstResult, this.onOffCommentPairs);
}
BACKTRACK_LOOKAHEAD(production, errValue = false) {
return this.ACTION(() => {
this.isBackTrackingStack.push(1);
// TODO: "saveRecogState" does not handle the occurrence stack
const orgState = this.saveRecogState();
try {
// hack to enable outputting non-CST values from grammar rules.
const { ruleName, originalGrammarAction } = production;
try {
this.ruleInvocationStateUpdate(
this.fullRuleNameToShort[ruleName],
ruleName,
this.subruleIdx
);
return originalGrammarAction.call(this);
} catch (e) {
return this.invokeRuleCatch(e, true, () => undefined);
} finally {
this.ruleFinallyStateUpdate();
}
} catch (e) {
if (isRecognitionException(e)) {
return errValue;
}
throw e;
} finally {
this.reloadRecogState(orgState);
this.isBackTrackingStack.pop();
}
});
}
setOnOffCommentPairs(onOffCommentPairs) {
this.onOffCommentPairs = onOffCommentPairs;
}
}