Implement lexing, almost. Currently, throws NoMemory exception on error.

This commit is contained in:
Danila Fedorin 2017-05-05 21:00:17 -07:00
parent a5ce4bc032
commit 69afdab402
2 changed files with 88 additions and 3 deletions

View File

@ -4,13 +4,15 @@
#include "Python.h"
static PyObject* pyliblex_init(PyObject* self, PyObject* args);
static PyObject* pyliblex_add_definitions(PyObject* self, PyObject* args);
static PyObject* pyliblex_add_definition(PyObject* self, PyObject* args);
static PyObject* pyliblex_lex(PyObject* self, PyObject* args);
static PyObject* pyliblex_test(PyObject* self, PyObject* args);
static const char module_docstring[] = "A wrapper around a homemade lexing library, liblex.";
static PyMethodDef module_methods[] = {
{"init", pyliblex_init, METH_VARARGS, "Initialize a liblex library object." },
{"add_definition", pyliblex_add_definition, METH_VARARGS, "Add a regular expression definition." },
{"lex", pyliblex_lex, METH_VARARGS, "Lex a string, converting it to tokens." },
{"test", pyliblex_test, METH_VARARGS, "Tests whether the library is working." },
{ NULL, NULL, 0, NULL }
};

View File

@ -25,8 +25,91 @@ static PyObject* pyliblex_init(PyObject* self, PyObject* args){
return return_object;
}
static PyObject* pyliblex_add_definitions(PyObject* self, PyObject* args);
static PyObject* pyliblex_lex(PyObject* self, PyObject* args);
static PyObject* pyliblex_add_definition(PyObject* self, PyObject* args){
PyObject* return_object = NULL;
PyObject* capsule;
const char* regex;
int id;
if(PyArg_ParseTuple(args, "Osi", &capsule, &regex, &id)) {
eval_config* config = PyCapsule_GetPointer(capsule, NULL);
if(config){
liblex_result result = eval_config_add(config, regex, id);
if(result != LIBLEX_SUCCESS){
return_object = PyErr_NoMemory();
} else {
Py_INCREF(Py_None);
return_object = Py_None;
}
}
}
return return_object;
}
static int _pyliblex_add_match(void* data, va_list args){
int return_code = 0;
match* match = data;
const char* string = va_arg(args, const char*);
PyObject* list = va_arg(args, PyObject*);
PyObject* string_object = NULL;
PyObject* int_object = NULL;
PyObject* tuple = NULL;
string_object = PyUnicode_FromStringAndSize(string + match->from, match->to - match->from);
int_object = PyLong_FromLong(match->pattern);
if(string_object && int_object){
tuple = PyTuple_New(2);
if(tuple){
return_code = PyTuple_SetItem(tuple, 0, string_object);
if(return_code == 0) return_code = PyTuple_SetItem(tuple, 1, int_object);
}
}
if(tuple) {
if(return_code != 0) Py_DECREF(tuple);
else return_code = PyList_Append(list, tuple);
}
return return_code;
}
static PyObject* pyliblex_lex(PyObject* self, PyObject* args){
PyObject* return_object = NULL;
PyObject* capsule;
const char* string;
if(PyArg_ParseTuple(args, "Os", &capsule, &string)) {
eval_config* config = PyCapsule_GetPointer(capsule, NULL);
if(config){
ll match_ll;
liblex_result result;
ll_init(&match_ll);
result = eval_all(string, 0, config, &match_ll);
if(result != LIBLEX_SUCCESS){
return_object = PyErr_NoMemory();
} else {
int return_code = 0;
PyObject* list = PyList_New(0);
if(list){
return_code = ll_foreach(&match_ll, NULL, compare_always, _pyliblex_add_match, string, list);
if(return_code != 0) {
Py_DECREF(list);
list = PyList_New(0);
}
}
ll_foreach(&match_ll, NULL, compare_always, eval_foreach_match_free);
ll_clear(&match_ll);
return_object = list;
}
ll_free(&match_ll);
}
}
return return_object;
}
static PyObject* pyliblex_test(PyObject* self, PyObject* args) {
return PyUnicode_FromString("Test from liblex!");
}