diff --git a/sablecc-runtime/src/main/java/de/hhu/stups/sablecc/patch/PositionedNode.java b/sablecc-runtime/src/main/java/de/hhu/stups/sablecc/patch/PositionedNode.java
index 574d0e9ad4aecb8052f5ee49bf27c1c210d0356a..dea3bfe839585b1d5d98d425f11f6895041752da 100644
--- a/sablecc-runtime/src/main/java/de/hhu/stups/sablecc/patch/PositionedNode.java
+++ b/sablecc-runtime/src/main/java/de/hhu/stups/sablecc/patch/PositionedNode.java
@@ -24,29 +24,10 @@ public class PositionedNode {
   }
 
   public SourcePosition getStartPos() {
-    /*
-     * Special treatment for tokens because they don't get a position in the
-     * PositionAspect
-     */
-    if (this instanceof IToken) {
-      final IToken token = (IToken) this;
-      return new SourcePosition(token.getLine(), token.getPos());
-    }
-
     return startPos;
   }
 
   public SourcePosition getEndPos() {
-    /*
-     * Special treatment for tokens because they don't get a position in the
-     * PositionAspect
-     */
-    if (this instanceof IToken) {
-      final IToken token = (IToken) this;
-      return new SourcePosition(token.getLine(), token.getPos()
-          + token.getText().length());
-    }
-
     return endPos;
   }
 
diff --git a/src/main/java/org/sablecc/sablecc/node/Token.java b/src/main/java/org/sablecc/sablecc/node/Token.java
index 861f4988b88f3612b9bb1a9b4104f5a9c2e805a0..54631a1e1e8a664268881b61f64ee33e28f87ad7 100644
--- a/src/main/java/org/sablecc/sablecc/node/Token.java
+++ b/src/main/java/org/sablecc/sablecc/node/Token.java
@@ -3,7 +3,7 @@
 package org.sablecc.sablecc.node;
 
 import de.hhu.stups.sablecc.patch.IToken;
-
+import de.hhu.stups.sablecc.patch.SourcePosition;
 
 
 public abstract class Token extends Node implements IToken
@@ -47,6 +47,9 @@ public abstract class Token extends Node implements IToken
     public void setText(String text)
     {
         this.text = text;
+        // Invalidate any already calculated SourcePositions
+        setStartPos(null);
+        setEndPos(null);
     }
 
     @Override
@@ -59,6 +62,9 @@ public abstract class Token extends Node implements IToken
     public void setLine(int line)
     {
         this.line = line;
+        // Invalidate any already calculated SourcePositions
+        setStartPos(null);
+        setEndPos(null);
     }
 
     @Override
@@ -71,6 +77,35 @@ public abstract class Token extends Node implements IToken
     public void setPos(int pos)
     {
         this.pos = pos;
+        // Invalidate any already calculated SourcePositions
+        setStartPos(null);
+        setEndPos(null);
+    }
+
+    // startPos and endPos are calculated lazily to avoid creating two SourcePosition objects for every token.
+
+    @Override
+    public SourcePosition getStartPos()
+    {
+        SourcePosition startPos = super.getStartPos();
+        if(startPos == null)
+        {
+            startPos = new SourcePosition(this.line, this.pos);
+            setStartPos(startPos);
+        }
+        return startPos;
+    }
+
+    @Override
+    public SourcePosition getEndPos()
+    {
+        SourcePosition endPos = super.getEndPos();
+        if(endPos == null)
+        {
+            endPos = new SourcePosition(this.line, this.pos + (this.text == null ? 0 : this.text.length()));
+            setEndPos(endPos);
+        }
+        return endPos;
     }
 
     @Override
diff --git a/src/main/resources/org/sablecc/sablecc/utils.txt b/src/main/resources/org/sablecc/sablecc/utils.txt
index 05a3036f91f445c5e259c817fc1d125ceaa91472..c0c38cc62e86c2bfce4944a9553213eb88be955b 100644
--- a/src/main/resources/org/sablecc/sablecc/utils.txt
+++ b/src/main/resources/org/sablecc/sablecc/utils.txt
@@ -192,7 +192,7 @@ Macro:Token
 package $0$;
 
 import de.hhu.stups.sablecc.patch.IToken;
-
+import de.hhu.stups.sablecc.patch.SourcePosition;
 
 
 public abstract class Token extends Node implements IToken
@@ -236,6 +236,9 @@ public abstract class Token extends Node implements IToken
     public void setText(String text)
     {
         this.text = text;
+        // Invalidate any already calculated SourcePositions
+        setStartPos(null);
+        setEndPos(null);
     }
 
     @Override
@@ -248,6 +251,9 @@ public abstract class Token extends Node implements IToken
     public void setLine(int line)
     {
         this.line = line;
+        // Invalidate any already calculated SourcePositions
+        setStartPos(null);
+        setEndPos(null);
     }
 
     @Override
@@ -260,6 +266,35 @@ public abstract class Token extends Node implements IToken
     public void setPos(int pos)
     {
         this.pos = pos;
+        // Invalidate any already calculated SourcePositions
+        setStartPos(null);
+        setEndPos(null);
+    }
+
+    // startPos and endPos are calculated lazily to avoid creating two SourcePosition objects for every token.
+
+    @Override
+    public SourcePosition getStartPos()
+    {
+        SourcePosition startPos = super.getStartPos();
+        if(startPos == null)
+        {
+            startPos = new SourcePosition(this.line, this.pos);
+            setStartPos(startPos);
+        }
+        return startPos;
+    }
+
+    @Override
+    public SourcePosition getEndPos()
+    {
+        SourcePosition endPos = super.getEndPos();
+        if(endPos == null)
+        {
+            endPos = new SourcePosition(this.line, this.pos + (this.text == null ? 0 : this.text.length()));
+            setEndPos(endPos);
+        }
+        return endPos;
     }
 
     @Override