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