0
# JSP Parser and AST
1
2
The JSP parser converts JSP source code into Abstract Syntax Trees (AST) using a JavaCC-generated parser. The AST provides a structured representation of JSP documents for analysis.
3
4
## Parser
5
6
### JspParser
7
8
Main parser class that converts JSP source into AST.
9
10
```java { .api }
11
public final class JspParser extends JjtreeParserAdapter<ASTCompilationUnit> {
12
public JspParser();
13
protected ASTCompilationUnit parseImpl(CharStream cs, ParserTask task) throws ParseException;
14
protected TokenDocumentBehavior tokenBehavior();
15
}
16
```
17
18
**Usage:**
19
20
```java
21
import net.sourceforge.pmd.lang.jsp.ast.JspParser;
22
import net.sourceforge.pmd.lang.jsp.ast.ASTCompilationUnit;
23
import net.sourceforge.pmd.lang.ast.impl.javacc.CharStream;
24
import net.sourceforge.pmd.lang.ast.Parser.ParserTask;
25
26
// Create parser
27
JspParser parser = new JspParser();
28
29
// Parse JSP content (requires PMD framework setup)
30
// CharStream stream = CharStream.create(document);
31
// ParserTask task = // ... PMD parser task
32
// ASTCompilationUnit ast = parser.parseImpl(stream, task);
33
```
34
35
**Methods:**
36
37
- `parseImpl(CharStream, ParserTask)`: Parses JSP source and returns the root AST node
38
- `tokenBehavior()`: Returns token behavior configuration for the parser
39
40
**Exceptions:**
41
42
- `ParseException`: Thrown when JSP source cannot be parsed due to syntax errors
43
44
## Root AST Node
45
46
### ASTCompilationUnit
47
48
Root node representing a complete JSP document.
49
50
```java { .api }
51
public final class ASTCompilationUnit extends AbstractJspNode implements RootNode {
52
ASTCompilationUnit(int id);
53
public AstInfo<ASTCompilationUnit> getAstInfo();
54
ASTCompilationUnit makeTaskInfo(ParserTask task);
55
protected <P, R> R acceptVisitor(JspVisitor<? super P, ? extends R> visitor, P data);
56
}
57
```
58
59
**Usage:**
60
61
```java
62
import net.sourceforge.pmd.lang.jsp.ast.ASTCompilationUnit;
63
import net.sourceforge.pmd.lang.ast.AstInfo;
64
65
// Get AST information
66
AstInfo<ASTCompilationUnit> astInfo = compilationUnit.getAstInfo();
67
68
// Access document metadata
69
String fileName = astInfo.getTextDocument().getDisplayName();
70
```
71
72
**Methods:**
73
74
- `getAstInfo()`: Returns metadata about the parsed AST and source document
75
- `acceptVisitor(JspVisitor, P)`: Accepts a visitor for AST traversal
76
77
## Base AST Infrastructure
78
79
### JspNode Interface
80
81
Root interface for all JSP AST nodes.
82
83
```java { .api }
84
public interface JspNode extends JjtreeNode<JspNode> {
85
}
86
```
87
88
All JSP AST nodes implement this interface, providing common navigation methods:
89
90
- `getParent()`: Get parent node
91
- `children()`: Get child nodes as stream
92
- `getChild(int)`: Get child by index
93
- `getNumChildren()`: Get number of children
94
95
### AbstractJspNode
96
97
Base implementation for all JSP AST nodes.
98
99
```java { .api }
100
public abstract class AbstractJspNode extends AbstractJjtreeNode<AbstractJspNode, JspNode> implements JspNode {
101
protected AbstractJspNode(int id);
102
public final <P, R> R acceptVisitor(AstVisitor<? super P, ? extends R> visitor, P data);
103
protected abstract <P, R> R acceptVisitor(JspVisitor<? super P, ? extends R> visitor, P data);
104
public String getXPathNodeName();
105
}
106
```
107
108
**Methods:**
109
110
- `acceptVisitor(AstVisitor, P)`: Generic visitor dispatch that delegates to JSP-specific visitors
111
- `acceptVisitor(JspVisitor, P)`: Abstract method implemented by concrete nodes for type-safe visitor dispatch
112
- `getXPathNodeName()`: Returns the XPath node name for XPath-based rules
113
114
### Content Node Base Classes
115
116
Base classes for nodes that contain textual content.
117
118
```java { .api }
119
public abstract class AbstractContentNode extends AbstractJspNode {
120
public String getContent();
121
}
122
123
public abstract class AbstractExpression extends AbstractContentNode {
124
}
125
```
126
127
**AbstractContentNode:**
128
- `getContent()`: Returns the textual content of the node
129
130
**AbstractExpression:**
131
- Base class for JSP expressions (JSP expressions, EL expressions, value bindings)
132
- Inherits `getContent()` method from `AbstractContentNode`
133
134
## Parser Integration
135
136
### Token Management
137
138
The parser uses JavaCC-generated token managers for lexical analysis.
139
140
```java { .api }
141
public final class JspTokenKinds {
142
public static final String[] TOKEN_NAMES;
143
public static TokenManager<JavaccToken> newTokenManager(CharStream cs);
144
}
145
```
146
147
### Internal API Bridge
148
149
Bridge class for internal PMD framework integration.
150
151
```java { .api }
152
public final class InternalApiBridge {
153
@InternalApi
154
public static JavaccTokenDocument.TokenDocumentBehavior getJspTokenBehavior();
155
}
156
```
157
158
**Note:** `InternalApiBridge` is marked with `@InternalApi` and should not be used in external code as compatibility may break.
159
160
## AST Structure
161
162
The JSP parser creates a hierarchical AST structure:
163
164
```
165
ASTCompilationUnit (root)
166
├── ASTContent
167
├── ASTElement (HTML/XML tags)
168
│ ├── ASTAttribute
169
│ │ └── ASTAttributeValue
170
│ └── ASTText (element content)
171
├── ASTJspDirective (<%@ ... %>)
172
│ └── ASTJspDirectiveAttribute
173
├── ASTJspExpression (<%= ... %>)
174
├── ASTJspScriptlet (<% ... %>)
175
├── ASTElExpression (${...})
176
├── ASTValueBinding (#{...})
177
└── ASTJspComment (<%-- ... --%>)
178
```
179
180
## Error Handling
181
182
### Parse Exceptions
183
184
```java { .api }
185
import net.sourceforge.pmd.lang.ast.ParseException;
186
```
187
188
Common parsing errors:
189
190
- **Syntax Errors**: Invalid JSP/HTML syntax
191
- **Unclosed Tags**: HTML elements without proper closing tags
192
- **Invalid Directives**: Malformed JSP directives
193
- **Expression Errors**: Invalid JSP or EL expression syntax
194
195
### Unclosed Tag Handling
196
197
The parser tracks unclosed HTML/XML tags using `OpenTagRegister`:
198
199
```java { .api }
200
class OpenTagRegister {
201
void openTag(ASTElement elm);
202
boolean closeTag(String closingTagName);
203
void closeTag(ASTElement z);
204
}
205
```
206
207
Unclosed tags are marked with `ASTElement.isUnclosed()` returning `true`.
208
209
## Examples
210
211
### Basic Parsing
212
213
```java
214
import net.sourceforge.pmd.lang.jsp.ast.*;
215
216
// Parse JSP and traverse AST
217
ASTCompilationUnit root = // ... parsed JSP
218
root.children().forEach(child -> {
219
if (child instanceof ASTElement) {
220
ASTElement element = (ASTElement) child;
221
System.out.println("Element: " + element.getName());
222
} else if (child instanceof ASTJspExpression) {
223
ASTJspExpression expr = (ASTJspExpression) child;
224
System.out.println("JSP Expression: " + expr.getContent());
225
}
226
});
227
```
228
229
### Finding Specific Nodes
230
231
```java
232
// Find all JSP expressions in the document
233
List<ASTJspExpression> expressions = root.descendants(ASTJspExpression.class)
234
.collect(Collectors.toList());
235
236
// Find elements with specific tag names
237
List<ASTElement> scriptTags = root.descendants(ASTElement.class)
238
.filter(elem -> "script".equals(elem.getName()))
239
.collect(Collectors.toList());
240
```
241
242
The parser provides a complete and accurate representation of JSP documents, enabling sophisticated analysis and rule development.