improved PHP Scanner
[phpeclipse.git] / net.sourceforge.phpeclipse / src / test / PHPParser.jj
index 57e9eb8..306f21d 100644 (file)
@@ -28,7 +28,6 @@ import org.eclipse.core.runtime.CoreException;
 import org.eclipse.ui.texteditor.MarkerUtilities;
 import org.eclipse.jface.preference.IPreferenceStore;
 
-import java.io.CharArrayReader;
 import java.util.Hashtable;
 import java.io.StringReader;
 import java.text.MessageFormat;
@@ -36,6 +35,9 @@ import java.text.MessageFormat;
 import net.sourceforge.phpeclipse.actions.PHPStartApacheAction;
 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
 import net.sourceforge.phpdt.internal.compiler.parser.PHPOutlineInfo;
+import net.sourceforge.phpdt.internal.compiler.parser.PHPSegmentWithChildren;
+import net.sourceforge.phpdt.internal.compiler.parser.PHPFunctionDeclaration;
+import net.sourceforge.phpdt.internal.compiler.parser.PHPClassDeclaration;
 
 /**
  * A new php parser.
@@ -46,10 +48,11 @@ import net.sourceforge.phpdt.internal.compiler.parser.PHPOutlineInfo;
  */
 public class PHPParser extends PHPParserSuperclass {
 
-  private static PHPParser me;
-
   private static IFile fileToParse;
 
+  /** The current segment */
+  private static PHPSegmentWithChildren currentSegment;
+
   private static final String PARSE_ERROR_STRING = "Parse error"; //$NON-NLS-1$
   private static final String PARSE_WARNING_STRING = "Warning"; //$NON-NLS-1$
   public static final int ERROR = 2;
@@ -62,28 +65,10 @@ public class PHPParser extends PHPParserSuperclass {
   public PHPParser() {
   }
 
-  public static PHPParser getInstance(IFile fileToParse) {
-    if (me == null) {
-      me = new PHPParser(fileToParse);
-    } else {
-      me.setFileToParse(fileToParse);
-    }
-    return me;
-  }
-
   public void setFileToParse(IFile fileToParse) {
     this.fileToParse = fileToParse;
   }
 
-  public static PHPParser getInstance(java.io.Reader stream) {
-    if (me == null) {
-      me = new PHPParser(stream);
-    } else {
-      me.ReInit(stream);
-    }
-    return me;
-  }
-
   public PHPParser(IFile fileToParse) {
     this(new StringReader(""));
     this.fileToParse = fileToParse;
@@ -105,11 +90,12 @@ public class PHPParser extends PHPParserSuperclass {
       jj_input_stream = new SimpleCharStream(stream, 1, 1);
     }
     ReInit(stream);
-    phpTest();
+    phpFile();
   }
 
   public PHPOutlineInfo parseInfo(Object parent, String s) {
     outlineInfo = new PHPOutlineInfo(parent);
+    currentSegment = outlineInfo.getDeclarations();
     StringReader stream = new StringReader(s);
     if (jj_input_stream == null) {
       jj_input_stream = new SimpleCharStream(stream, 1, 1);
@@ -228,7 +214,12 @@ public class PHPParser extends PHPParserSuperclass {
     try {
       parse();
     } catch (ParseException e) {
-      PHPeclipsePlugin.log(e);
+      if (errorMessage == null) {
+        PHPeclipsePlugin.log(e);
+      } else {
+        setMarker(errorMessage, e.currentToken.beginLine, errorLevel);
+        errorMessage = null;
+      }
     }
   }
 
@@ -263,20 +254,20 @@ PARSER_END(PHPParser)
 
 <DEFAULT> TOKEN :
 {
-  "<?php" : PHPPARSING
-| "<?"    : PHPPARSING
+  <PHPSTART : "<?php" | "<?"> : PHPPARSING
 }
 
-<DEFAULT> SKIP :
+<PHPPARSING> TOKEN :
 {
- < ~[] >
+  <PHPEND :"?>"> : DEFAULT
 }
 
-<PHPPARSING> TOKEN :
+<DEFAULT> SKIP :
 {
-  "?>" : DEFAULT
+ < ~[] >
 }
 
+
 /* WHITE SPACE */
 
 <PHPPARSING> SKIP :
@@ -545,7 +536,7 @@ void phpTest() :
 void phpFile() :
 {}
 {
- ("<?php" Php() "?>")*
+  (<PHPSTART> Php() <PHPEND>)*
   <EOF>
 }
 
@@ -556,10 +547,22 @@ void Php() :
 }
 
 void ClassDeclaration() :
-{}
 {
-  <CLASS> <IDENTIFIER> [ <EXTENDS> <IDENTIFIER> ]
+  PHPClassDeclaration classDeclaration;
+  Token className;
+  int pos = jj_input_stream.bufpos;
+}
+{
+  <CLASS> className = <IDENTIFIER> [ <EXTENDS> <IDENTIFIER> ]
+  {
+    classDeclaration = new PHPClassDeclaration(currentSegment,className.image,pos);
+    currentSegment.add(classDeclaration);
+    currentSegment = classDeclaration;
+  }
   ClassBody()
+  {
+    currentSegment = (PHPSegmentWithChildren) currentSegment.getParent();
+  }
 }
 
 void ClassBody() :
@@ -631,16 +634,39 @@ void ArrayInitializer() :
 }
 
 void MethodDeclaration() :
-{}
 {
-  <FUNCTION> MethodDeclarator()
+  PHPFunctionDeclaration functionDeclaration;
+}
+{
+  <FUNCTION> functionDeclaration = MethodDeclarator()
+  {
+    currentSegment.add(functionDeclaration);
+    currentSegment = functionDeclaration;
+  }
   ( Block() | <SEMICOLON> )
+  {
+    currentSegment = (PHPSegmentWithChildren) currentSegment.getParent();
+  }
 }
 
-void MethodDeclarator() :
-{}
+PHPFunctionDeclaration MethodDeclarator() :
 {
-  [<BIT_AND>] <IDENTIFIER> FormalParameters()
+  Token bit_and = null;
+  Token identifier;
+  StringBuffer methodDeclaration = new StringBuffer();
+  String formalParameters;
+  int pos = jj_input_stream.bufpos;
+}
+{
+  [ bit_and = <BIT_AND>]
+  identifier = <IDENTIFIER> FormalParameters()
+  {
+    if (bit_and != null) {
+      methodDeclaration.append("&");
+    }
+    methodDeclaration.append(identifier);
+    return new PHPFunctionDeclaration(currentSegment,methodDeclaration.toString(),pos);
+  }
 }
 
 void FormalParameters() :
@@ -906,13 +932,29 @@ void NullLiteral() :
 void Arguments() :
 {}
 {
-  <LPAREN> [ ArgumentList() ] <RPAREN>
+  <LPAREN> [ ArgumentList() ]
+  try {
+    <RPAREN>
+  } catch (ParseException e) {
+    errorMessage = "')' expected to close the argument list";
+    errorLevel   = ERROR;
+    throw e;
+  }
 }
 
 void ArgumentList() :
 {}
 {
-  Expression() ( <COMMA> Expression() )*
+  Expression()
+  ( <COMMA>
+      try {
+        Expression()
+      } catch (ParseException e) {
+        errorMessage = "expression expected after a comma in argument list";
+        errorLevel   = ERROR;
+        throw e;
+      }
+   )*
 }
 
 /*