NewLang Project
Yet another programm language
Loading...
Searching...
No Matches
parser_analysis_test.cpp
Go to the documentation of this file.
1#ifdef BUILD_UNITTEST
2
3#include "warning_push.h"
4#include <gtest/gtest.h>
5#include "warning_pop.h"
6
7
8
9#include "parser.h"
10#include "term.h"
11#include "version.h"
12#include "runtime.h"
13#include "analysis.h"
14
15using namespace newlang;
16
17class ParserAnalysis : public ::testing::Test {
18protected:
19
20
21
22 Parser *m_parser;
23 std::vector<std::string> m_postlex;
24
25 Logger::FuncCallback *m_log_callback_save;
26 void *m_log_callback_arg_save;
27 std::string m_output;
28
29 static void LoggerCallback(void *param, Logger::LogLevelType level, const char * str, bool flush) {
30 ParserAnalysis *p = static_cast<ParserAnalysis *> (param);
31 fprintf(stdout, "%s", str);
32 if (flush) {
33 fflush(stdout);
34 }
35 if (p) {
36 p->m_output += str;
37 }
38 }
39
40 void SetUp() {
41 m_parser = nullptr;
42 Logger::Instance()->SaveCallback(m_log_callback_save, m_log_callback_arg_save);
43 Logger::Instance()->SetCallback(&LoggerCallback, this);
44 }
45
46 void TearDown() {
47 delete m_parser;
48 m_parser = nullptr;
49 Logger::Instance()->SetCallback(m_log_callback_save, m_log_callback_arg_save);
50 }
51
52 TermPtr Parse(std::string str, MacroPtr buffer = nullptr, DiagPtr diag = nullptr, RuntimePtr rt = nullptr) {
53 if (m_parser) {
54 delete m_parser;
55 }
56
57 m_parser = new newlang::Parser(buffer, &m_postlex, diag, true, rt.get());
58
59 m_postlex.clear();
60 ast = m_parser->Parse(str);
61 return ast;
62 }
63
64 int Count(TermID token_id) {
65 int result = 0;
66 for (int c = 0; c < ast->size(); c++) {
67 if ((*ast)[c].second->m_id == token_id) {
68 result++;
69 }
70 }
71 return result;
72 }
73
74 std::string LexOut() {
75 std::string result;
76 for (int i = 0; i < m_postlex.size(); i++) {
77 if (!result.empty()) {
78 result += " ";
79 }
80 result += m_postlex[i];
81 }
82 trim(result);
83 return result;
84 }
85
86 TermPtr ast;
87};
88
89//TEST_F(ParserAnalysis, Declare) {
90//
91// ASSERT_ANY_THROW(Parse("@__PRAGMA_DECLARE__(printf(format:FmtChar, ...):Int32, FFI_DEFAULT_ABI)"));
92//
93// ASSERT_NO_THROW(Parse("@__PRAGMA_DECLARE__(printf(format:FmtChar, ...))"));
94// ASSERT_NO_THROW(Parse("@__PRAGMA_DECLARE__(printf(format, ...):Int32)"));
95//
96// ASSERT_NO_THROW(Parse("@__PRAGMA_DECLARE__(printf(format:FmtChar, ...):Int32) @__PRAGMA_DECLARE__(printf2(format:FmtChar, ...):Int32)"));
97//
98// ASSERT_TRUE(m_parser);
99// ASSERT_EQ(2, m_parser->m_declare.size());
100// std::cout << m_parser->m_declare.begin()->second->toString() << "\n";
101//
102// TermPtr obj = m_parser->m_declare.begin()->second;
103// ASSERT_STREQ("printf", obj->m_text.c_str());
104// ASSERT_TRUE(obj->m_type);
105// ASSERT_TRUE(obj->isCall());
106// ASSERT_STREQ(":Int32", obj->m_type->m_text.c_str());
107// ASSERT_EQ(2, obj->size());
108// ASSERT_STREQ("format", obj->at(0).second->m_text.c_str());
109// ASSERT_STREQ("...", obj->at(1).second->m_text.c_str());
110//
111//
112// ASSERT_ANY_THROW(Parse("@__PRAGMA_DECLARE__(printf(format:FmtChar='', ...):Int32)"));
113//
114//
115// ASSERT_NO_THROW(Parse("@__PRAGMA_DECLARE__(variable:Double)"));
116//
117// ASSERT_TRUE(m_parser);
118// ASSERT_EQ(1, m_parser->m_declare.size());
119// std::cout << m_parser->m_declare.begin()->second->toString() << "\n";
120//
121// obj = m_parser->m_declare.begin()->second;
122// ASSERT_STREQ("variable", obj->m_text.c_str());
123// ASSERT_FALSE(obj->isCall());
124// ASSERT_EQ(0, obj->size());
125// ASSERT_TRUE(obj->m_type);
126// ASSERT_STREQ(":Double", obj->m_type->m_text.c_str());
127//
128//
129// ASSERT_NO_THROW(Parse("@__PRAGMA_DECLARE__(variable)"));
130//
131//}
132
133
134TEST_F(ParserAnalysis, ErrorLimit1) {
135
136 RuntimePtr rt_default = RunTime::Init();
137 AstAnalysis analysis(*rt_default, rt_default->m_diag.get());
138
139 ASSERT_EQ(10, rt_default->m_diag->m_error_limit);
140
141 TermPtr term;
142
143 ASSERT_NO_THROW(term = Parse("1\\1 + 1:Int8; 1\\1 + 1:Int8; 1\\1 + 1:Int8", nullptr, nullptr, rt_default));
144 ASSERT_TRUE(analysis.Analyze(term));
145
146 ASSERT_TRUE(m_output.find("fatal error") == std::string::npos) << m_output;
147}
148
149TEST_F(ParserAnalysis, ErrorLimit2) {
150
151 RuntimePtr rt_default = RunTime::Init();
152 AstAnalysis analysis(*rt_default, rt_default->m_diag.get());
153
154 ASSERT_EQ(10, rt_default->m_diag->m_error_limit);
155
156 TermPtr term;
157
158 ASSERT_NO_THROW(term = Parse("1:Int8 + 1\\1; 1:Int8 + 1\\1; 1:Int8 + 1\\1", nullptr, nullptr, rt_default));
159 ASSERT_FALSE(analysis.Analyze(term));
160
161 ASSERT_TRUE(m_output.find("fatal error: 3 generated") != std::string::npos) << m_output;
162
163}
164
165TEST_F(ParserAnalysis, ErrorLimit3) {
166
167 TermPtr term;
168
169 RuntimePtr rt = RunTime::Init({"--nlc-error-limit=1"});
170 AstAnalysis analysis(*rt, rt->m_diag.get());
171
172 ASSERT_EQ(1, rt->m_diag->m_error_limit);
173
174 ASSERT_NO_THROW(term = Parse("1\\1 + 1:Int8; 1\\1 + 1:Int8; 1\\1 + 1:Int8", nullptr, nullptr, rt));
175 ASSERT_TRUE(analysis.Analyze(term));
176
177 ASSERT_TRUE(m_output.find("fatal error") == std::string::npos) << m_output;
178}
179
180TEST_F(ParserAnalysis, ErrorLimit4) {
181
182 TermPtr term;
183
184 RuntimePtr rt = RunTime::Init({"--nlc-error-limit=1"});
185 AstAnalysis analysis(*rt, rt->m_diag.get());
186
187 ASSERT_EQ(1, rt->m_diag->m_error_limit);
188
189 ASSERT_NO_THROW(term = Parse("1:Int8 + 1\\1; 1:Int8 + 1\\1; 1:Int8 + 1\\1", nullptr, nullptr, rt));
190 ASSERT_FALSE(analysis.Analyze(term));
191 ASSERT_TRUE(m_output.find("fatal error: too many errors emitted 1, stopping now [-nlc-error-limit=]") != std::string::npos) << m_output;
192}
193
194
195#endif // UNITTEST
uint8_t LogLevelType
Definition logger.h:319
TermPtr Parse(const std::string str, bool expand_module=false)
Definition parser.cpp:44
int result
Definition lexer.l:367
Definition nlc.h:59
TermID
Definition term.h:119
std::shared_ptr< Term > TermPtr
Definition variable.h:33
std::shared_ptr< RunTime > RuntimePtr
Definition types.h:242
std::shared_ptr< Macro > MacroPtr
Definition types.h:244
std::shared_ptr< Diag > DiagPtr
Definition types.h:243
std::string & trim(std::string &s, const char *t=ws)
Definition types.h:111