From: Mike D. Lowis Date: Tue, 27 Mar 2012 17:39:16 +0000 (-0400) Subject: Updated character escape sequence translation and number matching pattern. X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=ff1fd3a0649c050ea897e72ebf88b210c2630743;p=archive%2Fdlang.git Updated character escape sequence translation and number matching pattern. --- diff --git a/example.dl b/example.dl index 8c248ea..9634dae 100644 --- a/example.dl +++ b/example.dl @@ -5,12 +5,26 @@ # Nums foo := 1 foo = 1.0 +foo = 1.0e1 +foo = 1.0e1.0 +foo = -1 +foo = -1.0 +foo = -1.0e-1 +foo = -1.0e-1.0 # Char foo = 'a' +foo = '\a' # bell +foo = '\b' # backspace +foo = '\n' # newline +foo = '\r' # return +foo = '\t' # tab +foo = '\v' # vtab +#foo = '\xFF' # Hex Value # String foo = "some string" +foo = "foo \a \b \f \n \r \t \v \' \" \\ \xFF bar" foo = "12345"[2] # Symbol diff --git a/res/environment.scm b/res/environment.scm index 896e7ee..4096321 100644 --- a/res/environment.scm +++ b/res/environment.scm @@ -46,6 +46,10 @@ (define dl/Symbol 'dl/Symbol) (define dl/Block 'dl/Block) +; Named characters for escape sequences +(char-name 'null (integer->char 0)) +(char-name 'formfeed (integer->char 12)) + ;------------------------------------------------------------------------------ ; Built-in Functions ;------------------------------------------------------------------------------ diff --git a/source/dllexer/dllexer.cpp b/source/dllexer/dllexer.cpp index d4ea3fb..8631f4a 100644 --- a/source/dllexer/dllexer.cpp +++ b/source/dllexer/dllexer.cpp @@ -4,7 +4,7 @@ using namespace std; -#define NUM_SINGLE_CHAR_MATCHES 12 +#define NUM_SINGLE_CHAR_MATCHES 11 SingleCharMatch_T Single_Character_Matches[ NUM_SINGLE_CHAR_MATCHES ] = { { '[', LBRACK }, { ']', RBRACK }, @@ -14,7 +14,6 @@ SingleCharMatch_T Single_Character_Matches[ NUM_SINGLE_CHAR_MATCHES ] = { { '}', RBRACE }, { ',', COMMA }, { '+', ADD }, - { '-', SUB }, { '*', MUL }, { '/', DIV }, { '.', MEMB }, @@ -85,7 +84,7 @@ Token DLLexer::next(void) } else if (isDigit()) { - Number(ret); + Number(ret,false); } else if(current == '\'') { @@ -99,6 +98,18 @@ Token DLLexer::next(void) { Symbol(ret); } + else if(current == '-') + { + consume(); + if(isDigit()) + { + Number(ret,true); + } + else + { + ret = Token(SUB, line, column - 1); + } + } else { SingleCharOp(ret); @@ -140,9 +151,43 @@ void DLLexer::Id(Token& tok) tok = Token(ID, oss.str(), line, column); } -void DLLexer::Number(Token& tok) +void DLLexer::Number(Token& tok, bool isNegative) { ostringstream oss; + + // Get the first part of the number + oss << FloatingPoint(isNegative); + + // Get teh exponent if we have one + if ( current == 'e') + { + // consume the 'e' + oss << current; + consume(); + + // Capture the sign if we have one + if(current == '-') + { + consume(); + oss << FloatingPoint(true); + } + else + { + oss << FloatingPoint(false); + } + } + + tok = Token(NUM, oss.str(), line, column); +} + +std::string DLLexer::FloatingPoint(bool isNegative) +{ + ostringstream oss; + + // Make sure we capture the correct sign + oss << ((isNegative) ? '-' : '+'); + + // Capture the integer part do { oss << current; @@ -150,15 +195,16 @@ void DLLexer::Number(Token& tok) } while(isDigit()); + // Capture the decimal point if we have one if(current == '.') { - Decimal(tok, oss); + Decimal(oss); } - tok = Token(NUM, oss.str(), line, column); + return oss.str(); } -void DLLexer::Decimal(Token& tok, std::ostringstream& oss) +void DLLexer::Decimal(std::ostringstream& oss) { oss << current; consume(); @@ -176,8 +222,6 @@ void DLLexer::Decimal(Token& tok, std::ostringstream& oss) consume(); } while ( isDigit() ); - - tok = Token(NUM, oss.str(), line, column); } void DLLexer::Char(Token& tok) @@ -185,16 +229,14 @@ void DLLexer::Char(Token& tok) ostringstream oss; match('\''); - if(current != '\'') + if(current == '\\') { - oss << current; - consume(); + oss << EscapeSequence(); } else { - Exception ex(line,column); - ex << "Invalid character literal."; - throw ex; + oss << current; + consume(); } match('\''); @@ -207,8 +249,15 @@ void DLLexer::String(Token& tok) match('"'); while( isStringChar() ) { - oss << current; - consume(); + if(current == '\\') + { + oss << EscapeSequence(); + } + else + { + oss << current; + consume(); + } } match('"'); tok = Token( STRING, oss.str(), line, column ); @@ -350,3 +399,40 @@ void DLLexer::MultiCharOp(Token& tok) throw ex; } } + +std::string DLLexer::EscapeSequence() +{ + ostringstream oss; + + oss << current; + consume(); + + if ( current == 'x' ) + { + oss << current; + consume(); + for(int i = 0; i < 2; i++) + { + if ( ((current >= '0') || (current <= '9')) || + ((current >= 'a') || (current <= 'f')) || + ((current >= 'A') || (current <= 'F'))) + { + oss << current; + consume(); + } + else + { + Exception ex(line,column); + ex << "Invalid hexadecimal escape sequence."; + throw ex; + } + } + } + else + { + oss << current; + consume(); + } + return oss.str(); +} + diff --git a/source/dllexer/dllexer.h b/source/dllexer/dllexer.h index 3e1c10b..b3100a2 100644 --- a/source/dllexer/dllexer.h +++ b/source/dllexer/dllexer.h @@ -75,15 +75,15 @@ class DLLexer : public ILexer { Token next(void); void Id(Token& tok); - void Number(Token& tok); - void Decimal(Token& tok, std::ostringstream& oss); + void Number(Token& tok, bool isNegative); + std::string FloatingPoint(bool isNegative); + void Decimal(std::ostringstream& oss); void Char(Token& tok); void String(Token& tok); void Symbol(Token& tok); void SingleCharOp(Token& tok); void MultiCharOp(Token& tok); + std::string EscapeSequence(); }; - - #endif diff --git a/source/main.cpp b/source/main.cpp index dbea301..1e13c6f 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -29,12 +29,14 @@ int main(int argc, char** argv) // Setup Parser and Visitors DLParser parser; Scheme printer(output); + //Scheme debug_printer(std::cout); parser.input(new DLLexer(input)); // Parse the input stream parser.parse(); // Post process the AST (converts to scheme and prints to output file) + //parser.process( debug_printer ); parser.process( printer ); // Close the output file diff --git a/source/visitors/scheme/scheme.cpp b/source/visitors/scheme/scheme.cpp index 7232fff..ae1d40b 100644 --- a/source/visitors/scheme/scheme.cpp +++ b/source/visitors/scheme/scheme.cpp @@ -184,12 +184,41 @@ void Scheme::charToString(string ch) case ' ': stream << "#\\space"; break; - case '\n': - stream << "#\\newline"; - break; - case '\r': - stream << "#\\return"; + + // Convert escape sequence + case '\\': + switch ( ch.at(1) ) + { + case 'a': + stream << "#\\alarm"; + break; + + case 'b': + stream << "#\\backspace"; + break; + + case 'n': + stream << "#\\newline"; + break; + + case 'r': + stream << "#\\return"; + break; + + case 't': + stream << "#\\tab"; + break; + + case 'v': + stream << "#\\vtab"; + break; + + default: + stream << "#\\" << ch; + break; + }; break; + default: stream << "#\\" << ch; }