SmallSense__SmalltalkParser.st
changeset 85 d6a3fdbd87db
parent 68 681357e18fe5
child 96 12fe1a59dfd1
--- a/SmallSense__SmalltalkParser.st	Mon Sep 16 18:13:00 2013 +0100
+++ b/SmallSense__SmalltalkParser.st	Mon Sep 16 23:20:08 2013 +0100
@@ -145,6 +145,67 @@
 
 !SmalltalkParser methodsFor:'parsing-expressions'!
 
+keywordExpression
+    "parse a keyword-expression; return a node-tree, nil or #Error.
+
+     keywordExpression ::= binaryexpression
+                           | { KEYWORD-PART binaryExpression }
+    "
+
+    |receiver expr|
+
+    receiver := self binaryExpression.
+    (receiver == #Error) ifTrue:[^ #Error].
+    (tokenType == #EOF) ifTrue:[^ receiver].
+    tokenType == $] ifTrue:[^ receiver].
+    tokenType == $) ifTrue:[^ receiver].
+    expr := self keywordExpressionFor:receiver.
+
+    "/ expr could be an assignment as well, here
+    (ignoreWarnings or:[ignoreErrors]) ifFalse:[
+        "/ for a better error message, in case of a missing period in the previous message,
+        "/    <expr> <missing period> foo := ...
+        "/ would be parsed as unary message foo; detect this here, instead of high up in the calling hierarchy,
+        "/ where it is difficult to provide a reasonable error message
+        tokenType == #':=' ifTrue:[
+            | positionOfPeriod exprLast |
+
+            "/ Find the very last unary send node, Consider:
+            "/    x := 2
+            "/    y := false
+            "/ 
+            "/    x := 2 between: 0 and: 10
+            "/    y := false  
+            "/ 
+            "/    x := 2 between: 0 and: self max
+            "/    y := false  
+
+            exprLast := expr.
+            [ exprLast isMessage and: [ exprLast isUnaryMessage not ] ] whileTrue:[
+                exprLast := exprLast args last.
+            ].
+            (exprLast isMessage and: [ exprLast isUnaryMessage ] ) ifTrue:[
+                positionOfPeriod := exprLast receiver positionToInsertPeriodForStatementSeparation
+            ].
+            positionOfPeriod notNil ifTrue:[
+                "/Try to recover
+                expr := ParseErrorNode new
+                        startPosition:expr startPosition endPosition: positionOfPeriod - 1;
+                        errorString: ('":=" unexpected. Probably missing "." in previous expression.');
+                        children: (Array with: expr);
+                        yourself.        
+                source position: positionOfPeriod.
+                tokenType := $.
+            ]
+        ].
+    ].
+
+    ^ expr
+
+    "Created: / 16-09-2013 / 17:23:09 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 16-09-2013 / 23:18:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
 primary
     | nodeOrError |