From 9bb11d0b66dc40a650a74dab64a16709e8d37ec1 Mon Sep 17 00:00:00 2001 From: "Mike D. Lowis" Date: Tue, 26 Feb 2013 18:56:53 -0500 Subject: [PATCH] finished number matching --- source/lexer/classes.c | 2 +- source/lexer/classes.h | 3 + source/lexer/lex.c | 160 ++++++++++++++++++++++++++++------------- source/lexer/lex.h | 7 ++ 4 files changed, 122 insertions(+), 50 deletions(-) diff --git a/source/lexer/classes.c b/source/lexer/classes.c index a57ad66..4e088df 100644 --- a/source/lexer/classes.c +++ b/source/lexer/classes.c @@ -30,7 +30,7 @@ bool hex_digit(void) bool token_end(void) { - return (whitespace() || file_eof()); + return (whitespace() || matches_any("()[]{};") || file_eof()); } bool matches(char ch) diff --git a/source/lexer/classes.h b/source/lexer/classes.h index 25ee730..cb935de 100644 --- a/source/lexer/classes.h +++ b/source/lexer/classes.h @@ -9,11 +9,14 @@ #include +typedef bool (*predicate_t)(void); + bool whitespace(void); bool digit(void); bool hex_digit(void); bool token_end(void); bool matches(char ch); bool matches_any(char* str); +bool one_or_more(predicate_t pfn); #endif /* CLASSES_H */ diff --git a/source/lexer/lex.c b/source/lexer/lex.c index 999cb49..9cc160c 100644 --- a/source/lexer/lex.c +++ b/source/lexer/lex.c @@ -5,13 +5,16 @@ $HeadURL$ */ #include +#include #include "lex.h" #include "classes.h" #include "file.h" #include "buf.h" -tok_t Token = { 0u }; - +/* Global Variables + *****************************************************************************/ +tok_t Token; +jmp_buf Jump_Point; const char* Token_Strings[TOK_MAX] = { "EOF", /* TOK_EOF */ "ID", /* TOK_ID */ @@ -25,21 +28,91 @@ const char* Token_Strings[TOK_MAX] = { "TERM", /* TOK_TERM */ }; +/* Control Functions + *****************************************************************************/ +void record_position(void) +{ + Token.line = file_line(); + Token.column = file_column(); +} + +void set_type(tok_type_t type) +{ + Token.type = Token_Strings[type]; +} + +void consume(void) +{ + buf_put( file_get() ); +} + +void match_consume(char ch) +{ + if (matches(ch)) + consume(); + else + abort(); +} + +void prepare_for_token(void) +{ + (void)memset(&Token,0,sizeof(Token)); + while( whitespace() ) + (void)file_get(); + record_position(); +} + +void accept_char(tok_type_t type) +{ + set_type(type); + consume(); + accept(); +} + +void accept(void) +{ + if (!token_end()) + abort(); + else + Token.str = buf_accept(); +} + +void abort(void) +{ + longjmp(Jump_Point,1); +} + +bool one_or_more(predicate_t pfn) +{ + if (!pfn()) abort(); + while (pfn()) consume(); +} + +/* Token Matching Functions + *****************************************************************************/ tok_t next_token(void) { prepare_for_token(); if (!file_eof()) { - if (matches_any("()[]{};")) - punctuation(); - else if (digit()) - number(); - //else if (matches('\'')) - // character(); - //else if (matches('\"')) - // string(); + /* Mark our starting point so we can resume if we abort */ + if (0 == setjmp(Jump_Point)) + { + if (matches_any("()[]{};")) + punctuation(); + else if (matches('-') || digit() || matches('h')) + number(); + //else if (matches('\'')) + // character(); + //else if (matches('\"')) + // string(); + else + identifier(); + } else + { identifier(); + } /* the keyword "end" is actually a TOK_TERM */ if (0 == strcmp(Token.str,"end")) @@ -63,58 +136,47 @@ void punctuation(void) } } -void number() +void number(void) { set_type(TOK_NUM); - - while (digit()) consume(); - - if (!token_end()) - identifier(); + if (matches('h')) + { + hexadecimal(); + } else - accept(); -} - -void identifier() -{ - set_type(TOK_ID); - while (!token_end() && !matches_any("()[]{};")) consume(); + { + floating_point(); + if (matches_any("eE")) + { + consume(); + floating_point(); + } + } accept(); } -void record_position(void) -{ - Token.line = file_line(); - Token.column = file_column(); -} - -void set_type(tok_type_t type) +void hexadecimal(void) { - Token.type = Token_Strings[type]; + match_consume('h'); + one_or_more( hex_digit ); } -void consume(void) +void floating_point(void) { - buf_put( file_get() ); -} - -void prepare_for_token(void) -{ - (void)memset(&Token,0,sizeof(Token)); - while( whitespace() ) - (void)file_get(); - record_position(); + if (matches('-')) consume(); + one_or_more( digit ); + if (matches('.')) + { + consume(); + one_or_more( digit ); + } } -void accept_char(tok_type_t type) +void identifier(void) { - set_type(type); - consume(); + set_type(TOK_ID); + while (!token_end()) + consume(); accept(); } -void accept() -{ - Token.str = buf_accept(); -} - diff --git a/source/lexer/lex.h b/source/lexer/lex.h index a85e61a..5bfd45a 100644 --- a/source/lexer/lex.h +++ b/source/lexer/lex.h @@ -7,6 +7,8 @@ #ifndef LEX_H #define LEX_H +#include "classes.h" + typedef struct { int line; @@ -34,10 +36,15 @@ void punctuation(void); void record_position(void); void identifier(void); void number(void); +void hexadecimal(void); +void floating_point(void); void set_type(tok_type_t type); void consume(void); +void match_consume(char ch); void prepare_for_token(void); void accept_char(tok_type_t type); void accept(void); +void abort(void); +bool one_or_more(predicate_t pfn); #endif /* LEX_H */ -- 2.52.0