Added ws skipping. Non ws skipping versions of base parsers. Added comment skipping

This commit is contained in:
Jonathan Turner
2009-06-24 13:53:05 +00:00
parent 1abe806178
commit 3ed5fe0c97
7 changed files with 182 additions and 40 deletions

View File

@@ -13,4 +13,5 @@ include_directories(dispatchkit langkit)
add_subdirectory(langkit bin) add_subdirectory(langkit bin)
add_subdirectory(dispatchkit bin) add_subdirectory(dispatchkit bin)
add_subdirectory(chaiscript bin) add_subdirectory(chaiscript bin)
add_subdirectory(chaioop bin)

View File

@@ -3,8 +3,8 @@ cmake_minimum_required(VERSION 2.6)
project(chaioop) project(chaioop)
SET (CMAKE_BUILD_TYPE gdb) SET (CMAKE_BUILD_TYPE gdb)
SET (CMAKE_C_FLAGS_GDB " -Wall -ggdb -O3") SET (CMAKE_C_FLAGS_GDB " -Wall -ggdb")
SET (CMAKE_CXX_FLAGS_GDB " -Wall -ggdb -O3") SET (CMAKE_CXX_FLAGS_GDB " -Wall -ggdb")
include_directories(../langkit ../dispatchkit) include_directories(../langkit ../dispatchkit)

View File

