xref: /OpenGrok/opengrok-indexer/src/main/jflex/analysis/powershell/PowershellSymbolTokenizer.lex (revision d219b4cea555a12b602d2d5518daa22134ad4879)
1*d219b4ceSAdam Hornacek /*
2*d219b4ceSAdam Hornacek  * CDDL HEADER START
3*d219b4ceSAdam Hornacek  *
4*d219b4ceSAdam Hornacek  * The contents of this file are subject to the terms of the
5*d219b4ceSAdam Hornacek  * Common Development and Distribution License (the "License").
6*d219b4ceSAdam Hornacek  * You may not use this file except in compliance with the License.
7*d219b4ceSAdam Hornacek  *
8*d219b4ceSAdam Hornacek  * See LICENSE.txt included in this distribution for the specific
9*d219b4ceSAdam Hornacek  * language governing permissions and limitations under the License.
10*d219b4ceSAdam Hornacek  *
11*d219b4ceSAdam Hornacek  * When distributing Covered Code, include this CDDL HEADER in each
12*d219b4ceSAdam Hornacek  * file and include the License file at LICENSE.txt.
13*d219b4ceSAdam Hornacek  * If applicable, add the following below this CDDL HEADER, with the
14*d219b4ceSAdam Hornacek  * fields enclosed by brackets "[]" replaced with your own identifying
15*d219b4ceSAdam Hornacek  * information: Portions Copyright [yyyy] [name of copyright owner]
16*d219b4ceSAdam Hornacek  *
17*d219b4ceSAdam Hornacek  * CDDL HEADER END
18*d219b4ceSAdam Hornacek  */
19*d219b4ceSAdam Hornacek 
20*d219b4ceSAdam Hornacek /*
21*d219b4ceSAdam Hornacek  * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved.
22*d219b4ceSAdam Hornacek  * Portions Copyright (c) 2017-2018, Chris Fraire <cfraire@me.com>.
23*d219b4ceSAdam Hornacek  */
24*d219b4ceSAdam Hornacek 
25*d219b4ceSAdam Hornacek package org.opengrok.indexer.analysis.powershell;
26*d219b4ceSAdam Hornacek 
27*d219b4ceSAdam Hornacek import java.util.Locale;
28*d219b4ceSAdam Hornacek import java.util.regex.Matcher;
29*d219b4ceSAdam Hornacek import org.opengrok.indexer.analysis.JFlexSymbolMatcher;
30*d219b4ceSAdam Hornacek %%
31*d219b4ceSAdam Hornacek %public
32*d219b4ceSAdam Hornacek %class PoshSymbolTokenizer
33*d219b4ceSAdam Hornacek %extends JFlexSymbolMatcher
34*d219b4ceSAdam Hornacek %unicode
35*d219b4ceSAdam Hornacek %ignorecase
36*d219b4ceSAdam Hornacek %int
37*d219b4ceSAdam Hornacek %include ../CommonLexer.lexh
38*d219b4ceSAdam Hornacek %char
39*d219b4ceSAdam Hornacek %{
onCertainlyPublish(String symbol,int yyoffset)40*d219b4ceSAdam Hornacek     private boolean onCertainlyPublish(String symbol, int yyoffset) {
41*d219b4ceSAdam Hornacek         return onPossiblyPublish(symbol, yyoffset, true);
42*d219b4ceSAdam Hornacek     }
43*d219b4ceSAdam Hornacek 
onPossiblyPublish(String symbol,int yyoffset)44*d219b4ceSAdam Hornacek     private boolean onPossiblyPublish(String symbol, int yyoffset) {
45*d219b4ceSAdam Hornacek         return onPossiblyPublish(symbol, yyoffset, false);
46*d219b4ceSAdam Hornacek     }
47*d219b4ceSAdam Hornacek 
onPossiblyPublish(String symbol,int yyoffset,boolean skipKeywordCheck)48*d219b4ceSAdam Hornacek     private boolean onPossiblyPublish(String symbol, int yyoffset,
49*d219b4ceSAdam Hornacek         boolean skipKeywordCheck) {
50*d219b4ceSAdam Hornacek         if (skipKeywordCheck || !Consts.poshkwd.contains(symbol.
51*d219b4ceSAdam Hornacek                 toLowerCase(Locale.ROOT))) {
52*d219b4ceSAdam Hornacek             onSymbolMatched(symbol, yychar + yyoffset);
53*d219b4ceSAdam Hornacek             return true;
54*d219b4ceSAdam Hornacek         }
55*d219b4ceSAdam Hornacek         return false;
56*d219b4ceSAdam Hornacek     }
57*d219b4ceSAdam Hornacek %}
58*d219b4ceSAdam Hornacek 
59*d219b4ceSAdam Hornacek /*
60*d219b4ceSAdam Hornacek  * States:
61*d219b4ceSAdam Hornacek  * STRING   - double-quoted string, ex: "hello, world!"
62*d219b4ceSAdam Hornacek  * QSTRING  - single-quoted string, ex: 'hello, world!'
63*d219b4ceSAdam Hornacek  * COMMENT - multiple-line comment.
64*d219b4ceSAdam Hornacek  * SCOMMENT - single-line comment, ex: # this is a comment
65*d219b4ceSAdam Hornacek  * SUBSHELL - commands executed in a sub-shell,
66*d219b4ceSAdam Hornacek  *               example 1: (echo $header; cat file.txt)
67*d219b4ceSAdam Hornacek  * HERESTRING  - here-string, example: cat @" ... "@
68*d219b4ceSAdam Hornacek  * HEREQSTRING - here-string, example: cat @' ... '@
69*d219b4ceSAdam Hornacek  * DATATYPE - bracketed .NET datatype specification
70*d219b4ceSAdam Hornacek  * DOTSYNTAX - await possible dot syntax -- e.g. property or methods
71*d219b4ceSAdam Hornacek  */
72*d219b4ceSAdam Hornacek %state STRING COMMENT SCOMMENT QSTRING SUBSHELL HERESTRING HEREQSTRING
73*d219b4ceSAdam Hornacek %state DATATYPE DOTSYNTAX
74*d219b4ceSAdam Hornacek 
75*d219b4ceSAdam Hornacek %include ../Common.lexh
76*d219b4ceSAdam Hornacek %include Powershell.lexh
77*d219b4ceSAdam Hornacek %%
78*d219b4ceSAdam Hornacek 
79*d219b4ceSAdam Hornacek <STRING> {
80*d219b4ceSAdam Hornacek  {ComplexVariable}    {
81*d219b4ceSAdam Hornacek     int startOffset = 2;            // trim away the "${" prefix
82*d219b4ceSAdam Hornacek     int endOffset = yylength() - 1; // trim away the "}" suffix
83*d219b4ceSAdam Hornacek     String id = yytext().substring(startOffset, endOffset);
84*d219b4ceSAdam Hornacek     if (onPossiblyPublish(id, startOffset)) return yystate();
85*d219b4ceSAdam Hornacek  }
86*d219b4ceSAdam Hornacek  {SimpleVariable}    {
87*d219b4ceSAdam Hornacek     int startOffset = 1;	// trim away the "$" prefix
88*d219b4ceSAdam Hornacek     String id = yytext().substring(startOffset);
89*d219b4ceSAdam Hornacek     if (onPossiblyPublish(id, startOffset)) return yystate();
90*d219b4ceSAdam Hornacek  }
91*d219b4ceSAdam Hornacek }
92*d219b4ceSAdam Hornacek 
93*d219b4ceSAdam Hornacek <YYINITIAL, SUBSHELL> {
94*d219b4ceSAdam Hornacek  ^ {Label}    {
95*d219b4ceSAdam Hornacek     String id = yytext();
96*d219b4ceSAdam Hornacek     if (onPossiblyPublish(id, 0)) return yystate();
97*d219b4ceSAdam Hornacek  }
98*d219b4ceSAdam Hornacek  {Break} |
99*d219b4ceSAdam Hornacek  {Continue}    {
100*d219b4ceSAdam Hornacek     String capture = yytext();
101*d219b4ceSAdam Hornacek     Matcher m = PoshUtils.GOTO_LABEL.matcher(capture);
102*d219b4ceSAdam Hornacek     if (m.find()) {
103*d219b4ceSAdam Hornacek         String label   = m.group(3);
104*d219b4ceSAdam Hornacek         onCertainlyPublish(label, m.start(3));
105*d219b4ceSAdam Hornacek         return yystate();
106*d219b4ceSAdam Hornacek     }
107*d219b4ceSAdam Hornacek  }
108*d219b4ceSAdam Hornacek 
109*d219b4ceSAdam Hornacek  {DataType}    {
110*d219b4ceSAdam Hornacek     yypushback(yylength());
111*d219b4ceSAdam Hornacek     yypush(DATATYPE);
112*d219b4ceSAdam Hornacek  }
113*d219b4ceSAdam Hornacek }
114*d219b4ceSAdam Hornacek 
115*d219b4ceSAdam Hornacek <YYINITIAL, SUBSHELL, DOTSYNTAX> {
116*d219b4ceSAdam Hornacek  {ComplexVariable}    {
117*d219b4ceSAdam Hornacek     int startOffset = 2;	// trim away the "${" prefix
118*d219b4ceSAdam Hornacek     String id = yytext().substring(startOffset, yylength() - 1);
119*d219b4ceSAdam Hornacek     if (onPossiblyPublish(id, startOffset)) return yystate();
120*d219b4ceSAdam Hornacek     if (yystate() != DOTSYNTAX) yypush(DOTSYNTAX);
121*d219b4ceSAdam Hornacek  }
122*d219b4ceSAdam Hornacek  {SimpleVariable}    {
123*d219b4ceSAdam Hornacek     int startOffset = 1;	// trim away the "$" prefix
124*d219b4ceSAdam Hornacek     String id = yytext().substring(startOffset);
125*d219b4ceSAdam Hornacek     if (onPossiblyPublish(id, startOffset)) return yystate();
126*d219b4ceSAdam Hornacek     if (yystate() != DOTSYNTAX) yypush(DOTSYNTAX);
127*d219b4ceSAdam Hornacek  }
128*d219b4ceSAdam Hornacek }
129*d219b4ceSAdam Hornacek 
130*d219b4ceSAdam Hornacek <YYINITIAL, SUBSHELL> {
131*d219b4ceSAdam Hornacek  {Operator}    {
132*d219b4ceSAdam Hornacek     String capture = yytext();
133*d219b4ceSAdam Hornacek     int startOffset = 1;	// trim away the "-" prefix
134*d219b4ceSAdam Hornacek     String id = capture.substring(startOffset);
135*d219b4ceSAdam Hornacek     if (!Consts.poshkwd.contains(capture.toLowerCase(Locale.ROOT)) &&
136*d219b4ceSAdam Hornacek             onPossiblyPublish(id, startOffset)) {
137*d219b4ceSAdam Hornacek         return yystate();
138*d219b4ceSAdam Hornacek     }
139*d219b4ceSAdam Hornacek  }
140*d219b4ceSAdam Hornacek 
141*d219b4ceSAdam Hornacek  {Number}    {}
142*d219b4ceSAdam Hornacek 
143*d219b4ceSAdam Hornacek  \"     { yypush(STRING); }
144*d219b4ceSAdam Hornacek  \'     { yypush(QSTRING); }
145*d219b4ceSAdam Hornacek  "#"    { yypush(SCOMMENT); }
146*d219b4ceSAdam Hornacek  "<#"   { yypush(COMMENT); }
147*d219b4ceSAdam Hornacek  \@\"   { yypush(HERESTRING); }
148*d219b4ceSAdam Hornacek  \@\'   { yypush(HEREQSTRING); }
149*d219b4ceSAdam Hornacek }
150*d219b4ceSAdam Hornacek 
151*d219b4ceSAdam Hornacek <DOTSYNTAX> {
152*d219b4ceSAdam Hornacek  "."    {
153*d219b4ceSAdam Hornacek     // noop
154*d219b4ceSAdam Hornacek  }
155*d219b4ceSAdam Hornacek 
156*d219b4ceSAdam Hornacek  [^]    {
157*d219b4ceSAdam Hornacek     yypushback(yylength());
158*d219b4ceSAdam Hornacek     yypop();
159*d219b4ceSAdam Hornacek  }
160*d219b4ceSAdam Hornacek }
161*d219b4ceSAdam Hornacek 
162*d219b4ceSAdam Hornacek <YYINITIAL, SUBSHELL, DATATYPE, DOTSYNTAX> {
163*d219b4ceSAdam Hornacek  {Identifier}    {
164*d219b4ceSAdam Hornacek     String id = yytext();
165*d219b4ceSAdam Hornacek     if (onPossiblyPublish(id, 0)) return yystate();
166*d219b4ceSAdam Hornacek  }
167*d219b4ceSAdam Hornacek }
168*d219b4ceSAdam Hornacek 
169*d219b4ceSAdam Hornacek <DATATYPE> {
170*d219b4ceSAdam Hornacek  "]"    {
171*d219b4ceSAdam Hornacek     yypushback(yylength());
172*d219b4ceSAdam Hornacek     yypop();
173*d219b4ceSAdam Hornacek  }
174*d219b4ceSAdam Hornacek }
175*d219b4ceSAdam Hornacek 
176*d219b4ceSAdam Hornacek <STRING> {
177*d219b4ceSAdam Hornacek  [`][\"\$`] |
178*d219b4ceSAdam Hornacek  \"\"    {}
179*d219b4ceSAdam Hornacek 
180*d219b4ceSAdam Hornacek  \$? \"     { yypop(); }
181*d219b4ceSAdam Hornacek }
182*d219b4ceSAdam Hornacek 
183*d219b4ceSAdam Hornacek <STRING, HERESTRING> {
184*d219b4ceSAdam Hornacek  "$("    { yypush(SUBSHELL); }
185*d219b4ceSAdam Hornacek }
186*d219b4ceSAdam Hornacek 
187*d219b4ceSAdam Hornacek <QSTRING> {
188*d219b4ceSAdam Hornacek  \'\'    {}
189*d219b4ceSAdam Hornacek  \'      { yypop(); }
190*d219b4ceSAdam Hornacek }
191*d219b4ceSAdam Hornacek 
192*d219b4ceSAdam Hornacek <COMMENT> {
193*d219b4ceSAdam Hornacek  "#>"    { yypop();}
194*d219b4ceSAdam Hornacek }
195*d219b4ceSAdam Hornacek 
196*d219b4ceSAdam Hornacek <SCOMMENT> {
197*d219b4ceSAdam Hornacek  {EOL}   { yypop();}
198*d219b4ceSAdam Hornacek }
199*d219b4ceSAdam Hornacek 
200*d219b4ceSAdam Hornacek <SUBSHELL> {
201*d219b4ceSAdam Hornacek   \)    { yypop(); }
202*d219b4ceSAdam Hornacek }
203*d219b4ceSAdam Hornacek 
204*d219b4ceSAdam Hornacek <HERESTRING> {
205*d219b4ceSAdam Hornacek   "`$"    {}
206*d219b4ceSAdam Hornacek 
207*d219b4ceSAdam Hornacek  {SimpleVariable}    {
208*d219b4ceSAdam Hornacek     int startOffset = 1;	// trim away the "$" prefix
209*d219b4ceSAdam Hornacek     String id = yytext().substring(startOffset);
210*d219b4ceSAdam Hornacek     if (onPossiblyPublish(id, startOffset)) return yystate();
211*d219b4ceSAdam Hornacek  }
212*d219b4ceSAdam Hornacek 
213*d219b4ceSAdam Hornacek  {ComplexVariable}    {
214*d219b4ceSAdam Hornacek     int startOffset = 2;            // trim away the "${" prefix
215*d219b4ceSAdam Hornacek     int endOffset = yylength() - 1; // trim away the "}" suffix
216*d219b4ceSAdam Hornacek     String id = yytext().substring(startOffset, endOffset);
217*d219b4ceSAdam Hornacek     if (onPossiblyPublish(id, startOffset)) return yystate();
218*d219b4ceSAdam Hornacek  }
219*d219b4ceSAdam Hornacek 
220*d219b4ceSAdam Hornacek  ^ \"\@     { yypop(); }
221*d219b4ceSAdam Hornacek }
222*d219b4ceSAdam Hornacek 
223*d219b4ceSAdam Hornacek <HEREQSTRING> {
224*d219b4ceSAdam Hornacek  ^ "'@"     { yypop(); }
225*d219b4ceSAdam Hornacek }
226*d219b4ceSAdam Hornacek 
227*d219b4ceSAdam Hornacek <YYINITIAL, SUBSHELL> {
228*d219b4ceSAdam Hornacek   /* Don't enter new state if special character is escaped. */
229*d219b4ceSAdam Hornacek   [`][`\(\)\{\}\"\'\$\#\\]    {}
230*d219b4ceSAdam Hornacek 
231*d219b4ceSAdam Hornacek   /* $# should not start a comment. */
232*d219b4ceSAdam Hornacek   "$#"    {}
233*d219b4ceSAdam Hornacek 
234*d219b4ceSAdam Hornacek   \$ ? \(    { yypush(SUBSHELL); }
235*d219b4ceSAdam Hornacek }
236*d219b4ceSAdam Hornacek 
237*d219b4ceSAdam Hornacek <YYINITIAL, DATATYPE, SUBSHELL, STRING, COMMENT, SCOMMENT, QSTRING, HERESTRING,
238*d219b4ceSAdam Hornacek     HEREQSTRING> {
239*d219b4ceSAdam Hornacek {WhspChar}+ |
240*d219b4ceSAdam Hornacek [^]    {}
241*d219b4ceSAdam Hornacek }
242