improved php parser
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpeclipse / phpeditor / php / PHPCodeScanner.java
1 /**********************************************************************
2 Copyright (c) 2000, 2002 IBM Corp. and others.
3 All rights reserved. This program and the accompanying materials
4 are made available under the terms of the Common Public License v1.0
5 which accompanies this distribution, and is available at
6 http://www.eclipse.org/legal/cpl-v10.html
7
8 Contributors:
9     IBM Corporation - Initial implementation
10     Klaus Hartlage - www.eclipseproject.de
11 **********************************************************************/
12 package net.sourceforge.phpeclipse.phpeditor.php;
13
14 import java.util.ArrayList;
15 import java.util.List;
16
17 import net.sourceforge.phpeclipse.IPreferenceConstants;
18 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
19 import net.sourceforge.phpeclipse.phpeditor.util.PHPColorProvider;
20 import net.sourceforge.phpeclipse.phpeditor.util.PHPWhitespaceDetector;
21 import net.sourceforge.phpeclipse.phpeditor.util.PHPWordDetector;
22 import org.eclipse.jface.preference.IPreferenceStore;
23 import org.eclipse.jface.preference.PreferenceConverter;
24 import org.eclipse.jface.text.TextAttribute;
25 import org.eclipse.jface.text.rules.EndOfLineRule;
26 import org.eclipse.jface.text.rules.ICharacterScanner;
27 import org.eclipse.jface.text.rules.IRule;
28 import org.eclipse.jface.text.rules.IToken;
29 import org.eclipse.jface.text.rules.IWordDetector;
30 import org.eclipse.jface.text.rules.MultiLineRule;
31 import org.eclipse.jface.text.rules.RuleBasedScanner;
32 import org.eclipse.jface.text.rules.SingleLineRule;
33 import org.eclipse.jface.text.rules.Token;
34 import org.eclipse.jface.text.rules.WhitespaceRule;
35 import org.eclipse.jface.text.rules.WordRule;
36
37 /**
38  * PHP Code Scanner
39  */
40 public class PHPCodeScanner extends RuleBasedScanner implements IPreferenceConstants {
41
42   private IToken variable;
43
44   private class PHPWordRule extends WordRule {
45     private StringBuffer fBuffer = new StringBuffer();
46
47     public PHPWordRule(IWordDetector detector) {
48       super(detector, Token.UNDEFINED);
49     }
50
51     public PHPWordRule(IWordDetector detector, IToken defaultToken) {
52       super(detector, defaultToken);
53     }
54
55     public IToken evaluate(ICharacterScanner scanner) {
56       int c = scanner.read();
57       boolean isVariable = false;
58       if (fDetector.isWordStart((char) c)) {
59         if (c == '$') {
60           isVariable = true;
61         }
62         if (fColumn == UNDEFINED || (fColumn == scanner.getColumn() - 1)) {
63
64           fBuffer.setLength(0);
65           do {
66             fBuffer.append((char) c);
67             c = scanner.read();
68           } while (c != scanner.EOF && fDetector.isWordPart((char) c));
69           scanner.unread();
70
71           if (isVariable) {
72             return variable;
73           }
74           IToken token = (IToken) fWords.get(fBuffer.toString());
75           if (token != null)
76             return token;
77
78           if (fDefaultToken.isUndefined())
79             unreadBuffer(scanner);
80
81           return fDefaultToken;
82         }
83       }
84
85       scanner.unread();
86       return Token.UNDEFINED;
87     }
88   }
89
90   private static String[] fgConstants = { "__LINE__", "__FILE__", "true", "false", "null", "object", "array" };
91   private TextAttribute fComment;
92   private TextAttribute fKeyword;
93   private TextAttribute fType;
94   private TextAttribute fString;
95   private PHPColorProvider fColorProvider;
96
97   /**
98    * Creates a Java code scanner
99    */
100   public PHPCodeScanner(PHPColorProvider provider) {
101     final IPreferenceStore store = PHPeclipsePlugin.getDefault().getPreferenceStore();
102
103     IToken keyword = new Token(new TextAttribute(provider.getColor(PreferenceConverter.getColor(store, PHP_KEYWORD))));
104     IToken functionName = new Token(new TextAttribute(provider.getColor(PreferenceConverter.getColor(store, PHP_FUNCTIONNAME))));
105     IToken string = new Token(new TextAttribute(provider.getColor(PreferenceConverter.getColor(store, PHP_STRING))));
106     IToken comment = new Token(new TextAttribute(provider.getColor(PreferenceConverter.getColor(store, PHP_SINGLELINE_COMMENT))));
107     IToken multi_comment =
108       new Token(new TextAttribute(provider.getColor(PreferenceConverter.getColor(store, PHP_MULTILINE_COMMENT))));
109     IToken other = new Token(new TextAttribute(provider.getColor(PreferenceConverter.getColor(store, PHP_DEFAULT))));
110
111     variable = new Token(new TextAttribute(provider.getColor(PHPColorProvider.VARIABLE)));
112
113     List rules = new ArrayList();
114
115     // Add rule for single line comments.
116     rules.add(new EndOfLineRule("//", comment)); //$NON-NLS-1$
117     //    EndOfLineRule endOfLine = new EndOfLineRule("#", comment);
118     //    endOfLine.setColumnConstraint(0);
119     rules.add(new EndOfLineRule("#", comment));
120
121     // Add rule for strings and character constants.
122     rules.add(new MultiLineRule("\"", "\"", string, '\\')); //$NON-NLS-2$ //$NON-NLS-1$
123     rules.add(new SingleLineRule("'", "'", string, '\\')); //$NON-NLS-2$ //$NON-NLS-1$
124
125     // rules.add(new SingleLineRule("//", "//", php_comment));
126     rules.add(new MultiLineRule("/*", "*/", multi_comment));
127
128     // Add generic whitespace rule.
129     rules.add(new WhitespaceRule(new PHPWhitespaceDetector()));
130
131     // Add word rule for keywords, types, and constants.
132     PHPWordRule wordRule = new PHPWordRule(new PHPWordDetector(), other);
133     for (int i = 0; i < PHPKeywords.PHP_KEYWORS.length; i++)
134       wordRule.addWord(PHPKeywords.PHP_KEYWORS[i], keyword);
135     for (int i = 0; i < PHPFunctionNames.FUNCTION_NAMES.length; i++)
136       wordRule.addWord(PHPFunctionNames.FUNCTION_NAMES[i], functionName);
137     for (int i = 0; i < fgConstants.length; i++)
138       wordRule.addWord(fgConstants[i], functionName);
139     rules.add(wordRule);
140
141     IRule[] result = new IRule[rules.size()];
142     rules.toArray(result);
143     setRules(result);
144   }
145 }