]> git.mdlowis.com Git - archive/dlang.git/commitdiff
Updated character escape sequence translation and number matching pattern.
authorMike D. Lowis <mike@mdlowis.com>
Tue, 27 Mar 2012 17:39:16 +0000 (13:39 -0400)
committerMike D. Lowis <mike@mdlowis.com>
Tue, 27 Mar 2012 17:39:16 +0000 (13:39 -0400)
example.dl
res/environment.scm
source/dllexer/dllexer.cpp
source/dllexer/dllexer.h
source/main.cpp
source/visitors/scheme/scheme.cpp

index 8c248ea6ac7d9fd66b34df2d6e8e892e485e81a3..9634dae782f79c7fbe521893b89a874b65661875 100644 (file)
@@ -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
index 896e7ee5e1ab425d4e855b15578b8c9648357bf4..4096321adaa8fd712f3ae86699a4a30a28b453b0 100644 (file)
 (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
 ;------------------------------------------------------------------------------
index d4ea3fb373424d5529cb97ddec56eb74c62136b2..8631f4a8c77b614258fb7ea00ee37def8919294e 100644 (file)
@@ -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();
+}
+
index 3e1c10bb11f67f925359d401317b28d801220b40..b3100a298f1d2c9bb1482a36036c06a415ac75e9 100644 (file)
@@ -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
index dbea3011cdd6af718ad7e338236fa50e298d583e..1e13c6f7b940be275b65ddaf0bf96e349a904db5 100644 (file)
@@ -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
index 7232fffbfd01992db26d41e2e7eace80db52a8ac..ae1d40b28d855a5cb307b84dd171a582e9f33788 100644 (file)
@@ -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;
     }