summaryrefslogtreecommitdiff
path: root/src/runtime/c/pgf/lexer.c
diff options
context:
space:
mode:
authorkr.angelov <kr.angelov@gmail.com>2012-03-09 09:14:44 +0000
committerkr.angelov <kr.angelov@gmail.com>2012-03-09 09:14:44 +0000
commit1726995921f6c05686b2b06f672b1376e589f8ac (patch)
treebdec5f4aad7dc5c07eebd7869e5c4453047a50c7 /src/runtime/c/pgf/lexer.c
parentd536d02d9bd3a31ca2bb105ab69ad201015e8c97 (diff)
libpgf: added simple lexer
Diffstat (limited to 'src/runtime/c/pgf/lexer.c')
-rw-r--r--src/runtime/c/pgf/lexer.c103
1 files changed, 103 insertions, 0 deletions
diff --git a/src/runtime/c/pgf/lexer.c b/src/runtime/c/pgf/lexer.c
new file mode 100644
index 000000000..fd196bc1b
--- /dev/null
+++ b/src/runtime/c/pgf/lexer.c
@@ -0,0 +1,103 @@
+#include <gu/list.h>
+#include <pgf/lexer.h>
+#include <pgf/data.h>
+#include <wctype.h>
+
+struct PgfLexer {
+ GuReader* rdr;
+ GuUCS ucs;
+};
+
+PgfLexer*
+pgf_new_lexer(GuReader *rdr, GuPool *pool)
+{
+ PgfLexer* lexer = gu_new(PgfLexer, pool);
+ lexer->rdr = rdr;
+ lexer->ucs = ' ';
+ return lexer;
+}
+
+PgfToken
+pgf_lexer_next_token(PgfLexer *lexer, GuExn* err, GuPool *pool)
+{
+ GuPool* tmp_pool = gu_new_pool();
+
+ PgfToken tok;
+
+ GuStringBuf* buf = gu_string_buf(tmp_pool);
+ GuWriter* wtr = gu_string_buf_writer(buf);
+
+ while (iswspace(lexer->ucs)) {
+ lexer->ucs = gu_read_ucs(lexer->rdr, err);
+ if (gu_exn_is_raised(err))
+ goto stop;
+ }
+
+ if (iswalpha(lexer->ucs) ||
+ lexer->ucs == '\'' ||
+ lexer->ucs == '_') {
+ do {
+ gu_ucs_write(lexer->ucs, wtr, err);
+ if (gu_exn_is_raised(err))
+ goto stop;
+ lexer->ucs = gu_read_ucs(lexer->rdr, err);
+ if (gu_exn_is_raised(err))
+ goto stop;
+ } while (iswalnum(lexer->ucs) ||
+ lexer->ucs == '\'' ||
+ lexer->ucs == '_');
+ } else if (iswdigit(lexer->ucs) || lexer->ucs == '-') {
+ if (lexer->ucs == '-') {
+ gu_ucs_write(lexer->ucs, wtr, err);
+ if (gu_exn_is_raised(err))
+ goto stop;
+ lexer->ucs = gu_read_ucs(lexer->rdr, err);
+ if (gu_exn_is_raised(err))
+ goto stop;
+
+ if (!iswdigit(lexer->ucs))
+ goto stop;
+ }
+
+ do {
+ gu_ucs_write(lexer->ucs, wtr, err);
+ if (gu_exn_is_raised(err))
+ goto stop;
+ lexer->ucs = gu_read_ucs(lexer->rdr, err);
+ if (gu_exn_is_raised(err))
+ goto stop;
+ } while (iswdigit(lexer->ucs));
+
+ if (lexer->ucs == '.') {
+ gu_ucs_write(lexer->ucs, wtr, err);
+ if (gu_exn_is_raised(err))
+ goto stop;
+
+ lexer->ucs = gu_read_ucs(lexer->rdr, err);
+ if (gu_exn_is_raised(err))
+ goto stop;
+
+ while (iswdigit(lexer->ucs)) {
+ gu_ucs_write(lexer->ucs, wtr, err);
+ if (gu_exn_is_raised(err))
+ goto stop;
+ lexer->ucs = gu_read_ucs(lexer->rdr, err);
+ if (gu_exn_is_raised(err))
+ goto stop;
+ }
+ }
+ } else {
+ gu_ucs_write(lexer->ucs, wtr, err);
+ if (gu_exn_is_raised(err))
+ goto stop;
+ lexer->ucs = gu_read_ucs(lexer->rdr, err);
+ if (gu_exn_is_raised(err))
+ goto stop;
+ }
+
+stop:
+ tok = gu_string_buf_freeze(buf, pool);
+
+ gu_pool_free(tmp_pool);
+ return tok;
+}