xref: /OpenGrok/opengrok-indexer/src/main/jflex/analysis/swift/SwiftXref.lex (revision d219b4cea555a12b602d2d5518daa22134ad4879)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * See LICENSE.txt included in this distribution for the specific
9  * language governing permissions and limitations under the License.
10  *
11  * When distributing Covered Code, include this CDDL HEADER in each
12  * file and include the License file at LICENSE.txt.
13  * If applicable, add the following below this CDDL HEADER, with the
14  * fields enclosed by brackets "[]" replaced with your own identifying
15  * information: Portions Copyright [yyyy] [name of copyright owner]
16  *
17  * CDDL HEADER END
18  */
19 
20 /*
21  * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved.
22  * Portions Copyright (c) 2017, Chris Fraire <cfraire@me.com>.
23  */
24 
25 package org.opengrok.indexer.analysis.swift;
26 
27 import java.io.IOException;
28 import org.opengrok.indexer.analysis.JFlexSymbolMatcher;
29 import org.opengrok.indexer.analysis.ScopeAction;
30 import org.opengrok.indexer.util.StringUtils;
31 import org.opengrok.indexer.web.HtmlConsts;
32 %%
33 %public
34 %class SwiftXref
35 %extends JFlexSymbolMatcher
36 %unicode
37 %int
38 %char
39 %include ../CommonLexer.lexh
40 %include ../CommonXref.lexh
41 %{
42   /* Must match {WhiteSpace} regex */
43   private final static String WHITE_SPACE = "[ \\t\\f]+";
44 
45   private int nestedComment;
46 
47   @Override
reset()48   public void reset() {
49       super.reset();
50       nestedComment = 0;
51   }
52 
53   @Override
yypop()54   public void yypop() throws IOException {
55       onDisjointSpanChanged(null, yychar);
56       super.yypop();
57   }
58 
chkLOC()59   protected void chkLOC() {
60       switch (yystate()) {
61           case COMMENT:
62           case SCOMMENT:
63           case SDOC:
64               break;
65           default:
66               phLOC();
67               break;
68       }
69   }
70 %}
71 
72 File = [a-zA-Z]{FNameChar}* "." ([Jj][Aa][Vv][Aa] |
73     [Pp][Rr][Oo][Pp][Ee][Rr][Tt][Ii][Ee][Ss] | [Pp][Rr][Oo][Pp][Ss] |
74     [Xx][Mm][Ll] | [Cc][Oo][Nn][Ff] | [Tt][Xx][Tt] | [Hh][Tt][Mm][Ll]? |
75     [Ii][Nn][Ii] | [Jj][Nn][Ll][Pp] | [Jj][Aa][Dd] | [Dd][Ii][Ff][Ff] |
76     [Pp][Aa][Tt][Cc][Hh])
77 
78 /* TODO support markdown in comments
79 SdocWithClassArg = "@throws" | "@exception"
80 SdocWithParamNameArg = "@param"
81 
82 ClassName = "class"{WhiteSpace}({Identifier} ".")* {Identifier}
83 ParamName = {Identifier} | "<" {Identifier} ">"
84 */
85 
86 %state  STRING COMMENT SCOMMENT SDOC TSTRING
87 
88 %include ../Common.lexh
89 %include ../CommonURI.lexh
90 %include ../CommonPath.lexh
91 %include Swift.lexh
92 %%
93 <YYINITIAL>{
94  \{     { chkLOC(); onScopeChanged(ScopeAction.INC, yytext(), yychar); }
95  \}     { chkLOC(); onScopeChanged(ScopeAction.DEC, yytext(), yychar); }
96  \;     { chkLOC(); onScopeChanged(ScopeAction.END, yytext(), yychar); }
97 
98 {Identifier} {
99     chkLOC();
100     String id = yytext();
101     onFilteredSymbolMatched(id, yychar, Consts.kwd);
102 }
103 
104  [`] {Identifier} [`]    {
105     chkLOC();
106     String capture = yytext();
107     String id = capture.substring(1, capture.length() - 1);
108     onNonSymbolMatched("`", yychar);
109     onFilteredSymbolMatched(id, yychar, null);
110     onNonSymbolMatched("`", yychar);
111  }
112 
113  {ImplicitIdentifier} {
114     chkLOC();
115     onKeywordMatched(yytext(), yychar);
116  }
117 
118 "<" ({File}|{FPath}) ">" {
119         chkLOC();
120         onNonSymbolMatched("<", yychar);
121         String path = yytext();
122         path = path.substring(1, path.length() - 1);
123         onFilelikeMatched(path, yychar + 1);
124         onNonSymbolMatched(">", yychar + 1 + path.length());
125 }
126 
127 /*{Hier}
128         { onPathlikeMatched(yytext(), '.', false, yychar); }
129 */
130  {Number}        {
131     chkLOC();
132     onDisjointSpanChanged(HtmlConsts.NUMBER_CLASS, yychar);
133     onNonSymbolMatched(yytext(), yychar);
134     onDisjointSpanChanged(null, yychar);
135  }
136 
137  \"     {
138     chkLOC();
139     yypush(STRING);
140     onDisjointSpanChanged(HtmlConsts.STRING_CLASS, yychar);
141     onNonSymbolMatched(yytext(), yychar);
142  }
143  \"\"\"    {
144     chkLOC();
145     yypush(TSTRING);
146     onDisjointSpanChanged(HtmlConsts.STRING_CLASS, yychar);
147     onNonSymbolMatched(yytext(), yychar);
148  }
149  "/**" / [^/]    {
150     if (nestedComment++ == 0) {
151         yypush(SDOC);
152         onDisjointSpanChanged(HtmlConsts.COMMENT_CLASS, yychar);
153     }
154     onNonSymbolMatched(yytext(), yychar);
155  }
156  "//"    {
157     yypush(SCOMMENT);
158     onDisjointSpanChanged(HtmlConsts.COMMENT_CLASS, yychar);
159     onNonSymbolMatched(yytext(), yychar);
160  }
161 }
162 
163 <STRING> {
164  \\[\"\\]    { chkLOC(); onNonSymbolMatched(yytext(), yychar); }
165  \"     {
166     chkLOC();
167     onNonSymbolMatched(yytext(), yychar);
168     yypop();
169  }
170 }
171 
172 <TSTRING> {
173  \"\"\"    {
174     chkLOC();
175     onNonSymbolMatched(yytext(), yychar);
176     yypop();
177  }
178 }
179 
180 <STRING, TSTRING> {
181     {WhspChar}*{EOL}    {
182         onDisjointSpanChanged(null, yychar);
183         onEndOfLineMatched(yytext(), yychar);
184         onDisjointSpanChanged(HtmlConsts.STRING_CLASS, yychar);
185     }
186 }
187 
188 <YYINITIAL, COMMENT, SDOC> {
189  "/*"    {
190     if (nestedComment++ == 0) {
191         yypush(COMMENT);
192         onDisjointSpanChanged(HtmlConsts.COMMENT_CLASS, yychar);
193     }
194     onNonSymbolMatched(yytext(), yychar);
195  }
196 }
197 
198 <COMMENT, SDOC> {
199  "*/"    {
200     onNonSymbolMatched(yytext(), yychar);
201     if (--nestedComment == 0) {
202         yypop();
203     }
204  }
205  {WhspChar}*{EOL}    {
206     onDisjointSpanChanged(null, yychar);
207     onEndOfLineMatched(yytext(), yychar);
208     onDisjointSpanChanged(HtmlConsts.COMMENT_CLASS, yychar);
209  }
210 }
211 
212 /* TODO: support markdown in comments
213 <SDOC> {
214   {SdocWithParamNameArg} {WhiteSpace} {ParamName} |
215   {SdocWithClassArg} {WhiteSpace} {ClassName} {
216     String text = yytext();
217     String[] tokens = text.split(WHITE_SPACE, 2);
218     onNonSymbolMatched(tokens[0], EmphasisHint.STRONG, yychar);
219     onNonSymbolMatched(text.substring(tokens[0].length(), text.length() -
220         tokens[1].length()), yychar);
221     onNonSymbolMatched(tokens[1], EmphasisHint.EM, yychar);
222   }
223   "@" {Identifier} {
224     onNonSymbolMatched(yytext(), EmphasisHint.STRONG, yychar);
225   }
226 }
227 */
228 
229 <SCOMMENT> {
230   {WhspChar}*{EOL} {
231     yypop();
232     onEndOfLineMatched(yytext(), yychar);
233   }
234 }
235 
236 <YYINITIAL, STRING, COMMENT, SCOMMENT, SDOC, TSTRING> {
237 {WhspChar}*{EOL}    { onEndOfLineMatched(yytext(), yychar); }
238  [[\s]--[\n]]    { onNonSymbolMatched(yytext(), yychar); }
239  [^\n]    { chkLOC(); onNonSymbolMatched(yytext(), yychar); }
240 }
241 
242 <STRING, COMMENT, SCOMMENT, SDOC, TSTRING> {
243  {FPath}    {
244     chkLOC();
245     onPathlikeMatched(yytext(), '/', false, yychar);
246  }
247 
248 {File}
249         {
250         chkLOC();
251         String path = yytext();
252         onFilelikeMatched(path, yychar);
253  }
254 
255 {FNameChar}+ "@" {FNameChar}+ "." {FNameChar}+
256         {
257           chkLOC();
258           onEmailAddressMatched(yytext(), yychar);
259         }
260 }
261 
262 <STRING, SCOMMENT, TSTRING> {
263     {BrowseableURI}    {
264         chkLOC();
265         onUriMatched(yytext(), yychar);
266     }
267 }
268 
269 <COMMENT, SDOC> {
270     {BrowseableURI}    {
271         onUriMatched(yytext(), yychar, StringUtils.END_C_COMMENT);
272     }
273 }
274