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(dispatchkit bin)
add_subdirectory(chaiscript bin)
add_subdirectory(chaioop bin)

View File

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

View File

@ -7,6 +7,27 @@
#include <string.h>
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 {
std::string text;
@ -15,14 +36,85 @@ namespace langkit {
class Parser {
std::string::iterator input_pos, input_end;
int line, col;
std::string multiline_comment_begin, multiline_comment_end;
std::string singleline_comment;
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;
if ((input_pos != input_end) && (*input_pos >= '0') && (*input_pos <= '9')) {
retval = true;
while ((input_pos != input_end) && (*input_pos >= '0') && (*input_pos <= '9')) {
++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() {
SkipWS();
return Id_();
}
bool Char_(char c) {
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;
while ((input_pos != input_end) && (((*input_pos >= 'A') && (*input_pos <= 'Z')) || ((*input_pos >= 'a') && (*input_pos <= 'z')))) {
++input_pos;
}
}
return retval;
}
bool Char(char c) {
bool retval = false;
if ((input_pos != input_end) && (*input_pos == c)) {
++input_pos;
retval = true;
}
SkipWS();
return retval;
return Char_(c);
}
bool Str(const char *s) {
bool Str_(const char *s) {
bool retval = false;
int len = strlen(s);
@ -61,18 +154,46 @@ namespace langkit {
if (*tmp != s[i]) {
return false;
}
++tmp;
}
retval = true;
input_pos = tmp;
col += len;
}
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 retval = Id() || Int();
while (retval && Char(',')) {
retval = Id() || Int();
if (!retval) {
throw Parse_Error("Unexpected value in parameter list", File_Position(line, col, "_INPUT_"));
}
}
return retval;
}
@ -81,6 +202,8 @@ namespace langkit {
bool retval = false;
std::string::iterator prev = input_pos;
int prev_line = line;
int prev_col = col;
if (Id() && Char('(')) {
@ -88,16 +211,10 @@ namespace langkit {
retval = Char(')');
}
if (!retval) { input_pos = prev; }
return retval;
}
bool Eol() {
bool retval = false;
if ((input_pos != input_end) && (Str("\r\n") || Char('\n'))) {
retval = true;
if (!retval) {
input_pos = prev;
prev_line = line;
prev_col = col;
}
return retval;
@ -117,6 +234,10 @@ namespace langkit {
bool parse(std::string input) {
input_pos = input.begin();
input_end = input.end();
line = 1; col = 1;
multiline_comment_begin = "/*";
multiline_comment_end = "*/";
singleline_comment = "//";
return Fun_Calls();
}
@ -144,9 +265,29 @@ std::string load_file(const char *filename) {
int main(int argc, char *argv[]) {
langkit::Parser parser;
std::string input;
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;

View File

@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 2.6)
enable_testing()
project(wesley)
project(chaiscript)
SET (CMAKE_BUILD_TYPE gdb)
SET (CMAKE_C_FLAGS_GDB " -Wall -ggdb")
@ -15,11 +15,11 @@ if(Boost_FOUND)
add_executable(chaiscript_test main.cpp)
target_link_libraries(chaiscript_test ${Boost_LIBRARIES})
add_executable(chaiscript_callbacktest callbacktest.cpp)
target_link_libraries(chaiscript_callbacktest ${Boost_LIBRARIES})
add_executable(chaiscript_callbacktest callbacktest.cpp)
target_link_libraries(chaiscript_callbacktest ${Boost_LIBRARIES})
add_executable(sensors sensors.cpp)
target_link_libraries(sensors ${Boost_LIBRARIES})
add_executable(sensors sensors.cpp)
target_link_libraries(sensors ${Boost_LIBRARIES})
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)) {
try {
dispatchkit::Boxed_Value printeval
= dispatchkit::dispatch(chai.get_eval_engine().get_function("to_string"),
dispatchkit::Boxed_Value printeval
= dispatchkit::dispatch(chai.get_eval_engine().get_function("to_string"),
dispatchkit::Param_List_Builder() << val);
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);
} catch (const std::runtime_error &e) {
std::cout << "result: object #" << &val << std::endl;

View File

@ -12,11 +12,11 @@ if(Boost_FOUND)
include_directories(${Boost_INCLUDE_DIRS})
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()

View File

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