intial core test module
[phpeclipse.git] / net.sourceforge.phpeclipse / src / test / PHPParser.jj
index 9e3fc1d..e3b05cf 100644 (file)
@@ -48,7 +48,7 @@ import net.sourceforge.phpdt.internal.compiler.parser.PHPReqIncDeclaration;
  * You can test the parser with the PHPParserTestCase2.java
  * @author Matthieu Casanova
  */
-public class PHPParser extends PHPParserSuperclass {
+public final class PHPParser extends PHPParserSuperclass {
 
   private static IFile fileToParse;
 
@@ -64,7 +64,7 @@ public class PHPParser extends PHPParserSuperclass {
   public PHPParser() {
   }
 
-  public void setFileToParse(IFile fileToParse) {
+  public final void setFileToParse(IFile fileToParse) {
     this.fileToParse = fileToParse;
   }
 
@@ -73,7 +73,7 @@ public class PHPParser extends PHPParserSuperclass {
     this.fileToParse = fileToParse;
   }
 
-  public void phpParserTester(String strEval) throws CoreException, ParseException {
+  public static final void phpParserTester(String strEval) throws CoreException, ParseException {
     PHPParserTokenManager.SwitchTo(PHPParserTokenManager.PHPPARSING);
     StringReader stream = new StringReader(strEval);
     if (jj_input_stream == null) {
@@ -83,7 +83,7 @@ public class PHPParser extends PHPParserSuperclass {
     phpTest();
   }
 
-  public void htmlParserTester(String strEval) throws CoreException, ParseException {
+  public static final void htmlParserTester(String strEval) throws CoreException, ParseException {
     StringReader stream = new StringReader(strEval);
     if (jj_input_stream == null) {
       jj_input_stream = new SimpleCharStream(stream, 1, 1);
@@ -92,7 +92,7 @@ public class PHPParser extends PHPParserSuperclass {
     phpFile();
   }
 
-  public PHPOutlineInfo parseInfo(Object parent, String s) {
+  public final PHPOutlineInfo parseInfo(Object parent, String s) {
     outlineInfo = new PHPOutlineInfo(parent);
     currentSegment = outlineInfo.getDeclarations();
     StringReader stream = new StringReader(s);
@@ -201,8 +201,12 @@ public class PHPParser extends PHPParserSuperclass {
     }
   }
 
-  public void parse(String s) throws CoreException {
-    ReInit(new StringReader(s));
+  public final void parse(String s) throws CoreException {
+    StringReader stream = new StringReader(s);
+    if (jj_input_stream == null) {
+      jj_input_stream = new SimpleCharStream(stream, 1, 1);
+    }
+    ReInit(stream);
     try {
       parse();
     } catch (ParseException e) {
@@ -232,7 +236,7 @@ public class PHPParser extends PHPParserSuperclass {
     }
   }
 
-  public void parse() throws ParseException {
+  public static final void parse() throws ParseException {
          phpFile();
   }
 }
@@ -277,10 +281,14 @@ PARSER_END(PHPParser)
   "/*" : IN_MULTI_LINE_COMMENT
 }
 
-<IN_SINGLE_LINE_COMMENT>
-SPECIAL_TOKEN :
+<IN_SINGLE_LINE_COMMENT> SPECIAL_TOKEN :
 {
-  <SINGLE_LINE_COMMENT: "\n" | "\r" | "\r\n" | "?>" > : PHPPARSING
+  <SINGLE_LINE_COMMENT: "\n" | "\r" | "\r\n" > : PHPPARSING
+}
+
+<IN_SINGLE_LINE_COMMENT> TOKEN :
+{
+  <SINGLE_LINE_COMMENT_PHPEND : "?>" > : DEFAULT
 }
 
 <IN_FORMAL_COMMENT>
@@ -352,6 +360,10 @@ MORE :
 | < TRUE: "true" >
 | < WHILE: "while" >
 | < ENDWHILE : "endwhile" >
+| <ENDIF : "endif" >
+| <ENDFOR : "endfor" >
+| <FOREACH : "foreach" >
+| <AS : "as" >
 }
 
 /* TYPES */
@@ -481,6 +493,7 @@ MORE :
 | <LE: "<=" >
 | <GE: ">=" >
 | <NE: "!=" >
+| <DIF: "<>" >
 | <SC_OR: "||" >
 | <SC_AND: "&&" >
 | <INCR: "++" >
@@ -536,7 +549,15 @@ void phpFile() :
 {}
 {
   try {
-  (<PHPSTART> Php() <PHPEND>)*
+  (<PHPSTART> Php()
+  try {
+    <PHPEND>
+  } catch (ParseException e) {
+    errorMessage = "'?>' expected";
+    errorLevel   = ERROR;
+    throw e;
+  }
+    )*
   <EOF>
   } catch (TokenMgrError e) {
     errorMessage = e.getMessage();
@@ -555,18 +576,22 @@ void ClassDeclaration() :
 {
   PHPClassDeclaration classDeclaration;
   Token className;
-  int pos = jj_input_stream.bufpos;
+  final int pos = jj_input_stream.bufpos;
 }
 {
   <CLASS> className = <IDENTIFIER> [ <EXTENDS> <IDENTIFIER> ]
   {
-    classDeclaration = new PHPClassDeclaration(currentSegment,className.image,pos);
-    currentSegment.add(classDeclaration);
-    currentSegment = classDeclaration;
+    if (currentSegment != null) {
+      classDeclaration = new PHPClassDeclaration(currentSegment,className.image,pos);
+      currentSegment.add(classDeclaration);
+      currentSegment = classDeclaration;
+    }
   }
   ClassBody()
   {
-    currentSegment = (PHPSegmentWithChildren) currentSegment.getParent();
+    if (currentSegment != null) {
+      currentSegment = (PHPSegmentWithChildren) currentSegment.getParent();
+    }
   }
 }
 
@@ -604,10 +629,18 @@ void FieldDeclaration() :
 }
 {
   <VAR> variableDeclaration = VariableDeclarator()
-  {currentSegment.add(variableDeclaration);}
+  {
+    if (currentSegment != null) {
+      currentSegment.add(variableDeclaration);
+    }
+  }
   ( <COMMA>
-    variableDeclaration = VariableDeclarator()
-    {currentSegment.add(variableDeclaration);}
+      variableDeclaration = VariableDeclarator()
+      {
+      if (currentSegment != null) {
+        currentSegment.add(variableDeclaration);
+      }
+      }
   )*
   try {
     <SEMICOLON>
@@ -622,7 +655,7 @@ PHPVarDeclaration VariableDeclarator() :
 {
   String varName;
   String varValue = null;
-  int pos = jj_input_stream.bufpos;
+  final int pos = jj_input_stream.bufpos;
 }
 {
   varName = VariableDeclaratorId()
@@ -647,7 +680,7 @@ PHPVarDeclaration VariableDeclarator() :
 String VariableDeclaratorId() :
 {
   String expr;
-  StringBuffer buff = new StringBuffer();
+  final StringBuffer buff = new StringBuffer();
 }
 {
   try {
@@ -736,7 +769,7 @@ String VariableInitializer() :
 String ArrayVariable() :
 {
 String expr;
-StringBuffer buff = new StringBuffer();
+final StringBuffer buff = new StringBuffer();
 }
 {
   expr = Expression()
@@ -749,7 +782,7 @@ StringBuffer buff = new StringBuffer();
 String ArrayInitializer() :
 {
 String expr = null;
-StringBuffer buff = new StringBuffer("(");
+final StringBuffer buff = new StringBuffer("(");
 }
 {
   <LPAREN> [ expr = ArrayVariable()
@@ -771,12 +804,16 @@ void MethodDeclaration() :
 {
   <FUNCTION> functionDeclaration = MethodDeclarator()
   {
-    currentSegment.add(functionDeclaration);
-    currentSegment = functionDeclaration;
+    if (currentSegment != null) {
+      currentSegment.add(functionDeclaration);
+      currentSegment = functionDeclaration;
+    }
   }
   Block()
   {
-    currentSegment = (PHPSegmentWithChildren) currentSegment.getParent();
+    if (currentSegment != null) {
+      currentSegment = (PHPSegmentWithChildren) currentSegment.getParent();
+    }
   }
 }
 
@@ -785,7 +822,7 @@ PHPFunctionDeclaration MethodDeclarator() :
   Token identifier;
   StringBuffer methodDeclaration = new StringBuffer();
   String formalParameters;
-  int pos = jj_input_stream.bufpos;
+  final int pos = jj_input_stream.bufpos;
 }
 {
   [ <BIT_AND> {methodDeclaration.append("&");} ]
@@ -834,7 +871,7 @@ String FormalParameters() :
 String FormalParameter() :
 {
   PHPVarDeclaration variableDeclaration;
-  StringBuffer buff = new StringBuffer();
+  final StringBuffer buff = new StringBuffer();
 }
 {
   [<BIT_AND> {buff.append("&");}] variableDeclaration = VariableDeclarator()
@@ -870,6 +907,9 @@ String Type() :
 |
   <INTEGER>
   {return "integer";}
+|
+  <OBJECT>
+  {return "object";}
 }
 
 String Expression() :
@@ -955,7 +995,7 @@ String ConditionalOrExpression() :
   String expr;
   Token operator;
   String expr2 = null;
-  StringBuffer buff = new StringBuffer();
+  final StringBuffer buff = new StringBuffer();
 }
 {
   expr = ConditionalAndExpression()
@@ -979,7 +1019,7 @@ String ConditionalAndExpression() :
   String expr;
   Token operator;
   String expr2 = null;
-  StringBuffer buff = new StringBuffer();
+  final StringBuffer buff = new StringBuffer();
 }
 {
   expr = ConcatExpression()
@@ -1002,7 +1042,7 @@ String ConcatExpression() :
 {
   String expr;
   String expr2 = null;
-  StringBuffer buff = new StringBuffer();
+  final StringBuffer buff = new StringBuffer();
 }
 {
   expr = InclusiveOrExpression()
@@ -1025,7 +1065,7 @@ String InclusiveOrExpression() :
 {
   String expr;
   String expr2 = null;
-  StringBuffer buff = new StringBuffer();
+  final StringBuffer buff = new StringBuffer();
 }
 {
   expr = ExclusiveOrExpression()
@@ -1048,7 +1088,7 @@ String ExclusiveOrExpression() :
 {
   String expr;
   String expr2 = null;
-  StringBuffer buff = new StringBuffer();
+  final StringBuffer buff = new StringBuffer();
 }
 {
   expr = AndExpression()
@@ -1069,9 +1109,9 @@ String ExclusiveOrExpression() :
 
 String AndExpression() :
 {
-  String expr;
+  final String expr;
   String expr2 = null;
-  StringBuffer buff = new StringBuffer();
+  final StringBuffer buff = new StringBuffer();
 }
 {
   expr = EqualityExpression()
@@ -1095,13 +1135,14 @@ String EqualityExpression() :
   String expr;
   Token operator;
   String expr2;
-  StringBuffer buff = new StringBuffer();
+  final StringBuffer buff = new StringBuffer();
 }
 {
   expr = RelationalExpression()
   {buff.append(expr);}
   (
   (   operator = <EQ>
+    | operator = <DIF>
     | operator = <NE>
     | operator = <BANGDOUBLEEQUAL>
     | operator = <TRIPLEEQUAL>
@@ -1120,7 +1161,7 @@ String RelationalExpression() :
   String expr;
   Token operator;
   String expr2;
-  StringBuffer buff = new StringBuffer();
+  final StringBuffer buff = new StringBuffer();
 }
 {
   expr = ShiftExpression()
@@ -1139,17 +1180,16 @@ String ShiftExpression() :
 {
   String expr;
   Token operator;
-  String expr2;
-  StringBuffer buff = new StringBuffer();
+  final StringBuffer buff = new StringBuffer();
 }
 {
   expr = AdditiveExpression()
   {buff.append(expr);}
   (
-  (operator = <LSHIFT> | operator = <RSIGNEDSHIFT> | operator = <RUNSIGNEDSHIFT> ) expr2 = AdditiveExpression()
+  (operator = <LSHIFT> | operator = <RSIGNEDSHIFT> | operator = <RUNSIGNEDSHIFT> ) expr = AdditiveExpression()
   {
     buff.append(operator.image);
-    buff.append(expr2);
+    buff.append(expr);
   }
   )*
   {return buff.toString();}
@@ -1159,17 +1199,16 @@ String AdditiveExpression() :
 {
   String expr;
   Token operator;
-  String expr2;
-  StringBuffer buff = new StringBuffer();
+  final StringBuffer buff = new StringBuffer();
 }
 {
   expr = MultiplicativeExpression()
   {buff.append(expr);}
   (
-   ( operator = <PLUS> | operator = <MINUS> ) expr2 = MultiplicativeExpression()
+   ( operator = <PLUS> | operator = <MINUS> ) expr = MultiplicativeExpression()
   {
     buff.append(operator.image);
-    buff.append(expr2);
+    buff.append(expr);
   }
    )*
   {return buff.toString();}
@@ -1177,17 +1216,17 @@ String AdditiveExpression() :
 
 String MultiplicativeExpression() :
 {
-  String expr, expr2;
+  String expr;
   Token operator;
   final StringBuffer buff = new StringBuffer();}
 {
   expr = UnaryExpression()
   {buff.append(expr);}
   (
-  ( operator = <STAR> | operator = <SLASH> | operator = <REM> ) expr2 = UnaryExpression()
+  ( operator = <STAR> | operator = <SLASH> | operator = <REM> ) expr = UnaryExpression()
   {
     buff.append(operator.image);
-    buff.append(expr2);
+    buff.append(expr);
   }
   )*
   {return buff.toString();}
@@ -1279,8 +1318,7 @@ String UnaryExpressionNotPlusMinus() :
 
 String CastExpression() :
 {
-String type;
-String expr;
+final String type, expr;
 }
 {
   <LPAREN> type = Type() <RPAREN> expr = UnaryExpression()
@@ -1328,7 +1366,7 @@ String PrimaryExpression() :
 
 String ArrayDeclarator() :
 {
-  String expr;
+  final String expr;
 }
 {
   <ARRAY> expr = ArrayInitializer()
@@ -1465,7 +1503,7 @@ String expr = null;
 String ArgumentList() :
 {
 String expr;
-StringBuffer buff = new StringBuffer();
+final StringBuffer buff = new StringBuffer();
 }
 {
   expr = Expression()
@@ -1528,6 +1566,8 @@ void Statement() :
 |
   ForStatement()
 |
+  ForeachStatement()
+|
   BreakStatement()
 |
   ContinueStatement()
@@ -1546,12 +1586,16 @@ void Statement() :
 void IncludeStatement() :
 {
   String expr;
-  int pos = jj_input_stream.bufpos;
+  final int pos = jj_input_stream.bufpos;
 }
 {
   <REQUIRE>
   expr = Expression()
-  {currentSegment.add(new PHPReqIncDeclaration(currentSegment, "require",pos,expr));}
+  {
+    if (currentSegment != null) {
+      currentSegment.add(new PHPReqIncDeclaration(currentSegment, "require",pos,expr));
+    }
+  }
   try {
     (<SEMICOLON> | "?>")
   } catch (ParseException e) {
@@ -1562,7 +1606,11 @@ void IncludeStatement() :
 |
   <REQUIRE_ONCE>
   expr = Expression()
-  {currentSegment.add(new PHPReqIncDeclaration(currentSegment, "require_once",pos,expr));}
+  {
+    if (currentSegment != null) {
+      currentSegment.add(new PHPReqIncDeclaration(currentSegment, "require_once",pos,expr));
+    }
+  }
   try {
     (<SEMICOLON> | "?>")
   } catch (ParseException e) {
@@ -1573,7 +1621,11 @@ void IncludeStatement() :
 |
   <INCLUDE>
   expr = Expression()
-  {currentSegment.add(new PHPReqIncDeclaration(currentSegment, "include",pos,expr));}
+  {
+    if (currentSegment != null) {
+      currentSegment.add(new PHPReqIncDeclaration(currentSegment, "include",pos,expr));
+    }
+  }
   try {
     (<SEMICOLON> | "?>")
   } catch (ParseException e) {
@@ -1584,7 +1636,11 @@ void IncludeStatement() :
 |
   <INCLUDE_ONCE>
   expr = Expression()
-  {currentSegment.add(new PHPReqIncDeclaration(currentSegment, "include_once",pos,expr));}
+  {
+    if (currentSegment != null) {
+      currentSegment.add(new PHPReqIncDeclaration(currentSegment, "include_once",pos,expr));
+    }
+  }
   try {
     (<SEMICOLON> | "?>")
   } catch (ParseException e) {
@@ -1596,7 +1652,7 @@ void IncludeStatement() :
 
 String PrintExpression() :
 {
-  StringBuffer buff = new StringBuffer("print ");
+  final StringBuffer buff = new StringBuffer("print ");
   String expr;
 }
 {
@@ -1727,9 +1783,12 @@ void IfStatement() :
  * else's to the innermost if statement.  The LOOKAHEAD specification
  * is to tell JavaCC that we know what we are doing.
  */
-{}
 {
-  <IF> Condition("if") Statement() ( LOOKAHEAD(1) ElseIfStatement() )* [ LOOKAHEAD(1) <ELSE> Statement() ]
+  Token token;
+  final int pos = jj_input_stream.bufpos;
+}
+{
+  token = <IF> Condition("if") IfStatement0(pos,pos+token.image.length())
 }
 
 void Condition(String keyword) :
@@ -1752,6 +1811,52 @@ void Condition(String keyword) :
   }
 }
 
+void IfStatement0(int start,int end) :
+{
+}
+{
+  <COLON> (Statement())* (ElseIfStatementColon())* [ElseStatementColon()]
+
+  {try {
+  setMarker(fileToParse,
+            "Ugly syntax detected, you should if () {...} instead of if (): ... endif;",
+            start,
+            end,
+            INFO,
+            "Line " + token.beginLine);
+  } catch (CoreException e) {
+    PHPeclipsePlugin.log(e);
+  }}
+  try {
+    <ENDIF>
+  } catch (ParseException e) {
+    errorMessage = "'endif' expected";
+    errorLevel   = ERROR;
+    throw e;
+  }
+  try {
+    <SEMICOLON>
+  } catch (ParseException e) {
+    errorMessage = "';' expected 'endif' keyword";
+    errorLevel   = ERROR;
+    throw e;
+  }
+|
+  Statement() ( LOOKAHEAD(1) ElseIfStatement() )* [ LOOKAHEAD(1) <ELSE> Statement() ]
+}
+
+void ElseIfStatementColon() :
+{}
+{
+  <ELSEIF> Condition("elseif") <COLON> (Statement())*
+}
+
+void ElseStatementColon() :
+{}
+{
+  <ELSE> <COLON> (Statement())*
+}
+
 void ElseIfStatement() :
 {}
 {
@@ -1759,19 +1864,39 @@ void ElseIfStatement() :
 }
 
 void WhileStatement() :
-{}
 {
-  <WHILE> Condition("while") WhileStatement0()
+  Token token;
+  final int pos = jj_input_stream.bufpos;
+}
+{
+  token = <WHILE> Condition("while") WhileStatement0(pos,pos + token.image.length())
 }
 
-void WhileStatement0() :
+void WhileStatement0(final int start, final int end) :
 {}
 {
-  <COLON> (Statement())* <ENDWHILE>
+  <COLON> (Statement())*
+  {try {
+  setMarker(fileToParse,
+            "Ugly syntax detected, you should while () {...} instead of while (): ... endwhile;",
+            start,
+            end,
+            INFO,
+            "Line " + token.beginLine);
+  } catch (CoreException e) {
+    PHPeclipsePlugin.log(e);
+  }}
+  try {
+    <ENDWHILE>
+  } catch (ParseException e) {
+    errorMessage = "'endwhile' expected";
+    errorLevel   = ERROR;
+    throw e;
+  }
   try {
     (<SEMICOLON> | "?>")
   } catch (ParseException e) {
-    errorMessage = "';' expected";
+    errorMessage = "';' expected after 'endwhile' keyword";
     errorLevel   = ERROR;
     throw e;
   }
@@ -1792,10 +1917,102 @@ void DoStatement() :
   }
 }
 
-void ForStatement() :
+void ForeachStatement() :
 {}
 {
-  <FOR> <LPAREN> [ ForInit() ] <SEMICOLON> [ Expression() ] <SEMICOLON> [ ForUpdate() ] <RPAREN> Statement()
+  <FOREACH>
+    try {
+    <LPAREN>
+  } catch (ParseException e) {
+    errorMessage = "'(' expected after 'foreach' keyword";
+    errorLevel   = ERROR;
+    throw e;
+  }
+  try {
+    Variable()
+  } catch (ParseException e) {
+    errorMessage = "variable expected";
+    errorLevel   = ERROR;
+    throw e;
+  }
+  try {
+    <AS>
+  } catch (ParseException e) {
+    errorMessage = "'as' expected";
+    errorLevel   = ERROR;
+    throw e;
+  }
+  try {
+    Variable()
+  } catch (ParseException e) {
+    errorMessage = "variable expected";
+    errorLevel   = ERROR;
+    throw e;
+  }
+  [ <ARRAYASSIGN> Expression() ]
+  try {
+    <RPAREN>
+  } catch (ParseException e) {
+    errorMessage = "')' expected after 'foreach' keyword";
+    errorLevel   = ERROR;
+    throw e;
+  }
+  try {
+  Statement()
+  } catch (ParseException e) {
+    if (errorMessage != null) throw e;
+    errorMessage = "statement expected";
+    errorLevel   = ERROR;
+    throw e;
+  }
+}
+
+void ForStatement() :
+{
+Token token;
+final int pos = jj_input_stream.bufpos;
+}
+{
+  token = <FOR>
+  try {
+    <LPAREN>
+  } catch (ParseException e) {
+    errorMessage = "'(' expected after 'for' keyword";
+    errorLevel   = ERROR;
+    throw e;
+  }
+     [ ForInit() ] <SEMICOLON> [ Expression() ] <SEMICOLON> [ ForUpdate() ] <RPAREN>
+    (
+      Statement()
+    |
+      <COLON> (Statement())*
+      {
+        try {
+        setMarker(fileToParse,
+                  "Ugly syntax detected, you should for () {...} instead of for (): ... endfor;",
+                  pos,
+                  pos+token.image.length(),
+                  INFO,
+                  "Line " + token.beginLine);
+        } catch (CoreException e) {
+          PHPeclipsePlugin.log(e);
+        }
+      }
+      try {
+        <ENDFOR>
+      } catch (ParseException e) {
+        errorMessage = "'endfor' expected";
+        errorLevel   = ERROR;
+        throw e;
+      }
+      try {
+        <SEMICOLON>
+      } catch (ParseException e) {
+        errorMessage = "';' expected 'endfor' keyword";
+        errorLevel   = ERROR;
+        throw e;
+      }
+    )
 }
 
 void ForInit() :