mirror of
https://github.com/yhirose/cpp-peglib.git
synced 2025-01-22 21:35:29 +00:00
Better error report.
This commit is contained in:
parent
a7c2de1c32
commit
f3f73e5c35
@ -1,5 +1,6 @@
|
|||||||
#include "interpreter.hpp"
|
#include "interpreter.hpp"
|
||||||
#include "parser.hpp"
|
#include "parser.hpp"
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
using namespace peglib;
|
using namespace peglib;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@ -187,11 +188,20 @@ std::ostream& operator<<(std::ostream& os, const Value& val)
|
|||||||
return val.out(os);
|
return val.out(os);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool run(Env& env, const char* expr, size_t len, Value& val, std::string& msg, bool print_ast)
|
bool run(const string& path, Env& env, const char* expr, size_t len, Value& val, std::string& msg, bool print_ast)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
shared_ptr<Ast> ast;
|
shared_ptr<Ast> ast;
|
||||||
if (get_parser().parse_n(expr, len, ast)) {
|
|
||||||
|
auto& parser = get_parser();
|
||||||
|
|
||||||
|
parser.log = [&](size_t ln, size_t col, const string& err_msg) {
|
||||||
|
stringstream ss;
|
||||||
|
ss << path << ":" << ln << ":" << col << ": " << err_msg << endl;
|
||||||
|
msg = ss.str();
|
||||||
|
};
|
||||||
|
|
||||||
|
if (parser.parse_n(expr, len, ast)) {
|
||||||
if (print_ast) {
|
if (print_ast) {
|
||||||
ast->print();
|
ast->print();
|
||||||
}
|
}
|
||||||
@ -199,7 +209,7 @@ bool run(Env& env, const char* expr, size_t len, Value& val, std::string& msg, b
|
|||||||
val = Eval::eval(*ast, env);
|
val = Eval::eval(*ast, env);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} catch (exception& e) {
|
} catch (runtime_error& e) {
|
||||||
msg = e.what();
|
msg = e.what();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,4 +193,4 @@ private:
|
|||||||
std::map<std::string, Value> dic_;
|
std::map<std::string, Value> dic_;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool run(Env& env, const char* expr, size_t len, Value& val, std::string& msg, bool print_ast);
|
bool run(const std::string& path, Env& env, const char* expr, size_t len, Value& val, std::string& msg, bool print_ast);
|
||||||
|
@ -44,6 +44,7 @@ int main(int argc, const char** argv)
|
|||||||
shell = path_list.empty();
|
shell = path_list.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
Env env;
|
Env env;
|
||||||
env.setup_built_in_functions();
|
env.setup_built_in_functions();
|
||||||
|
|
||||||
@ -56,9 +57,8 @@ int main(int argc, const char** argv)
|
|||||||
|
|
||||||
Value val;
|
Value val;
|
||||||
string msg;
|
string msg;
|
||||||
if (!run(env, buff.data(), buff.size(), val, msg, print_ast)) {
|
if (!run(path, env, buff.data(), buff.size(), val, msg, print_ast)) {
|
||||||
cerr << "error in '" << path << "'." << endl;
|
cerr << msg;
|
||||||
cerr << msg.c_str() << endl;
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -66,6 +66,10 @@ int main(int argc, const char** argv)
|
|||||||
if (shell) {
|
if (shell) {
|
||||||
repl(env, print_ast);
|
repl(env, print_ast);
|
||||||
}
|
}
|
||||||
|
} catch (exception& e) {
|
||||||
|
cerr << e.what() << endl;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,24 @@ static auto g_grammar = R"(
|
|||||||
Comment <- '/*' (!'*/' .)* '*/' / ('#' / '//') (!(EndOfLine / EndOfFile) .)* (EndOfLine / EndOfFile)
|
Comment <- '/*' (!'*/' .)* '*/' / ('#' / '//') (!(EndOfLine / EndOfFile) .)* (EndOfLine / EndOfFile)
|
||||||
)";
|
)";
|
||||||
|
|
||||||
static auto g_parser = peg(g_grammar)
|
peglib::peg& get_parser()
|
||||||
|
{
|
||||||
|
static peg parser;
|
||||||
|
|
||||||
|
static bool initialized = false;
|
||||||
|
|
||||||
|
if (!initialized) {
|
||||||
|
initialized = true;
|
||||||
|
|
||||||
|
parser.log = [&](size_t ln, size_t col, const string& msg) {
|
||||||
|
cerr << ln << ":" << col << ": " << msg << endl;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!parser.load_grammar(g_grammar)) {
|
||||||
|
throw logic_error("invalid peg grammar");
|
||||||
|
}
|
||||||
|
|
||||||
|
parser
|
||||||
.ast_node_optimizable("STATEMENTS", Statements)
|
.ast_node_optimizable("STATEMENTS", Statements)
|
||||||
.ast_node("WHILE", While)
|
.ast_node("WHILE", While)
|
||||||
.ast_node("ASSIGNMENT", Assignment)
|
.ast_node("ASSIGNMENT", Assignment)
|
||||||
@ -59,14 +76,10 @@ static auto g_parser = peg(g_grammar)
|
|||||||
.ast_token("BOOLEAN", Boolean)
|
.ast_token("BOOLEAN", Boolean)
|
||||||
.ast_token("STRING")
|
.ast_token("STRING")
|
||||||
.ast_token("IDENTIFIER", Identifier)
|
.ast_token("IDENTIFIER", Identifier)
|
||||||
.ast_end()
|
.ast_end();
|
||||||
.set_logger([&](size_t ln, size_t col, const string& msg) {
|
}
|
||||||
cerr << ln << ":" << col << ": " << msg << endl;
|
|
||||||
});
|
|
||||||
|
|
||||||
const peglib::peg& get_parser()
|
return parser;
|
||||||
{
|
|
||||||
return g_parser;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// vim: et ts=4 sw=4 cin cino={1s ff=unix
|
// vim: et ts=4 sw=4 cin cino={1s ff=unix
|
||||||
|
@ -6,6 +6,6 @@ enum AstType
|
|||||||
Identifier, Number, Boolean, Function
|
Identifier, Number, Boolean, Function
|
||||||
};
|
};
|
||||||
|
|
||||||
const peglib::peg& get_parser();
|
peglib::peg& get_parser();
|
||||||
|
|
||||||
// vim: et ts=4 sw=4 cin cino={1s ff=unix
|
// vim: et ts=4 sw=4 cin cino={1s ff=unix
|
||||||
|
@ -16,11 +16,11 @@ int repl(Env& env, bool print_ast)
|
|||||||
if (!line.empty()) {
|
if (!line.empty()) {
|
||||||
Value val;
|
Value val;
|
||||||
string msg;
|
string msg;
|
||||||
if (run(env, line.c_str(), line.size(), val, msg, print_ast)) {
|
if (run("(repl)", env, line.c_str(), line.size(), val, msg, print_ast)) {
|
||||||
cout << val << endl;
|
cout << val << endl;
|
||||||
linenoise::AddHistory(line.c_str());
|
linenoise::AddHistory(line.c_str());
|
||||||
} else if (!msg.empty()) {
|
} else if (!msg.empty()) {
|
||||||
cout << msg << endl;
|
cout << msg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user