@@ -7,6 +7,27 @@
#include <string.h> #include <string.h>
namespace langkit { namespace langkit {
struct File_Position {
int line;
int column;
const char *filename;
File_Position(int file_line, int file_column, const char *file_name)
: line(file_line), column(file_column), filename(file_name) { }
File_Position() : line(0), column(0), filename(NULL) { }
};
struct Parse_Error {
std::string reason;
File_Position position;
Parse_Error(const std::string &why, const File_Position &where) :
reason(why), position(where) { }
virtual ~Parse_Error() throw() {}
};
class Token { class Token {
std::string text; std::string text;
@@ -15,14 +36,85 @@ namespace langkit {
class Parser { class Parser {
std::string::iterator input_pos, input_end; std::string::iterator input_pos, input_end;
int line, col;
std::string multiline_comment_begin, multiline_comment_end;
std::string singleline_comment;
public: public:
bool Int() { bool SkipComment() {
bool retval = false;
if (Str_(multiline_comment_begin.c_str())) {
while (input_pos != input_end) {
if (Str_(multiline_comment_end.c_str())) {
break;
}
else if (!Eol_()) {
++col;
++input_pos;
}
}
retval = true;
}
else if (Str_(singleline_comment.c_str())) {
while (input_pos != input_end) {
if (Eol_()) {
break;
}
else {
++col;
++input_pos;
}
}
retval = true;
}
return retval;
}
bool SkipWS() {
bool retval = false;
while (input_pos != input_end) {
if ((*input_pos == ' ') || (*input_pos == '\t')) {
++input_pos;
++col;
retval = true;
}
else if (SkipComment()) {
retval = true;
}
else {
break;
}
}
return retval;
}
bool Int_() {
bool retval = false; bool retval = false;
if ((input_pos != input_end) && (*input_pos >= '0') && (*input_pos <= '9')) { if ((input_pos != input_end) && (*input_pos >= '0') && (*input_pos <= '9')) {
retval = true; retval = true;
while ((input_pos != input_end) && (*input_pos >= '0') && (*input_pos <= '9')) { while ((input_pos != input_end) && (*input_pos >= '0') && (*input_pos <= '9')) {
++input_pos; ++input_pos;
++col;
}
}
return retval;
}
bool Int() {
SkipWS();
return Int_();
}
bool Id_() {
bool retval = false;
if ((input_pos != input_end) && (((*input_pos >= 'A') && (*input_pos <= 'Z')) || ((*input_pos >= 'a') && (*input_pos <= 'z')))) {
retval = true;
while ((input_pos != input_end) && (((*input_pos >= 'A') && (*input_pos <= 'Z')) || ((*input_pos >= 'a') && (*input_pos <= 'z')))) {
++input_pos;
++col;
} }
} }
@@ -30,28 +122,29 @@ namespace langkit {
} }
bool Id() { bool Id() {
SkipWS();
return Id_();
}
bool Char_(char c) {
bool retval = false; bool retval = false;
if ((input_pos != input_end) && (((*input_pos >= 'A') && (*input_pos <= 'Z')) || ((*input_pos >= 'a') && (*input_pos <= 'z')))) { if ((input_pos != input_end) && (*input_pos == c)) {
++input_pos;
++col;
retval = true; retval = true;
while ((input_pos != input_end) && (((*input_pos >= 'A') && (*input_pos <= 'Z')) || ((*input_pos >= 'a') && (*input_pos <= 'z')))) {
++input_pos;
}
} }
return retval; return retval;
} }
bool Char(char c) { bool Char(char c) {
bool retval = false; SkipWS();
if ((input_pos != input_end) && (*input_pos == c)) {
++input_pos;
retval = true;
}
return retval; return Char_(c);
} }
bool Str(const char *s) { bool Str_(const char *s) {
bool retval = false; bool retval = false;
int len = strlen(s); int len = strlen(s);
@@ -61,18 +154,46 @@ namespace langkit {
if (*tmp != s[i]) { if (*tmp != s[i]) {
return false; return false;
} }
++tmp;
} }
retval = true; retval = true;
input_pos = tmp; input_pos = tmp;
col += len;
} }
return retval; return retval;
} }
bool Str(const char *s) {
SkipWS();
return Str_(s);
}
bool Eol_() {
bool retval = false;
if ((input_pos != input_end) && (Str_("\r\n") || Char_('\n'))) {
retval = true;
++line;
col = 1;
}
return retval;
}
bool Eol() {
SkipWS();
return Eol_();
}
bool Arg_List() { bool Arg_List() {
bool retval = Id() || Int(); bool retval = Id() || Int();
while (retval && Char(',')) { while (retval && Char(',')) {
retval = Id() || Int(); retval = Id() || Int();
if (!retval) {
throw Parse_Error("Unexpected value in parameter list", File_Position(line, col, "_INPUT_"));
}
} }
return retval; return retval;
} }
@@ -81,6 +202,8 @@ namespace langkit {
bool retval = false; bool retval = false;
std::string::iterator prev = input_pos; std::string::iterator prev = input_pos;
int prev_line = line;
int prev_col = col;
if (Id() && Char('(')) { if (Id() && Char('(')) {
@@ -88,16 +211,10 @@ namespace langkit {
retval = Char(')'); retval = Char(')');
} }
if (!retval) { input_pos = prev; } if (!retval) {
input_pos = prev;
return retval; prev_line = line;
} prev_col = col;
bool Eol() {
bool retval = false;
if ((input_pos != input_end) && (Str("\r\n") || Char('\n'))) {
retval = true;
} }
return retval; return retval;
@@ -117,6 +234,10 @@ namespace langkit {
bool parse(std::string input) { bool parse(std::string input) {
input_pos = input.begin(); input_pos = input.begin();
input_end = input.end(); input_end = input.end();
line = 1; col = 1;
multiline_comment_begin = "/*";
multiline_comment_end = "*/";
singleline_comment = "//";
return Fun_Calls(); return Fun_Calls();
} }
@@ -144,9 +265,29 @@ std::string load_file(const char *filename) {
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
langkit::Parser parser; langkit::Parser parser;
std::string input;
if (argc > 1) { if (argc > 1) {
std::cout << parser.parse(load_file(argv[1])) << std::endl; try {
std::cout << parser.parse(load_file(argv[1])) << std::endl;
}
catch (langkit::Parse_Error &pe) {
std::cout << pe.reason << " at " << pe.position.line << ", " << pe.position.column << std::endl;
}
}
else {
std::cout << "eval> ";
std::getline(std::cin, input);
while (input != "quit") {
try {
std::cout << parser.parse(input) << std::endl;
}
catch (langkit::Parse_Error &pe) {
std::cout << pe.reason << " at " << pe.position.line << ", " << pe.position.column << std::endl;
}
std::cout << "eval> ";
std::getline(std::cin, input);
}
} }
return 0; return 0;

View File

@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 2.6) cmake_minimum_required(VERSION 2.6)
enable_testing() enable_testing()
project(wesley) project(chaiscript)
SET (CMAKE_BUILD_TYPE gdb) SET (CMAKE_BUILD_TYPE gdb)
SET (CMAKE_C_FLAGS_GDB " -Wall -ggdb") SET (CMAKE_C_FLAGS_GDB " -Wall -ggdb")
@@ -15,11 +15,11 @@ if(Boost_FOUND)
add_executable(chaiscript_test main.cpp) add_executable(chaiscript_test main.cpp)
target_link_libraries(chaiscript_test ${Boost_LIBRARIES}) target_link_libraries(chaiscript_test ${Boost_LIBRARIES})
add_executable(chaiscript_callbacktest callbacktest.cpp) add_executable(chaiscript_callbacktest callbacktest.cpp)
target_link_libraries(chaiscript_callbacktest ${Boost_LIBRARIES}) target_link_libraries(chaiscript_callbacktest ${Boost_LIBRARIES})
add_executable(sensors sensors.cpp) add_executable(sensors sensors.cpp)
target_link_libraries(sensors ${Boost_LIBRARIES}) target_link_libraries(sensors ${Boost_LIBRARIES})
endif() endif()

View File

@@ -18,11 +18,11 @@ int main(int argc, char *argv[]) {
if (val.get_type_info().m_bare_type_info && *(val.get_type_info().m_bare_type_info) != typeid(void)) { if (val.get_type_info().m_bare_type_info && *(val.get_type_info().m_bare_type_info) != typeid(void)) {
try { try {
dispatchkit::Boxed_Value printeval dispatchkit::Boxed_Value printeval
= dispatchkit::dispatch(chai.get_eval_engine().get_function("to_string"), = dispatchkit::dispatch(chai.get_eval_engine().get_function("to_string"),
dispatchkit::Param_List_Builder() << val); dispatchkit::Param_List_Builder() << val);
std::cout << "result: "; std::cout << "result: ";
dispatchkit::dispatch(chai.get_eval_engine().get_function("print"), dispatchkit::dispatch(chai.get_eval_engine().get_function("print"),
dispatchkit::Param_List_Builder() << printeval); dispatchkit::Param_List_Builder() << printeval);
} catch (const std::runtime_error &e) { } catch (const std::runtime_error &e) {
std::cout << "result: object #" << &val << std::endl; std::cout << "result: object #" << &val << std::endl;

View File

@@ -12,11 +12,11 @@ if(Boost_FOUND)
include_directories(${Boost_INCLUDE_DIRS}) include_directories(${Boost_INCLUDE_DIRS})
include_directories(.) include_directories(.)
add_executable(dispatchkit_test test.cpp) add_executable(dispatchkit_test test.cpp)
add_executable(dispatchkit_unittest unittest.cpp) add_executable(dispatchkit_unittest unittest.cpp)
target_link_libraries(dispatchkit_unittest ${Boost_LIBRARIES}) target_link_libraries(dispatchkit_unittest ${Boost_LIBRARIES})
endif() endif()

View File

@@ -11,11 +11,11 @@ find_package( Boost 1.36.0 COMPONENTS regex unit_test_framework)
if(Boost_FOUND) if(Boost_FOUND)
include_directories(${Boost_INCLUDE_DIRS}) include_directories(${Boost_INCLUDE_DIRS})
add_executable(langkit_test main.cpp) add_executable(langkit_test main.cpp)
target_link_libraries(langkit_test ${Boost_LIBRARIES}) target_link_libraries(langkit_test ${Boost_LIBRARIES})
add_executable(langkit_unittest unittest.cpp) add_executable(langkit_unittest unittest.cpp)
target_link_libraries(langkit_unittest ${Boost_LIBRARIES}) target_link_libraries(langkit_unittest ${Boost_LIBRARIES})
endif() endif()
add_test(langkit_unittest ${EXECUTABLE_OUTPUT_PATH}/langkit_unittest) add_test(langkit_unittest ${EXECUTABLE_OUTPUT_PATH}/langkit_unittest)