loom

Форк
0
/
FuzeSblRdp.cpp 
191 строка · 6.2 Кб
1
/*
2
MIT License
3

4
Copyright (c) 2021 МГТУ им. Н.Э. Баумана, кафедра ИУ-6, Михаил Фетисов,
5

6
https://bmstu.codes/lsx/simodo/loom
7
*/
8

9
#include "simodo/parser/fuze/FuzeSblRdp.h"
10
#include "simodo/parser/fuze/BaseOperationCode.h"
11

12
#include "simodo/inout/format/fmt.h"
13

14
#include <cassert>
15

16
namespace simodo::parser
17
{
18

19
bool FuzeSblRdp::parse(inout::Tokenizer &tzer, inout::Token &t) {
20
    // "{" { <вызов> ";" } "}"
21
    //  ^
22
    ast().addNode_StepInto(SCRIPT_HOST_NAME, static_cast<ast::OperationCode>(BaseOperationCode::Block), t, t);
23
    ast().addNode(SCRIPT_HOST_NAME, static_cast<ast::OperationCode>(BaseOperationCode::Block), t, t);
24

25
    t = getToken(tzer);
26

27
    while(t.type() != inout::LexemeType::Empty) {
28
        if (t.type() == inout::LexemeType::Punctuation && t.lexeme() == u"}") {
29
            // "{" { <вызов> ";" } "}"
30
            //                      ^
31
            ast().addNode(SCRIPT_HOST_NAME, static_cast<ast::OperationCode>(BaseOperationCode::Block), t, t);
32
            /// \todo Обрабатывать возврат false!
33
            ast().goParent();
34

35
            t = getToken(tzer);
36
            break;
37
        }
38

39
        // "{" { <вызов> ";" } "}"
40
        //       ^
41
        if (!parseProcedureCalling(tzer,t))
42
            return false;
43

44
        // "{" { <вызов> ";" } "}"
45
        //                ^
46
        if (t.type() != inout::LexemeType::Punctuation || t.lexeme() != u";") {
47
            reportUnexpected(t, "';'");
48
            return false;
49
        }
50

51
        t = getToken(tzer);
52
    }
53

54
    return true;
55
}
56

57
bool FuzeSblRdp::parseProcedureCalling(inout::Tokenizer &tzer, inout::Token &t) {
58
    // <адрес>
59
    // ^
60
    if (!parseAddress(tzer,t))
61
        return false;
62

63
    ast().addNode(SCRIPT_HOST_NAME, static_cast<ast::OperationCode>(BaseOperationCode::Pop), t, t);
64

65
    return true;
66
}
67

68
bool FuzeSblRdp::parseAddress(inout::Tokenizer &tzer, inout::Token &t) {
69
    // <AddressAtom> {["." <AddressAtom>] | "(" [<список параметров>] ")"}
70
    // ^
71
    if (!parseAddressAtom(tzer,t))
72
        return false;
73

74
    while(t.type() != inout::LexemeType::Empty) {
75
        // <AddressAtom> {["." <AddressAtom>] | "(" [<список параметров>] ")"}
76
        //               ^
77
        if (t.type() == inout::LexemeType::Punctuation && t.lexeme() == u".") {
78
            // <AddressAtom> {["." <AddressAtom>] | "(" [<список параметров>] ")"}
79
            //                  ^
80
            ast().addNode_StepInto(SCRIPT_HOST_NAME, static_cast<ast::OperationCode>(BaseOperationCode::ObjectElement), t, t);
81

82
            t = getToken(tzer);
83

84
            if (!parseAddressAtom(tzer,t))
85
                return false;
86

87
            /// \todo Обрабатывать возврат false!
88
            ast().goParent();
89
        }
90
        else if (t.type() == inout::LexemeType::Punctuation && t.lexeme() == u"(") {
91
            // <AddressAtom> {["." <AddressAtom>] | "(" [<список параметров>] ")"}
92
            //                                       ^
93
            ast().addNode_StepInto(SCRIPT_HOST_NAME, static_cast<ast::OperationCode>(BaseOperationCode::FunctionCall), t, t);
94

95
            t = getToken(tzer);
96

97
            // <AddressAtom> {["." <AddressAtom>] | "(" [<список параметров>] ")"}
98
            //                                          ^
99
            if (t.type() != inout::LexemeType::Punctuation || t.lexeme() != u")") {
100
                // <AddressAtom> {["." <AddressAtom>] | "(" [<список параметров>] ")"}
101
                //                                           ^
102
                if (!parseArgumentList(tzer,t))
103
                    return false;
104

105
                // <AddressAtom> {["." <AddressAtom>] | "(" [<список параметров>] ")"}
106
                //                                                                 ^
107
                if (t.type() != inout::LexemeType::Punctuation || t.lexeme() != u")")
108
                {
109
                    reportUnexpected(t, "')'");
110
                    return false;
111
                }
112
            }
113

114
            /// \todo Обрабатывать возврат false!
115
            ast().goParent();
116

117
            t = getToken(tzer);
118
        }
119
        else
120
            break;
121
    }
122

123
    return true;
124
}
125

126
bool FuzeSblRdp::parseAddressAtom(inout::Tokenizer &tzer, inout::Token &t)
127
{
128
    // ID
129
    // ^
130
    if (t.type() != inout::LexemeType::Id) {
131
        reportUnexpected(t, inout::fmt("идентификатор"));
132
        return false;
133
    }
134

135
    ast().addNode(SCRIPT_HOST_NAME, static_cast<ast::OperationCode>(BaseOperationCode::PushVariable), t, t);
136

137
    t = getToken(tzer);
138

139
    return true;
140
}
141

142
bool FuzeSblRdp::parseArgumentList(inout::Tokenizer &tzer, inout::Token &t)
143
{
144
    while(t.type() != inout::LexemeType::Empty)
145
    {
146
        // { NUMBER | ANNOTATION | "true" | "false" | "null" | <адрес> [","] }
147
        //   ^        ^            ^        ^         ^        ^
148
        if (t.type() == inout::LexemeType::Number || t.type() == inout::LexemeType::Annotation)
149
        {
150
            ast().addNode(SCRIPT_HOST_NAME, static_cast<ast::OperationCode>(BaseOperationCode::PushConstant), t, t);
151

152
            t = getToken(tzer);
153
        }
154
        else if (t.type() == inout::LexemeType::Punctuation
155
             && t.qualification() == inout::TokenQualification::Keyword
156
             && (t.lexeme() == u"true" || t.lexeme() == u"false" || t.lexeme() == u"null"))
157
        {
158
            ast().addNode(SCRIPT_HOST_NAME, static_cast<ast::OperationCode>(BaseOperationCode::PushConstant), t, t);
159

160
            t = getToken(tzer);
161
        }
162
        else if (!parseAddress(tzer,t))
163
            return false;
164

165
        // { NUMBER | ANNOTATION | <адрес> [","] }
166
        //                                   ^
167
        if (t.type() != inout::LexemeType::Punctuation || t.lexeme() != u",")
168
            break;
169

170
        t = getToken(tzer);
171
    }
172

173
    return true;
174
}
175

176
inout::Token FuzeSblRdp::getToken(inout::Tokenizer & tzer) const
177
{
178
    inout::Token token = tzer.getAnyToken();
179

180
    while (token.type() == inout::LexemeType::Comment) {
181
        _syntax_data_collector.collectToken(token);
182

183
        token = tzer.getAnyToken();
184
    }
185

186
    _syntax_data_collector.collectToken(token);
187

188
    return token;
189
}
190

191
}

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.