[svn] r7604: nemerle/trunk/ncc/parsing/Lexer.n

VladD2 svnadmin at nemerle.org
Sat Apr 21 01:53:53 CEST 2007


Log:
Added recursive string (for DSL purpose). 

Author: VladD2
Date: Sat Apr 21 01:53:51 2007
New Revision: 7604

Modified:
   nemerle/trunk/ncc/parsing/Lexer.n

Modified: nemerle/trunk/ncc/parsing/Lexer.n
==============================================================================
--- nemerle/trunk/ncc/parsing/Lexer.n	(original)
+++ nemerle/trunk/ncc/parsing/Lexer.n	Sat Apr 21 01:53:51 2007
@@ -898,6 +898,44 @@
     loop ()
   }
 
+  /// Read <# .... <# ... #> ... #> string
+  protected get_recursive_string () : Token
+  {
+    mutable nestingLevel = 1;
+    def buf = Text.StringBuilder (1024);
+    _ = buf.Append ("<#");
+    def (startLine, startCol) = (line, col - 2);
+    def loop (ch)
+    {
+      | '<' when peek () == '#' => _ = read (); nestingLevel++; _ = buf.Append ("<#"); loop (read ())
+      | '#' =>
+        def next = read ();
+        if (next == '>')
+        {
+          _ = buf.Append ("#>");
+          nestingLevel--;
+          if (nestingLevel == 0) Token.StringLiteral (buf.ToString ())
+          else                   loop (read ())
+        }
+        else
+        {
+          _ = buf.Append ('#');
+          _ = buf.Append (next);
+          loop (read ())
+        }
+
+      | '\0' =>
+          Message.Error (this.Location, "Unterminated string literal"); // like MS csc
+          Token.StringLiteral (buf.ToString ())
+
+      | _ => _ = buf.Append (ch); loop (read ())
+    }
+
+    def tok = loop (read ());
+    tok.Location = Location (file_idx, startLine, startCol, line, col);
+    tok
+  }
+
   abstract protected comment_beginning () : char;
 
   /// returns true if there is some character in the input pending
@@ -1015,7 +1053,8 @@
       | ',' => Token.Comma ()
       | ';' => Token.Semicolon (generated = false)
 
-      | '<' when peek_or_white () == '[' => ignore (read ()); Token.BeginQuote ()
+      | '<' when peek () == '[' => ignore (read ()); Token.BeginQuote ()
+      | '<' when peek () == '#' => ignore (read ()); get_recursive_string ()
         
       | '@' =>
         def next = read ();
@@ -1062,8 +1101,12 @@
         Fake();
         def startLine = this.Location.Line;
         def startCol  = this.Location.Column;
+        _ = eat_whitespace ();
+        def next = peek ();
 
-        if (eat_whitespace () && (peek_or_white () == '"' || peek_or_white () == '@')) {
+        match (next)
+        {
+          | '"' | '@' | '<' when peek () == '#' =>
           // we will not warn about $ in string literal in this mode
           def strStartLoc = this.Location;
           def c = read ();
@@ -1071,7 +1114,10 @@
           def str =
             if (c == '"')
               get_string (c, true)
-            else {
+              else if (c == '<' && peek () == '#')
+                get_recursive_string ()
+              else
+              {
               unless (read () == '"')
                 Message.Error (this.Location, "expected string literal after @");
           
@@ -1084,8 +1130,9 @@
           def dolTok = Token.Operator (dolLoc, "$");
           dolTok.Next = str;
           Token.RoundGroup (groupLok, Token.LooseGroup (groupLok, dolTok))
+
+          | _ => get_op (ch)
         }
-        else get_op (ch)
                               
       | '^' | '~' | '?' | '#'
         => get_op (ch)



More information about the svn mailing list