Some bugs fixed
[phpeclipse.git] / net.sourceforge.phpeclipse / src / test / PHPParser.jj
index 2de24e2..b49b15a 100644 (file)
@@ -50,6 +50,7 @@ import net.sourceforge.phpdt.internal.compiler.parser.PHPReqIncDeclaration;
  */
 public final class PHPParser extends PHPParserSuperclass {
 
+  /** The file that is parsed. */
   private static IFile fileToParse;
 
   /** The current segment */
@@ -58,9 +59,15 @@ public final class PHPParser extends PHPParserSuperclass {
   private static final String PARSE_ERROR_STRING = "Parse error"; //$NON-NLS-1$
   private static final String PARSE_WARNING_STRING = "Warning"; //$NON-NLS-1$
   PHPOutlineInfo outlineInfo;
+
+  /** The error level of the current ParseException. */
   private static int errorLevel = ERROR;
+  /** The message of the current ParseException. If it's null it's because the parse exception wasn't handled */
   private static String errorMessage;
 
+  private static int errorStart = -1;
+  private static int errorEnd = -1;
+
   public PHPParser() {
   }
 
@@ -128,12 +135,23 @@ public final class PHPParser extends PHPParserSuperclass {
    */
   private static void setMarker(final ParseException e) {
     try {
-      setMarker(fileToParse,
-                errorMessage,
-                jj_input_stream.tokenBegin,
-                jj_input_stream.tokenBegin + e.currentToken.image.length(),
-                errorLevel,
-                "Line " + e.currentToken.beginLine);
+      if (errorStart == -1) {
+        setMarker(fileToParse,
+                  errorMessage,
+                  jj_input_stream.tokenBegin,
+                  jj_input_stream.tokenBegin + e.currentToken.image.length(),
+                  errorLevel,
+                  "Line " + e.currentToken.beginLine);
+      } else {
+        setMarker(fileToParse,
+                  errorMessage,
+                  errorStart,
+                  errorEnd,
+                  errorLevel,
+                  "Line " + e.currentToken.beginLine);
+        errorStart = -1;
+        errorEnd = -1;
+      }
     } catch (CoreException e2) {
       PHPeclipsePlugin.log(e2);
     }
@@ -249,9 +267,9 @@ PARSER_END(PHPParser)
 
 <DEFAULT> TOKEN :
 {
-  <PHPSTARTSHORT : "<?"> : PHPPARSING
+  <PHPSTARTSHORT : "<?">   : PHPPARSING
 | <PHPSTARTLONG : "<?php"> : PHPPARSING
-| <PHPECHOSTART : "<?=">      : PHPPARSING
+| <PHPECHOSTART : "<?=">   : PHPPARSING
 }
 
 <PHPPARSING> TOKEN :
@@ -282,6 +300,8 @@ PARSER_END(PHPParser)
 {
   "//" : IN_SINGLE_LINE_COMMENT
 |
+  "#"  : IN_SINGLE_LINE_COMMENT
+|
   <"/**" ~["/"]> { input_stream.backup(1); } : IN_FORMAL_COMMENT
 |
   "/*" : IN_MULTI_LINE_COMMENT
@@ -610,10 +630,28 @@ void ClassDeclaration() :
 {
   final PHPClassDeclaration classDeclaration;
   final Token className;
-  final int pos = jj_input_stream.bufpos;
+  final int pos;
 }
 {
-  <CLASS> className = <IDENTIFIER> [ <EXTENDS> <IDENTIFIER> ]
+  <CLASS>
+  try {
+    {pos = jj_input_stream.bufpos;}
+    className = <IDENTIFIER>
+  } catch (ParseException e) {
+    errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', identifier expected";
+    errorLevel   = ERROR;
+    throw e;
+  }
+  [
+    <EXTENDS>
+    try {
+      <IDENTIFIER>
+    } catch (ParseException e) {
+      errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', identifier expected";
+      errorLevel   = ERROR;
+      throw e;
+    }
+  ]
   {
     if (currentSegment != null) {
       classDeclaration = new PHPClassDeclaration(currentSegment,className.image,pos);
@@ -832,7 +870,17 @@ void MethodDeclaration() :
   final PHPFunctionDeclaration functionDeclaration;
 }
 {
-  <FUNCTION> functionDeclaration = MethodDeclarator()
+  <FUNCTION>
+  try {
+    functionDeclaration = MethodDeclarator()
+  } catch (ParseException e) {
+    if (errorMessage != null) {
+      throw e;
+    }
+    errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', function identifier expected";
+    errorLevel   = ERROR;
+    throw e;
+  }
   {
     if (currentSegment != null) {
       currentSegment.add(functionDeclaration);
@@ -1145,7 +1193,13 @@ String EqualityExpression() :
     | operator = <BANGDOUBLEEQUAL>
     | operator = <TRIPLEEQUAL>
   )
-  expr = RelationalExpression()
+  try {
+    expr = RelationalExpression()
+  } catch (ParseException e) {
+    errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', expression expected after '"+operator.image+"'";
+    errorLevel   = ERROR;
+    throw e;
+  }
   {
     buff.append(operator.image);
     buff.append(expr);
@@ -1422,7 +1476,14 @@ String VariableSuffix() :
   String expr = null;
 }
 {
-  <CLASSACCESS> expr = VariableName()
+  <CLASSACCESS>
+  try {
+    expr = VariableName()
+  } catch (ParseException e) {
+    errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', function call or field access expected";
+    errorLevel   = ERROR;
+    throw e;
+  }
   {return "->" + expr;}
 | 
   <LBRACKET> [ expr = Expression() ]
@@ -1489,7 +1550,7 @@ String expr = null;
   try {
     <RPAREN>
   } catch (ParseException e) {
-    errorMessage = "')' expected to close the argument list";
+    errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', ')' expected to close the argument list";
     errorLevel   = ERROR;
     throw e;
   }
@@ -1524,17 +1585,16 @@ final StringBuffer buff = new StringBuffer();
    {return buff.toString();}
 }
 
-/*
- * Statement syntax follows.
+/**
+ * A Statement without break
  */
-
 void StatementNoBreak() :
 {}
 {
   LOOKAHEAD(2)
   Expression()
   try {
-    (<SEMICOLON> | <PHPEND>)
+    (<SEMICOLON> | <PHPEND> {PHPParserTokenManager.SwitchTo(PHPParserTokenManager.DEFAULT);})
   } catch (ParseException e) {
     errorMessage = "';' expected";
     errorLevel   = ERROR;
@@ -1582,6 +1642,9 @@ void StatementNoBreak() :
   GlobalStatement()
 }
 
+/**
+ * A Normal statement
+ */
 void Statement() :
 {}
 {
@@ -1604,7 +1667,7 @@ void IncludeStatement() :
     }
   }
   try {
-    (<SEMICOLON> | "?>")
+    (<SEMICOLON> | <PHPEND> {PHPParserTokenManager.SwitchTo(PHPParserTokenManager.DEFAULT);})
   } catch (ParseException e) {
     errorMessage = "';' expected";
     errorLevel   = ERROR;
@@ -1619,7 +1682,7 @@ void IncludeStatement() :
     }
   }
   try {
-    (<SEMICOLON> | "?>")
+    (<SEMICOLON> | <PHPEND> {PHPParserTokenManager.SwitchTo(PHPParserTokenManager.DEFAULT);})
   } catch (ParseException e) {
     errorMessage = "';' expected";
     errorLevel   = ERROR;
@@ -1634,7 +1697,7 @@ void IncludeStatement() :
     }
   }
   try {
-    (<SEMICOLON> | "?>")
+    (<SEMICOLON> | <PHPEND> {PHPParserTokenManager.SwitchTo(PHPParserTokenManager.DEFAULT);})
   } catch (ParseException e) {
     errorMessage = "';' expected";
     errorLevel   = ERROR;
@@ -1649,7 +1712,7 @@ void IncludeStatement() :
     }
   }
   try {
-    (<SEMICOLON> | "?>")
+    (<SEMICOLON> | <PHPEND> {PHPParserTokenManager.SwitchTo(PHPParserTokenManager.DEFAULT);})
   } catch (ParseException e) {
     errorMessage = "';' expected";
     errorLevel   = ERROR;
@@ -1676,19 +1739,37 @@ String ListExpression() :
   String expr;
 }
 {
-  <LIST> <LPAREN>
+  <LIST>
+  try {
+    <LPAREN>
+  } catch (ParseException e) {
+    errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', '(' expected";
+    errorLevel   = ERROR;
+    throw e;
+  }
   [
     expr = VariableDeclaratorId()
     {buff.append(expr);}
   ]
-  <COMMA>
-  {buff.append(",");}
   [
+    try {
+      <COMMA>
+    } catch (ParseException e) {
+      errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', ',' expected";
+      errorLevel   = ERROR;
+      throw e;
+    }
     expr = VariableDeclaratorId()
-    {buff.append(expr);}
+    {buff.append(",").append(expr);}
   ]
   {buff.append(")");}
-  <RPAREN>
+  try {
+    <RPAREN>
+  } catch (ParseException e) {
+    errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', ')' expected";
+    errorLevel   = ERROR;
+    throw e;
+  }
   [ <ASSIGN> expr = Expression() {buff.append("(").append(expr);}]
   {return buff.toString();}
 }
@@ -1698,7 +1779,7 @@ void EchoStatement() :
 {
   <ECHO> Expression() (<COMMA> Expression())*
   try {
-    (<SEMICOLON> | "?>")
+    (<SEMICOLON> | <PHPEND> {PHPParserTokenManager.SwitchTo(PHPParserTokenManager.DEFAULT);})
   } catch (ParseException e) {
     errorMessage = "';' expected after 'echo' statement";
     errorLevel   = ERROR;
@@ -1711,7 +1792,7 @@ void GlobalStatement() :
 {
   <GLOBAL> VariableDeclaratorId() (<COMMA> VariableDeclaratorId())*
   try {
-    (<SEMICOLON> | "?>")
+    (<SEMICOLON> | <PHPEND> {PHPParserTokenManager.SwitchTo(PHPParserTokenManager.DEFAULT);})
   } catch (ParseException e) {
     errorMessage = "';' expected";
     errorLevel   = ERROR;
@@ -1724,7 +1805,7 @@ void StaticStatement() :
 {
   <STATIC> VariableDeclarator() (<COMMA> VariableDeclarator())*
   try {
-    (<SEMICOLON> | "?>")
+    (<SEMICOLON> | <PHPEND> {PHPParserTokenManager.SwitchTo(PHPParserTokenManager.DEFAULT);})
   } catch (ParseException e) {
     errorMessage = "';' expected";
     errorLevel   = ERROR;
@@ -1752,7 +1833,7 @@ void Block() :
   try {
     <RBRACE>
   } catch (ParseException e) {
-    errorMessage = "unexpected token : "+ e.currentToken.image +", '}' expected";
+    errorMessage = "unexpected token : '"+ e.currentToken.image +"', '}' expected";
     errorLevel   = ERROR;
     throw e;
   }
@@ -1768,6 +1849,9 @@ void BlockStatement() :
   MethodDeclaration()
 }
 
+/**
+ * A Block statement that will not contain any 'break'
+ */
 void BlockStatementNoBreak() :
 {}
 {
@@ -1845,15 +1929,7 @@ void SwitchStatement() :
     (
       line = SwitchLabel()
       ( BlockStatementNoBreak() )*
-      [ breakToken = <BREAK>
-        try {
-          <SEMICOLON>
-        } catch (ParseException e) {
-          errorMessage = "';' expected after 'break' keyword";
-          errorLevel   = ERROR;
-          throw e;
-        }
-      ]
+      [ breakToken = BreakStatement() ]
       {
         try {
           if (breakToken == null) {
@@ -1877,6 +1953,22 @@ void SwitchStatement() :
   }
 }
 
+Token BreakStatement() :
+{
+  final Token token;
+}
+{
+  token = <BREAK> [ Expression() ]
+  try {
+    <SEMICOLON>
+  } catch (ParseException e) {
+    errorMessage = "';' expected after 'break' keyword";
+    errorLevel   = ERROR;
+    throw e;
+  }
+  {return token;}
+}
+
 int SwitchLabel() :
 {
   final Token token;
@@ -2022,7 +2114,7 @@ void WhileStatement0(final int start, final int end) :
     throw e;
   }
   try {
-    (<SEMICOLON> | "?>")
+    (<SEMICOLON> | <PHPEND> {PHPParserTokenManager.SwitchTo(PHPParserTokenManager.DEFAULT);})
   } catch (ParseException e) {
     errorMessage = "';' expected after 'endwhile' keyword";
     errorLevel   = ERROR;
@@ -2037,7 +2129,7 @@ void DoStatement() :
 {
   <DO> Statement() <WHILE> Condition("while")
   try {
-    (<SEMICOLON> | "?>")
+    (<SEMICOLON> | <PHPEND> {PHPParserTokenManager.SwitchTo(PHPParserTokenManager.DEFAULT);})
   } catch (ParseException e) {
     errorMessage = "';' expected";
     errorLevel   = ERROR;
@@ -2159,19 +2251,6 @@ void StatementExpressionList() :
   StatementExpression() ( <COMMA> StatementExpression() )*
 }
 
-void BreakStatement() :
-{}
-{
-  <BREAK> [ <IDENTIFIER> ]
-  try {
-    <SEMICOLON>
-  } catch (ParseException e) {
-    errorMessage = "';' expected after 'break' statement";
-    errorLevel   = ERROR;
-    throw e;
-  }
-}
-
 void ContinueStatement() :
 {}
 {