1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 %{
17 #include <iostream>
18 #include <cerrno>
19 #include <climits>
20 #include <cstdlib>
21 #include <string>
22 
23 #include "parser.hpp"  // 包含由parser.y生成的头文件
24 #include "scanner.h"   // 包含yyFlexLexer子类的头文件
25 #include "location.hh" // 包含位置调试信息头文件
26 
27 /* 定义了YY_USER_ACTION,该宏在每个记号的语义动作之前被调用,来根据记号的长度设置位置的信息 */
28 #define YY_USER_ACTION  loc.columns (yyleng);
29 
30 using namespace Uscript;
31 #define yyterminate() Parser::make_END(loc);
32 %}
33 
34 /* 声明使用C++版本FLEXER */
35 %option c++
36 
37 %option noyywrap
38 
39 /* 使用Scanner::yylex() */
40 %option yyclass="Scanner"
41 
42 /* 一些与编译常量使用该前缀否则为yy */
43 %option prefix="script_"
44 
45 %%
46 %{
47   // C++ 兼容的词法分析器的规则,step函数把位置的起始值设置为与结束值相等
48   loc.step();
49 %}
50 
51 "#".*    {
52             loc.step(); // 注释
53 }
54 
55 "/*"([^\*]|(\*)*[^\*/])*(\*)*"*/" {
56             loc.step(); // 注释
57 }
58 
59 "//".* |
60 [ \t]     {
61             /* 跳过注释和空白符号
62              * step函数把位置的起始值设置为与结束值相等,这样位置就指向了上一个极少的结束位置。
63              * 由于注释和空白符号识别后并不会返回,而前一个step的调用是在上一次yylex返回时,所以此处需要手动更新记号的起始位置
64              */
65             loc.step();
66           }
67 \n        {
68             loc.lines(yyleng); // 使用lines函数来更新位置信息中的行号
69             loc.step();
70           }
71 
72 "function"  { return Parser::make_FUNCTION(yytext, loc); }
73 "for"       { return Parser::make_FOR(yytext, loc); }
74 "while"     { return Parser::make_WHILE(yytext, loc); }
75 "if"        { return Parser::make_IF(yytext, loc); } //return IF;
76 "else"      { return Parser::make_ELSE(yytext, loc); } //return ELSE;
77 "+"         { return Parser::make_ADD(yytext, loc); } //return ADD;
78 "-"         { return Parser::make_SUB(yytext, loc); } //return SUB;
79 "*"         { return Parser::make_MUL(yytext, loc); } //return MUL;
80 "/"         { return Parser::make_DIV(yytext, loc); } //return DIV;
81 "="         { return Parser::make_ASSIGN(yytext, loc); } //return ASSIGN;
82 "=="        { return Parser::make_EQ(yytext, loc); } //return EQ;
83 "&&"        { return Parser::make_AND(yytext, loc); } //return AND;
84 "||"        { return Parser::make_OR(yytext, loc); } //return OR;
85 "!="        { return Parser::make_NE(yytext, loc); } //return NE;
86 ">"         { return Parser::make_GT(yytext, loc); } //return GT;
87 ">="        { return Parser::make_GE(yytext, loc); } //return GE;
88 "<"         { return Parser::make_LT(yytext, loc); } //return LT;
89 "<="        { return Parser::make_LE(yytext, loc); } //return LE;
90 "("         { return Parser::make_LP(yytext, loc); } //return LP;
91 ")"         { return Parser::make_RP(yytext, loc); } //return RP;
92 "{"         { return Parser::make_LC(yytext, loc); } //return LC;
93 "}"         { return Parser::make_RC(yytext, loc); } //return RC;
94 ";"         { return Parser::make_SEMICOLON(yytext, loc); } //return SEMICOLON;
95 "break"     { return Parser::make_BREAK(yytext, loc); } //return BREAK;
96 "continue"  { return Parser::make_CONTINUE(yytext, loc); } //return CONTINUE;
97 "return"    { return Parser::make_RETURN(yytext, loc); } //return RETURN;
98 ","         { return Parser::make_COMMA(yytext, loc); } //return COMMA;
99 
100 [A-Za-z_][A-Za-z_0-9]* {
101     return Parser::make_IDENTIFIER(yytext, loc);
102 }
103 ([1-9][0-9]*)|"0" {
104     return Parser::make_NUMBER(std::strtol(yytext, nullptr, 10),loc);
105 }
106 [0-9]+\.[0-9]+ {
107     char* end = nullptr;
108     return Parser::make_FLOAT(std::strtof(yytext, &end), loc);
109 }
110 
111 \"[^\n"]+\" {
112     return Parser::make_STRING(std::string(yytext + 1, yyleng - 2), loc);
113 }
114 <<EOF>>   {
115     return yyterminate();
116 }
117 
118 .   {
119     loc.step();
120 }
121 %%
122