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