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 30using 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