xref: /OpenGrok/opengrok-indexer/src/main/jflex/analysis/c/CxxXref.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) 2008, 2021, Oracle and/or its affiliates. All rights reserved.
22  * Portions Copyright (c) 2017, Chris Fraire <cfraire@me.com>.
23  */
24 
25 /*
26  * Cross reference a C++ file
27  */
28 
29 package org.opengrok.indexer.analysis.c;
30 
31 import java.io.IOException;
32 import java.util.regex.Matcher;
33 import java.util.regex.Pattern;
34 import org.opengrok.indexer.analysis.JFlexSymbolMatcher;
35 import org.opengrok.indexer.analysis.ScopeAction;
36 import org.opengrok.indexer.util.StringUtils;
37 import org.opengrok.indexer.web.HtmlConsts;
38 %%
39 %public
40 %class CxxXref
41 %extends JFlexSymbolMatcher
42 %unicode
43 %int
44 %char
45 %include ../CommonLexer.lexh
46 %include ../CommonXref.lexh
47 %{
48   private static final Pattern MATCH_INCLUDE = Pattern.compile(
49       "^(#.*)(include)(.*)([<\"])(.*)([>\"])$");
50   private static final int INCL_HASH_G = 1;
51   private static final int INCLUDE_G = 2;
52   private static final int INCL_POST_G = 3;
53   private static final int INCL_PUNC0_G = 4;
54   private static final int INCL_PATH_G = 5;
55   private static final int INCL_PUNCZ_G = 6;
56 
57   @Override
yypop()58   public void yypop() throws IOException {
59       onDisjointSpanChanged(null, yychar);
60       super.yypop();
61   }
62 
chkLOC()63   protected void chkLOC() {
64       switch (yystate()) {
65           case COMMENT:
66           case SCOMMENT:
67               break;
68           default:
69               phLOC();
70               break;
71       }
72   }
73 %}
74 
75 File = [a-zA-Z]{FNameChar}* "." ([cChHsStT] | [Cc][Oo][Nn][Ff] |
76     [Jj][Aa][Vv][Aa] | [CcHh][Pp][Pp] | [Cc][Cc] | [Tt][Xx][Tt] |
77     [Hh][Tt][Mm][Ll]? | [Pp][Ll] | [Xx][Mm][Ll] | [CcHh][\+][\+] | [Hh][Hh] |
78     [CcHh][Xx][Xx] | [Dd][Ii][Ff][Ff] | [Pp][Aa][Tt][Cc][Hh])
79 
80 %state  STRING COMMENT SCOMMENT QSTRING
81 
82 %include ../Common.lexh
83 %include ../CommonURI.lexh
84 %include ../CommonPath.lexh
85 %include Cxx.lexh
86 %%
87 <YYINITIAL>{
88  \{     { chkLOC(); onScopeChanged(ScopeAction.INC, yytext(), yychar); }
89  \}     { chkLOC(); onScopeChanged(ScopeAction.DEC, yytext(), yychar); }
90  \;     { chkLOC(); onScopeChanged(ScopeAction.END, yytext(), yychar); }
91 
92 {Identifier} {
93     chkLOC();
94     String id = yytext();
95     onFilteredSymbolMatched(id, yychar, CxxConsts.kwd);
96 }
97 
98 "#" {WhspChar}* "include" {WhspChar}* ("<"[^>\n\r]+">" | \"[^\"\n\r]+\")    {
99         chkLOC();
100         String capture = yytext();
101         Matcher match = MATCH_INCLUDE.matcher(capture);
102         if (match.matches()) {
103             onNonSymbolMatched(match.group(INCL_HASH_G), yychar);
104             onFilteredSymbolMatched(match.group(INCLUDE_G), yychar, CxxConsts.kwd);
105             onNonSymbolMatched(match.group(INCL_POST_G), yychar);
106             onNonSymbolMatched(match.group(INCL_PUNC0_G), yychar);
107             String path = match.group(INCL_PATH_G);
108             onPathlikeMatched(path, '/', false, yychar);
109             onNonSymbolMatched(match.group(INCL_PUNCZ_G), yychar);
110         } else {
111             onNonSymbolMatched(capture, yychar);
112         }
113 }
114 
115 /*{Hier}
116         { onPathlikeMatched(yytext(), '.', false, yychar); }
117 */
118 {Number} {
119     chkLOC();
120     onDisjointSpanChanged(HtmlConsts.NUMBER_CLASS, yychar);
121     onNonSymbolMatched(yytext(), yychar);
122     onDisjointSpanChanged(null, yychar);
123  }
124 
125  \"     {
126     chkLOC();
127     yypush(STRING);
128     onDisjointSpanChanged(HtmlConsts.STRING_CLASS, yychar);
129     onNonSymbolMatched(yytext(), yychar);
130  }
131  \'     {
132     chkLOC();
133     yypush(QSTRING);
134     onDisjointSpanChanged(HtmlConsts.STRING_CLASS, yychar);
135     onNonSymbolMatched(yytext(), yychar);
136  }
137  "/*"   {
138     yypush(COMMENT);
139     onDisjointSpanChanged(HtmlConsts.COMMENT_CLASS, yychar);
140     onNonSymbolMatched(yytext(), yychar);
141  }
142  "//"   {
143     yypush(SCOMMENT);
144     onDisjointSpanChanged(HtmlConsts.COMMENT_CLASS, yychar);
145     onNonSymbolMatched(yytext(), yychar);
146  }
147 }
148 
149 <STRING> {
150  \\[\"\\] |
151  \" {WhspChar}+ \"    { chkLOC(); onNonSymbolMatched(yytext(), yychar); }
152  \"    { chkLOC(); onNonSymbolMatched(yytext(), yychar); yypop(); }
153 }
154 
155 <QSTRING> {
156  \\[\'\\] |
157  \' {WhspChar}+ \'    { chkLOC(); onNonSymbolMatched(yytext(), yychar); }
158  \'    { chkLOC(); onNonSymbolMatched(yytext(), yychar); yypop(); }
159 }
160 
161 <COMMENT> {
162 "*/"    { onNonSymbolMatched(yytext(), yychar); yypop(); }
163 }
164 
165 <SCOMMENT> {
166 {WhspChar}*{EOL}      {
167     yypop();
168     onEndOfLineMatched(yytext(), yychar);}
169 }
170 
171 
172 <YYINITIAL, STRING, COMMENT, SCOMMENT, QSTRING> {
173 {WhspChar}*{EOL}    { onEndOfLineMatched(yytext(), yychar); }
174  [[\s]--[\n]]    { onNonSymbolMatched(yytext(), yychar); }
175  [^\n]    { chkLOC(); onNonSymbolMatched(yytext(), yychar); }
176 }
177 
178 <STRING, COMMENT, SCOMMENT, QSTRING> {
179  {FPath}    {
180     chkLOC();
181     onPathlikeMatched(yytext(), '/', false, yychar);
182  }
183 
184 {File}
185         {
186         chkLOC();
187         String path = yytext();
188         onFilelikeMatched(path, yychar);
189  }
190 
191 {FNameChar}+ "@" {FNameChar}+ "." {FNameChar}+
192         {
193           chkLOC();
194           onEmailAddressMatched(yytext(), yychar);
195         }
196 }
197 
198 <STRING, SCOMMENT> {
199     {BrowseableURI}    {
200         chkLOC();
201         onUriMatched(yytext(), yychar);
202     }
203 }
204 
205 <COMMENT> {
206     {BrowseableURI}    {
207         onUriMatched(yytext(), yychar, StringUtils.END_C_COMMENT);
208     }
209 }
210 
211 <QSTRING> {
212     {BrowseableURI}    {
213         chkLOC();
214         onUriMatched(yytext(), yychar, StringUtils.APOS_NO_BSESC);
215     }
216 }
217