xref: /OpenGrok/opengrok-indexer/src/main/jflex/analysis/c/CXref.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) 2005, 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 CXref
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 C.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, Consts.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, Consts.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  \\[\"\']    { chkLOC(); onNonSymbolMatched(yytext(), yychar); }
126  \"     {
127     chkLOC();
128     yypush(STRING);
129     onDisjointSpanChanged(HtmlConsts.STRING_CLASS, yychar);
130     onNonSymbolMatched(yytext(), yychar);
131  }
132  \'     {
133     chkLOC();
134     yypush(QSTRING);
135     onDisjointSpanChanged(HtmlConsts.STRING_CLASS, yychar);
136     onNonSymbolMatched(yytext(), yychar);
137  }
138  "/*"   {
139     yypush(COMMENT);
140     onDisjointSpanChanged(HtmlConsts.COMMENT_CLASS, yychar);
141     onNonSymbolMatched(yytext(), yychar);
142  }
143  "//"   {
144     yypush(SCOMMENT);
145     onDisjointSpanChanged(HtmlConsts.COMMENT_CLASS, yychar);
146     onNonSymbolMatched(yytext(), yychar);
147  }
148 }
149 
150 <STRING> {
151  \\[\"\\] |
152  \" {WhspChar}+ \"    { chkLOC(); onNonSymbolMatched(yytext(), yychar); }
153  \"    { chkLOC(); onNonSymbolMatched(yytext(), yychar); yypop(); }
154 }
155 
156 <QSTRING> {
157  \\[\'\\] |
158  \' {WhspChar}+ \'    { chkLOC(); onNonSymbolMatched(yytext(), yychar); }
159  \'    { chkLOC(); onNonSymbolMatched(yytext(), yychar); yypop(); }
160 }
161 
162 <COMMENT> {
163 "*/"    { onNonSymbolMatched(yytext(), yychar); yypop(); }
164 }
165 
166 <SCOMMENT> {
167 {WhspChar}*{EOL}      {
168     yypop();
169     onEndOfLineMatched(yytext(), yychar);}
170 }
171 
172 
173 <YYINITIAL, STRING, COMMENT, SCOMMENT, QSTRING> {
174 {WhspChar}*{EOL}    { onEndOfLineMatched(yytext(), yychar); }
175  [[\s]--[\n]]    { onNonSymbolMatched(yytext(), yychar); }
176  [^\n]    { chkLOC(); onNonSymbolMatched(yytext(), yychar); }
177 }
178 
179 <STRING, COMMENT, SCOMMENT, QSTRING> {
180  {FPath}    {
181     chkLOC();
182     onPathlikeMatched(yytext(), '/', false, yychar);
183  }
184 
185 {File}
186         {
187         chkLOC();
188         String path = yytext();
189         onFilelikeMatched(path, yychar);
190  }
191 
192 {FNameChar}+ "@" {FNameChar}+ "." {FNameChar}+
193         {
194           chkLOC();
195           onEmailAddressMatched(yytext(), yychar);
196         }
197 }
198 
199 <STRING, SCOMMENT> {
200     {BrowseableURI}    {
201         chkLOC();
202         onUriMatched(yytext(), yychar);
203     }
204 }
205 
206 <COMMENT> {
207     {BrowseableURI}    {
208         onUriMatched(yytext(), yychar, StringUtils.END_C_COMMENT);
209     }
210 }
211 
212 <QSTRING> {
213     {BrowseableURI}    {
214         chkLOC();
215         onUriMatched(yytext(), yychar, StringUtils.APOS_NO_BSESC);
216     }
217 }
218