[SCM] Lisaac eclipse plugin branch, master, updated. d4c84b7fca3d50fce0cac8f2602a7becd6faa910
Damien Bouvarel
dams.bouvarel at wanadoo.fr
Thu Apr 16 12:17:46 UTC 2009
The following commit has been merged in the master branch:
commit d4c84b7fca3d50fce0cac8f2602a7becd6faa910
Author: Damien Bouvarel <dams.bouvarel at wanadoo.fr>
Date: Thu Apr 16 13:57:43 2009 +0200
"put to to" bug OK + slot hyperlink + slot hover
diff --git a/src/org/eclipse/lisaac/editors/LisaacCompletionProcessor.java b/src/org/eclipse/lisaac/editors/LisaacCompletionProcessor.java
index 036e35b..2f99d6d 100644
--- a/src/org/eclipse/lisaac/editors/LisaacCompletionProcessor.java
+++ b/src/org/eclipse/lisaac/editors/LisaacCompletionProcessor.java
@@ -6,7 +6,6 @@ import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextViewer;
-import org.eclipse.jface.text.contentassist.CompletionProposal;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
import org.eclipse.jface.text.contentassist.IContextInformation;
@@ -39,8 +38,6 @@ public class LisaacCompletionProcessor implements IContentAssistProcessor {
result.add(props[t]);
}
- String prefix = lastWord(document, offset);
-
return (ICompletionProposal[]) result.toArray(new ICompletionProposal[result.size()]);
} catch (Exception e) {
@@ -80,7 +77,7 @@ public class LisaacCompletionProcessor implements IContentAssistProcessor {
//
String contents = document.get(pos+1, baseOffset-1 - pos);
- LisaacCompletionParser parser = new LisaacCompletionParser(contents);
+ LisaacCompletionParser parser = new LisaacCompletionParser(contents, null);
parser.parseCompletions(pos+1, baseOffset, proposals);
}
} catch (BadLocationException e) {
@@ -90,21 +87,6 @@ public class LisaacCompletionProcessor implements IContentAssistProcessor {
}
}
-
-
- private String lastWord(IDocument doc, int offset) {
- try {
- for (int n = offset-1; n >= 0; n--) {
- char c = doc.getChar(n);
- if (!Character.isJavaIdentifierPart(c))
- return doc.get(n + 1, offset-n-1);
- }
- } catch (BadLocationException e) {
- // ... log the exception ...
- }
- return "";
- }
-
public IContextInformation[] computeContextInformation(ITextViewer viewer,
int offset) {
diff --git a/src/org/eclipse/lisaac/editors/LisaacConfiguration.java b/src/org/eclipse/lisaac/editors/LisaacConfiguration.java
index 61372eb..205b4ba 100644
--- a/src/org/eclipse/lisaac/editors/LisaacConfiguration.java
+++ b/src/org/eclipse/lisaac/editors/LisaacConfiguration.java
@@ -84,7 +84,7 @@ public class LisaacConfiguration extends SourceViewerConfiguration {
IProject project = editor.getProject();
LisaacModel model = LisaacModel.getModel(project);
- textHover = new LisaacTextHover(model);
+ textHover = new LisaacTextHover(model, editor.getFileName());
}
return textHover;
}
diff --git a/src/org/eclipse/lisaac/editors/LisaacScanner.java b/src/org/eclipse/lisaac/editors/LisaacScanner.java
index 39c66ea..705dcee 100644
--- a/src/org/eclipse/lisaac/editors/LisaacScanner.java
+++ b/src/org/eclipse/lisaac/editors/LisaacScanner.java
@@ -320,6 +320,10 @@ public class LisaacScanner extends RuleBasedScanner {
public static boolean isPrototypeIdentifier(String word) {
return detectKeyword(word, new LisaacPrototypeDetector());
}
+
+ public static boolean isIdentifier(String word) {
+ return detectKeyword(word, new LisaacWordDetector());
+ }
private static boolean detectKeyword(String word, IWordDetector detector) {
int i = 0;
diff --git a/src/org/eclipse/lisaac/editors/LisaacTextHover.java b/src/org/eclipse/lisaac/editors/LisaacTextHover.java
index 9e8d0c4..0cd7d85 100644
--- a/src/org/eclipse/lisaac/editors/LisaacTextHover.java
+++ b/src/org/eclipse/lisaac/editors/LisaacTextHover.java
@@ -15,16 +15,18 @@ import org.eclipse.jface.text.Region;
import org.eclipse.lisaac.model.LisaacCompletionParser;
import org.eclipse.lisaac.model.LisaacModel;
import org.eclipse.lisaac.model.items.Prototype;
+import org.eclipse.lisaac.model.items.Slot;
import org.eclipse.swt.widgets.Shell;
public class LisaacTextHover implements ITextHover, ITextHoverExtension {
protected LisaacModel model;
-
-
- public LisaacTextHover(LisaacModel model) {
+ protected String filename;
+
+ public LisaacTextHover(LisaacModel model, String filename) {
super();
this.model = model;
+ this.filename = filename;
}
public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) {
@@ -32,11 +34,21 @@ public class LisaacTextHover implements ITextHover, ITextHoverExtension {
String text = textViewer.getDocument().get(hoverRegion.getOffset(), hoverRegion.getLength());
if (LisaacScanner.isPrototypeIdentifier(text)) {
// get prototype info
-
+
Prototype prototype = LisaacCompletionParser.findPrototype(text, model);
if (prototype != null) {
return "<I>Prototype : </I> "+prototype.getHoverInformation();
}
+ } else if (LisaacScanner.isIdentifier(text)) {
+ // get slot info
+
+ Prototype prototype = model.getPrototype(LisaacModel.extractPrototypeName(filename));
+ if (prototype != null) {
+ Slot slot = prototype.getSlotFromKeyword(text, prototype.openParser(), hoverRegion.getOffset());
+ if (slot != null) {
+ return "<I>Slot : </I> "+slot.getHoverInformation();
+ }
+ }
}
} catch (BadLocationException e) {
} catch (CoreException e) {
@@ -55,16 +67,16 @@ public class LisaacTextHover implements ITextHover, ITextHoverExtension {
/*
- * @see org.eclipse.jface.text.ITextHoverExtension#getHoverControlCreator()
- */
- public IInformationControlCreator getHoverControlCreator() {
- return new IInformationControlCreator() {
- public IInformationControl createInformationControl(Shell parent) {
- return new DefaultInformationControl(parent, "", new HTMLTextPresenter());
- }
- };
- }
-
+ * @see org.eclipse.jface.text.ITextHoverExtension#getHoverControlCreator()
+ */
+ public IInformationControlCreator getHoverControlCreator() {
+ return new IInformationControlCreator() {
+ public IInformationControl createInformationControl(Shell parent) {
+ return new DefaultInformationControl(parent, "", new HTMLTextPresenter());
+ }
+ };
+ }
+
protected IRegion selectWord(IDocument doc, int caretPos) throws BadLocationException {
int startPos, endPos;
diff --git a/src/org/eclipse/lisaac/editors/LisaacWordRule.java b/src/org/eclipse/lisaac/editors/LisaacWordRule.java
index baadd77..08da2b4 100644
--- a/src/org/eclipse/lisaac/editors/LisaacWordRule.java
+++ b/src/org/eclipse/lisaac/editors/LisaacWordRule.java
@@ -1,5 +1,6 @@
package org.eclipse.lisaac.editors;
+import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.text.rules.ICharacterScanner;
import org.eclipse.jface.text.rules.IToken;
import org.eclipse.jface.text.rules.IWordDetector;
@@ -35,10 +36,21 @@ public class LisaacWordRule extends WordRule {
}
//
int offset = ((LisaacScanner) scanner).getOffset();
+ String word = fBuffer.toString();
+
+ try {
+ Slot slot = prototype.getSlotFromKeyword(word, prototype.openParser(), offset-word.length());
+ if (slot != null) {
+ return result;
+ }
+ } catch (CoreException e) {
+ e.printStackTrace();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
Slot slot = prototype.getSlot(offset);
if (slot != null) {
- String word = fBuffer.toString();
// is current word a slot argument?
if (slot.hasArgument(word)) {
diff --git a/src/org/eclipse/lisaac/editors/PrototypeHyperLink.java b/src/org/eclipse/lisaac/editors/PrototypeHyperLink.java
index 19766e1..af1080f 100644
--- a/src/org/eclipse/lisaac/editors/PrototypeHyperLink.java
+++ b/src/org/eclipse/lisaac/editors/PrototypeHyperLink.java
@@ -12,6 +12,8 @@ import org.eclipse.jface.text.hyperlink.IHyperlink;
import org.eclipse.lisaac.LisaacPlugin;
import org.eclipse.lisaac.model.LisaacModel;
import org.eclipse.lisaac.model.items.Prototype;
+import org.eclipse.lisaac.model.items.Slot;
+import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchWindow;
@@ -55,23 +57,41 @@ public class PrototypeHyperLink implements IHyperlink {
if (part instanceof LipEditor) {
return;
}
+
if (project != null) {
String prototypePath;
boolean createLink=false;
-
+ Prototype prototype;
+ Slot slot = null;
+
LisaacModel model = LisaacModel.getModel(project);
- Prototype prototype = model.getPrototype(fPrototypeString);
+
+ // Slot Hyperlink
+ prototype = LisaacModel.getCurrentPrototype();
+ try {
+ slot = prototype.getSlotFromKeyword(fPrototypeString, prototype.openParser(), fRegion.getOffset());
+ } catch (CoreException e1) {
+ e1.printStackTrace();
+ }
+ if (slot != null) {
+ // slot hyperlink
+ prototype = slot.getPrototype();
+ } else {
+ // prototype hyperlink
+ prototype = model.getPrototype(fPrototypeString);
+ }
+
if (prototype != null) {
prototypePath = prototype.getFileName();
} else {
prototypePath = model.getPathManager().getFullPath(fPrototypeString);
createLink = true;
}
-
if (prototypePath != null) {
final IProject p = project;
final String filename = prototypePath;
final boolean link = createLink;
+ final Slot selectSlot = slot;
part.getSite().getShell().getDisplay().asyncExec(new Runnable() {
public void run() {
@@ -98,6 +118,12 @@ public class PrototypeHyperLink implements IHyperlink {
file.createLink(location, IResource.NONE, null);
}
IDE.openEditor(page, file);
+ if (selectSlot != null) {
+ IWorkbenchPart part = w.getPartService().getActivePart();
+ if (part instanceof LisaacEditor) {
+ ((LisaacEditor)part).selectAndReveal(selectSlot.getPosition().offset, selectSlot.getPosition().length);
+ }
+ }
if (link) {
//file.delete(true, null);
}
diff --git a/src/org/eclipse/lisaac/model/AbstractLisaacParser.java b/src/org/eclipse/lisaac/model/AbstractLisaacParser.java
index 5674b82..acb27fe 100644
--- a/src/org/eclipse/lisaac/model/AbstractLisaacParser.java
+++ b/src/org/eclipse/lisaac/model/AbstractLisaacParser.java
@@ -1,791 +1,795 @@
-package org.eclipse.lisaac.model;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.StringWriter;
-
-import org.eclipse.lisaac.builder.ILisaacErrorHandler;
-
-
-public class AbstractLisaacParser {
-
- protected ILisaacErrorHandler reporter;
-
- protected ILisaacModel model;
-
- protected String source;
-
- protected int position;
-
- protected int pos_cur, pos_line, pos_col;
- protected int begin_position;
-
- protected String string_tmp="";
-
-
- public Position getPosition() {
- return getPosition(0);
- }
-
- public Position getPosition(int len) {
- Position result=null;
-
- while (pos_cur != position) {
- if (source.charAt(pos_cur) == '\n') {
- pos_col = 0;
- pos_line++;
- } else {
- pos_col++;
- }
- pos_cur++;
- }
- if (pos_line > 32767) {
- result = new Position(32767, pos_col, pos_cur);
- reporter.syntaxError ("Line counter overflow.",result);
- }
- if (pos_col > 255) {
- result = new Position(pos_line, 255, pos_cur);
- reporter.syntaxError ("Column counter overflow (line too long).",result);
- };
- result = new Position(pos_line, pos_col, pos_cur, len);
- return result;
- }
- public String getSource() {
- return source;
- }
-
- public boolean isEOF() {
- return position > source.length()-1;
- }
-
-
- protected long lastInteger;
- protected String lastReal;
- protected String lastString;
-
- protected static String lastComment;
- protected boolean isCatchComment;
-
- protected boolean isParameterType;
-
- protected void setCatchComment() {
- isCatchComment = true;
- lastComment = "";
- }
- protected void setCatchCommentOff() {
- isCatchComment = false;
- }
-
- public String getLastString() {
- return lastString;
- }
-
- public char lastCharacter() {
- if (position > source.length()-1) {
- return 0;
- }
- return source.charAt(position);
- }
-
- //
- // AMBIGU Manager.
- //
-
- protected int old_position;
- protected int old_pos_cur;
- protected int old_pos_line;
- protected int old_pos_col;
-
- protected void saveContext() {
- old_position = position;
- old_pos_cur = pos_cur;
- old_pos_line = pos_line;
- old_pos_col = pos_col;
- }
- protected void restoreContext() {
- position = old_position;
- pos_cur = old_pos_cur;
- pos_line = old_pos_line;
- pos_col = old_pos_col;
- }
-
- public AbstractLisaacParser(InputStream contents, ILisaacModel model) {
- this.model = model;
- this.reporter = model.getReporter();
-
- // convert the input stream into string
- try {
- InputStreamReader reader = new InputStreamReader (contents);
- BufferedReader buffer = new BufferedReader(reader);
-
- StringWriter writer = new StringWriter();
-
- String line="";
- do {
- line = buffer.readLine();
- if (line != null) {
- writer.write(line+"\n");
- }
- } while (line != null);
- //
- source = writer.toString();
- //
- } catch (IOException e) {
- return; // ERROR
- }
- initialize();
- }
-
- public AbstractLisaacParser(String contents) {
- // null reporter
- this.reporter = new ILisaacErrorHandler() {
- public void fatalError(String msg, Position position) {
- }
- public void semanticError(String msg, Position position) {
- }
- public void syntaxError(String msg, Position position) {
- }
- public void warning(String msg, Position position) {
- }
- };
- source = contents;
- initialize();
- }
-
- public void initialize() {
- position = 0;
- pos_cur = 0;
- pos_line = 1;
- pos_col = 0;
- }
-
- //
- // Lisaac Parser
- //
-
- public boolean readSpace() {
- int pos,posold;
- int level_comment = 0;
-
- pos = position;
- posold = -1;
- while (posold != position) {
- posold = position;
-
- // skip spaces
- while ((lastCharacter() != 0) && (lastCharacter() <= ' ')) {
- position++;
- }
- if (position < source.length()-1) {
- // Skip C++ comment style :
- if (lastCharacter() == '/' && source.charAt(position+1) == '/') {
- position += 2;
-
- if (isCatchComment)
- lastComment += "\t";
-
- while ((lastCharacter() != 0) && (lastCharacter() != '\n')) {
- if (isCatchComment)
- lastComment += lastCharacter();
-
- lastCharacter();
- position++;
- }
- if (isCatchComment)
- lastComment += "\n";
- }
- }
- if (position < source.length()-1) {
- // Skip C comment style :
- if (lastCharacter() == '/' && source.charAt(position+1) == '*') {
- position += 2;
- level_comment++;
-
- while (lastCharacter() != 0 && level_comment != 0) {
- if (lastCharacter() == '/' && source.charAt(position+1) == '*') {
- position += 2;
- level_comment++;
- } else if (lastCharacter() == '*' && source.charAt(position+1) == '/') {
- position += 2;
- level_comment--;
- } else {
- position++;
- }
- }
- if (level_comment != 0) {
- reporter.syntaxError("End of comment not found !", getPosition());
- }
- }
- }
- }
- // FALSE : Last character.
- begin_position = position;
- return (position != pos) || (lastCharacter() != 0);
- }
-
- public boolean readSymbol(String st) {
- int posold,j;
- boolean result=false;
-
- if (! readSpace()) {
- result = false;
- } else {
- posold = position;
- j = 0;
- while (lastCharacter() != 0 && (j <= st.length()-1 && lastCharacter() == st.charAt(j))) {
- position++;
- j++;
- }
- if (j > st.length()-1) {
- result = true;
- lastString = st;
- } else {
- position = posold;
- result = false;
- }
- }
- return result;
- }
-
- public boolean readCharacter (char ch) {
- boolean result=false;
-
- if (! readSpace()) {
- result = false;
- } else {
- if (lastCharacter() == ch) {
- position++;
- result = true;
- }
- }
- return result;
- }
-
- //-- affect -> ":=" | "<-" | "?="
- public boolean readAffect() {
- return readSymbol(ILisaacModel.symbol_affect_immediate) ||
- readSymbol(ILisaacModel.symbol_affect_cast) ||
- readSymbol(ILisaacModel.symbol_affect_code);
- }
-
- //-- style -> '-' | '+'
- public char readStyle() {
- char result;
-
- if (readCharacter('-')) {
- result = '-';
- } else if (readCharacter('+')) {
- result = '+';
- } else {
- result = ' ';
- }
- return result;
- }
-
- //-- identifier -> 'a'-'z' {'a'-'z' | '0'-'9' | '_'}
- public boolean readIdentifier() {
- boolean result=false;
- int posold,idx;
-
- if (! readSpace() || !Character.isLowerCase(lastCharacter())) {
- result = false;
- } else {
- posold = position;
- string_tmp = "";
-
- while (lastCharacter() != 0 &&
- (Character.isLowerCase(lastCharacter()) ||
- Character.isDigit(lastCharacter()) ||
- lastCharacter() == '_')) {
- string_tmp += lastCharacter();
- position++;
- }
- if (string_tmp.length() > 0) {
- idx = string_tmp.lastIndexOf("__");
- if (idx != -1) {
- position = posold+idx;
- reporter.syntaxError("Identifier is incorrect.", getPosition());
- }
- lastString = getString(string_tmp);
- result = true;
- }
- }
- return result;
- }
-
- public boolean readWord(String st) {
- int posold,idx;
- boolean result=false;
-
- if (! readSpace()) {
- result = false;
- } else {
- posold = position;
- idx = 0;
-
- while (idx <= st.length()-1 && lastCharacter() == st.charAt(idx)) {
- position++;
- idx++;
- }
- if (idx > st.length()-1) {
- lastString = st;
- result = true;
- } else {
- position = posold;
- }
- }
- return result;
- }
-
- public boolean readThisKeyword(String st) {
- return readWord(st);
- }
-
- //-- keyword -> 'A'-'Z' 'a'-'z' {'a'-'z' | '0'-'9' | '_'}
- public boolean readKeyword() {
- boolean result=false;
-
- if (! readSpace() || ! Character.isUpperCase(lastCharacter())) {
- result = false;
- } else {
- string_tmp = "";
- string_tmp += lastCharacter();
- position++;
-
- if (Character.isLowerCase(lastCharacter())) {
- string_tmp += lastCharacter();
- position++;
- while (lastCharacter() != 0 &&
- (Character.isLowerCase(lastCharacter()) ||
- Character.isDigit(lastCharacter()) ||
- lastCharacter() == '_')) {
- string_tmp += lastCharacter();
- position++;
- }
- lastString = getString(string_tmp);
- result = true;
- } else {
- position--;
- result = false;
- }
- }
- return result;
- }
-
- //-- cap_identifier -> 'A'-'Z' {'A'-'Z' | '0'-'9' | '_'}
- public boolean readCapIdentifier() {
- int posold,idx;
- boolean result=false;
- char car;
-
- if (! readSpace() || ! Character.isUpperCase(lastCharacter())) {
- result = false;
- } else {
- posold = position;
- string_tmp = ""+lastCharacter();
- position++;
- isParameterType = true;
- while (lastCharacter() != 0 &&
- (Character.isUpperCase(lastCharacter()) ||
- Character.isDigit(lastCharacter()) ||
- lastCharacter() == '_')) {
- car = lastCharacter();
- isParameterType = isParameterType && (Character.isDigit(car));
-
- string_tmp += car;
- position++;
- }
- if (Character.isLetter(lastCharacter()) ||
- Character.isDigit(lastCharacter()) ||
- lastCharacter() == '_') {
- reporter.syntaxError("Identifier is incorrect.", getPosition());
- return false;
- }
- idx = string_tmp.lastIndexOf("__");
- if (idx != -1) {
- position = posold + idx;
- reporter.syntaxError("Identifier is incorrect.", getPosition());
- return false;
- }
- lastString = getString(string_tmp);
- result = true;
- }
- return result;
- }
-
- //-- integer -> number
- //-- number -> {'0'-'9'} ['d']
- //-- | '0'-'9' {'0'-'9' | 'A'-'F' | 'a'-'f'} 'h'
- //-- | {'0'-'7'} 'o'
- //-- | {'0' | '1'} 'b'
- public boolean readInteger() {
- boolean result=false;
- //int pos_old;
-
- if (readSpace() && Character.isDigit(lastCharacter())) {
- result = true;
- string_tmp = ""+lastCharacter();
- //pos_old = position;
- position++;
-
- while (isHexadecimalDigit(lastCharacter()) || lastCharacter() == '_') {
- if (lastCharacter() != '_') {
- string_tmp += lastCharacter();
- }
- position++;
- }
- if (lastCharacter() == 'h') {
- try {
- Integer integer = Integer.valueOf(string_tmp, 16);
- lastInteger = integer.intValue();
- } catch (Exception e) {
- System.out.println("Warning readInteger : "+e);// FIXME hex string
- lastInteger = 0;
- }
- position++;
- } else {
- if (string_tmp.charAt(string_tmp.length()-1) > '9') {
- string_tmp = string_tmp.substring(0, string_tmp.length()-1);// remove last
- position--;
- }
- if (lastCharacter() == 'o') {
- if (!isOctal(string_tmp)) {
- reporter.syntaxError("Incorrect octal number.", getPosition());
- }
- lastInteger = Integer.valueOf(string_tmp, 8).intValue();
- position++;
- } else if (lastCharacter() == 'b') {
- if (!isBinary(string_tmp)) {
- reporter.syntaxError("Incorrect binary number.", getPosition());
- }
- lastInteger = Integer.valueOf(string_tmp, 2).intValue();
- position++;
- } else {
- if (lastCharacter() == 'd') {
- position++;
- }
- if (! isInteger(string_tmp)) {
- reporter.syntaxError("Incorrect decimal number.", getPosition());
- }
- lastInteger = Integer.valueOf(string_tmp);
- }
- }
- }
- return result;
- }
-
- private boolean isInteger(String s) {
- try {
- Integer.parseInt(s);
- } catch (NumberFormatException e) {
- return false;
- }
- return true;
- }
-
- // True when the contents is a sequence of bits (i.e., mixed
- // characters `0' and characters `1').
- private boolean isBinary(String s) {
- boolean result;
- int i;
-
- i = s.length()-1;
- result = true;
- while (result && i != 0) {
- result = s.charAt(i) == '0' || s.charAt(i) == '1';
- i--;
- }
- return result;
- }
-
- private boolean isOctal(String s) {
- try {
- Integer.parseInt(s, 8);
- } catch (NumberFormatException e) {
- return false;
- }
- return true;
- }
-
- private boolean isHexadecimalDigit(char c) {
- boolean result=false;
-
- if (Character.isDigit(c)) {
- result = true;
- } else if (c >= 'a') {
- result = c <= 'f';
- } else if (c >= 'A') {
- result = c <= 'F';
- }
- return result;
- }
-
- //-- real -> '0'-'9' {'0'-'9'_} [ '.' {'0'-'9'} ] [ 'E' ['+'|'-'] '0'-'9' {'0'-'9'}
- public boolean readReal() {
- boolean result=false;
- int pos_old;
-
- if (readSpace() && Character.isDigit(lastCharacter())) {
- string_tmp = ""+lastCharacter();
- pos_old = position;
- position++;
-
- while (Character.isDigit(lastCharacter()) || lastCharacter() == '_') {
- if (lastCharacter() != '_') {
- string_tmp += lastCharacter();
- }
- position++;
- }
- if (lastCharacter() == '.') {
- string_tmp += '.';
- position++;
-
- if (Character.isDigit(lastCharacter())) {
- result = true;
- string_tmp += lastCharacter();
- position++;
-
- while (Character.isDigit(lastCharacter())) {
- string_tmp += lastCharacter();
- position++;
- }
- }
- if (lastCharacter() == 'E') {
- result = true;
- string_tmp += 'E';
- position++;
-
- if (lastCharacter() == '+' || lastCharacter() == '-') {
- string_tmp += lastCharacter();
- position++;
- }
- if (Character.isDigit(lastCharacter())) {
- string_tmp += lastCharacter();
- position++;
- while (Character.isDigit(lastCharacter())) {
- string_tmp += lastCharacter();
- position++;
- }
- } else {
- reporter.syntaxError("Incorrect real number.", getPosition());
- }
- }
- }
- if (result) {
- lastReal = getString(string_tmp);
- } else {
- position = pos_old;
- }
- }
- return result;
- }
-
- public void readEscapeCharacter() {
- int val;
-
- if (isSeparator(lastCharacter())) {
- position++;
- while (lastCharacter() != 0 && isSeparator(lastCharacter())) {
- position++;
- }
- if (lastCharacter() == '\\') {
- string_tmp.substring(0, string_tmp.length()-2); // remove last
- position++;
- } else if (lastCharacter() != 0) {
- reporter.syntaxError("Unknown escape sequence.", getPosition());
- }
- } else if (lastCharacter() != 0) {
- char c = lastCharacter();
-
- if (c == 'a' ||
- c == 'b' ||
- c == 'f' ||
- c == 'n' ||
- c == 'r' ||
- c == 't' ||
- c == 'v' ||
- c == '\\' ||
- c == '?' ||
- c == '\'' ||
- c == '\"') {
- string_tmp += c;
- position++;
- } else if (lastCharacter() >= '0' && lastCharacter() <= '9') {
- if (lastCharacter() == '0' &&
- position < source.length() &&
- ! isHexadecimalDigit(source.charAt(position+1))) {
-
- string_tmp += lastCharacter();
- position++;
- } else {
- String string_tmp2 = new String(string_tmp);
- readInteger(); // result is Always TRUE.
- string_tmp = string_tmp2;
-
- if (lastInteger > 255) {
- reporter.syntaxError("Invalid range character number [0,255].", getPosition());
- }
- val = (int) lastInteger;
- string_tmp += (val / 64);
- string_tmp += ((val % 64) / 8);
- string_tmp += (val % 8);
- if (lastCharacter() == '\\') {
- position++;
- } else {
- reporter.syntaxError("Character '\' is needed.", getPosition());
- }
- }
- } else {
- reporter.syntaxError("Unknown escape sequence.", getPosition());
- }
- }
- }
-
- //-- character -> '\'' ascii '\''
- public boolean readCharacters() {
- boolean result=false;
- int count=0;
-
- if (readSpace() && lastCharacter() == '\'') {
- //old_pos = position;
- position++;
- string_tmp = "";
- while (lastCharacter() != 0 && lastCharacter() != '\n' && lastCharacter() != '\'') {
- string_tmp += lastCharacter();
- if (lastCharacter() == '\\') {
- position++;
- readEscapeCharacter();
- count++;
- } else {
- position++;
- count++;
- }
- }
- if (lastCharacter() == '\'') {
- position++;
- lastString = getString(string_tmp);
- if (count != 1) {
- position = begin_position;
- reporter.syntaxError("Character constant too long.", getPosition());
- }
- result = true;
- } else {
- position = begin_position;
- reporter.syntaxError("Unterminated character constant.", getPosition());
- }
- }
- return result;
- }
-
- //-- string -> '\"' ascii_string '\"'
- public boolean readString() {
- boolean result=false;
- // int old_pos;
-
- if (readSpace() && lastCharacter() == '\"') {
- // old_pos = position;
- position = position+1;
- string_tmp = "";
- while (lastCharacter() != 0 && lastCharacter() != '\n' && lastCharacter() != '\"') {
- string_tmp += lastCharacter();
- if (lastCharacter() == '\\') {
- position = position+1;
- readEscapeCharacter();
- } else {
- position = position+1;
- }
- }
- if (lastCharacter() == '\"') {
- position = position+1;
- lastString = getString(string_tmp);
- result = true;
- } else {
- position = begin_position;
- reporter.syntaxError("Unterminated string constant.", getPosition());
- }
- }
- return result;
- }
-
- //-- external -> '`' ascii_c_code '`'
- public boolean readExternal() {
- boolean result=false;
- // int pos_old;
-
- if ((! readSpace()) || lastCharacter() != '`') {
- result = false;
- } else {
- // pos_old=position;
- position = position+1;
- string_tmp = "";
- while (lastCharacter() != 0 && lastCharacter() != '`') {
- string_tmp += lastCharacter();
- if (lastCharacter() == '\\') {
- position = position+1;
- string_tmp += lastCharacter();
- if (lastCharacter() != 0) {
- position = position+1;
- }
- } else {
- position = position+1;
- }
- }
- if (lastCharacter() != 0) {
- position = position+1;
- lastString = getString(string_tmp);
- result = true;
- } else {
- result = false;
- }
- }
- return result;
- }
-
- private final String operators = "!@#$%^&<|*-+=~/?\\>";
-
- //-- operator -> '!' | '@' | '#' | '$' | '%' | '^' | '&' | '<' | '|'
- //-- | '*' | '-' | '+' | '=' | '~' | '/' | '?' | '\' | '>'
- public boolean readOperator() {
- boolean result=false;
- // int old_pos;
-
- readSpace();
- // old_pos = position;
- string_tmp = "";
- while (lastCharacter() != 0 &&
- operators.indexOf(lastCharacter()) != -1) {
- string_tmp += lastCharacter();
- position = position+1;
- }
- if (string_tmp.length() > 0) {
- lastString = getString(string_tmp);
- if (lastString.equals(ILisaacModel.symbol_affect_immediate) ||
- lastString.equals(ILisaacModel.symbol_affect_code) ||
- lastString.equals(ILisaacModel.symbol_affect_cast)) {
- reporter.syntaxError("Incorrect operator.", getPosition());
- }
- result = true;
- }
- return result;
- }
-
- // True when character is a separator.
- private boolean isSeparator(char c) {
- return c == ' ' || c == '\t' || c == '\n' ||
- c == '\r' || c == '\0' || c == '\f'; // || c == '\v';
- }
-
- public String getString(String str) {
- if (model == null) {
- return str;
- }
- return model.getAliasString().get(str);
- }
-
-
- public ILisaacErrorHandler getReporter() {
- return reporter;
- }
-}
+package org.eclipse.lisaac.model;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.StringWriter;
+
+import org.eclipse.lisaac.builder.ILisaacErrorHandler;
+
+
+public class AbstractLisaacParser {
+
+ protected ILisaacErrorHandler reporter;
+
+ protected ILisaacModel model;
+
+ protected String source;
+
+ protected int position;
+
+ protected int pos_cur, pos_line, pos_col;
+ protected int begin_position;
+
+ protected String string_tmp="";
+
+
+ public Position getPosition() {
+ return getPosition(0);
+ }
+
+ public Position getPosition(int len) {
+ Position result=null;
+
+ while (pos_cur != position) {
+ if (source.charAt(pos_cur) == '\n') {
+ pos_col = 0;
+ pos_line++;
+ } else {
+ pos_col++;
+ }
+ pos_cur++;
+ }
+ if (pos_line > 32767) {
+ result = new Position(32767, pos_col, pos_cur);
+ reporter.syntaxError ("Line counter overflow.",result);
+ }
+ if (pos_col > 255) {
+ result = new Position(pos_line, 255, pos_cur);
+ reporter.syntaxError ("Column counter overflow (line too long).",result);
+ };
+ result = new Position(pos_line, pos_col, pos_cur, len);
+ return result;
+ }
+ public String getSource() {
+ return source;
+ }
+
+ public boolean isEOF() {
+ return position > source.length()-1;
+ }
+
+ public void setPosition(int pos) {
+ initialize();
+ position = pos;
+ }
+
+ protected long lastInteger;
+ protected String lastReal;
+ protected String lastString;
+
+ protected static String lastComment;
+ protected boolean isCatchComment;
+
+ protected boolean isParameterType;
+
+ protected void setCatchComment() {
+ isCatchComment = true;
+ lastComment = "";
+ }
+ protected void setCatchCommentOff() {
+ isCatchComment = false;
+ }
+
+ public String getLastString() {
+ return lastString;
+ }
+
+ public char lastCharacter() {
+ if (position > source.length()-1) {
+ return 0;
+ }
+ return source.charAt(position);
+ }
+
+ //
+ // AMBIGU Manager.
+ //
+
+ protected int old_position;
+ protected int old_pos_cur;
+ protected int old_pos_line;
+ protected int old_pos_col;
+
+ protected void saveContext() {
+ old_position = position;
+ old_pos_cur = pos_cur;
+ old_pos_line = pos_line;
+ old_pos_col = pos_col;
+ }
+ protected void restoreContext() {
+ position = old_position;
+ pos_cur = old_pos_cur;
+ pos_line = old_pos_line;
+ pos_col = old_pos_col;
+ }
+
+ public AbstractLisaacParser(InputStream contents, ILisaacModel model) {
+ this.model = model;
+ this.reporter = model.getReporter();
+
+ // convert the input stream into string
+ try {
+ InputStreamReader reader = new InputStreamReader (contents);
+ BufferedReader buffer = new BufferedReader(reader);
+
+ StringWriter writer = new StringWriter();
+
+ String line="";
+ do {
+ line = buffer.readLine();
+ if (line != null) {
+ writer.write(line+"\n");
+ }
+ } while (line != null);
+ //
+ source = writer.toString();
+ //
+ } catch (IOException e) {
+ return; // ERROR
+ }
+ initialize();
+ }
+
+ public AbstractLisaacParser(String contents) {
+ // null reporter
+ this.reporter = new ILisaacErrorHandler() {
+ public void fatalError(String msg, Position position) {
+ }
+ public void semanticError(String msg, Position position) {
+ }
+ public void syntaxError(String msg, Position position) {
+ }
+ public void warning(String msg, Position position) {
+ }
+ };
+ source = contents;
+ initialize();
+ }
+
+ public void initialize() {
+ position = 0;
+ pos_cur = 0;
+ pos_line = 1;
+ pos_col = 0;
+ }
+
+ //
+ // Lisaac Parser
+ //
+
+ public boolean readSpace() {
+ int pos,posold;
+ int level_comment = 0;
+
+ pos = position;
+ posold = -1;
+ while (posold != position) {
+ posold = position;
+
+ // skip spaces
+ while ((lastCharacter() != 0) && (lastCharacter() <= ' ')) {
+ position++;
+ }
+ if (position < source.length()-1) {
+ // Skip C++ comment style :
+ if (lastCharacter() == '/' && source.charAt(position+1) == '/') {
+ position += 2;
+
+ if (isCatchComment)
+ lastComment += "\t";
+
+ while ((lastCharacter() != 0) && (lastCharacter() != '\n')) {
+ if (isCatchComment)
+ lastComment += lastCharacter();
+
+ lastCharacter();
+ position++;
+ }
+ if (isCatchComment)
+ lastComment += "\n";
+ }
+ }
+ if (position < source.length()-1) {
+ // Skip C comment style :
+ if (lastCharacter() == '/' && source.charAt(position+1) == '*') {
+ position += 2;
+ level_comment++;
+
+ while (lastCharacter() != 0 && level_comment != 0) {
+ if (lastCharacter() == '/' && source.charAt(position+1) == '*') {
+ position += 2;
+ level_comment++;
+ } else if (lastCharacter() == '*' && source.charAt(position+1) == '/') {
+ position += 2;
+ level_comment--;
+ } else {
+ position++;
+ }
+ }
+ if (level_comment != 0) {
+ reporter.syntaxError("End of comment not found !", getPosition());
+ }
+ }
+ }
+ }
+ // FALSE : Last character.
+ begin_position = position;
+ return (position != pos) || (lastCharacter() != 0);
+ }
+
+ public boolean readSymbol(String st) {
+ int posold,j;
+ boolean result=false;
+
+ if (! readSpace()) {
+ result = false;
+ } else {
+ posold = position;
+ j = 0;
+ while (lastCharacter() != 0 && (j <= st.length()-1 && lastCharacter() == st.charAt(j))) {
+ position++;
+ j++;
+ }
+ if (j > st.length()-1) {
+ result = true;
+ lastString = st;
+ } else {
+ position = posold;
+ result = false;
+ }
+ }
+ return result;
+ }
+
+ public boolean readCharacter (char ch) {
+ boolean result=false;
+
+ if (! readSpace()) {
+ result = false;
+ } else {
+ if (lastCharacter() == ch) {
+ position++;
+ result = true;
+ }
+ }
+ return result;
+ }
+
+ //-- affect -> ":=" | "<-" | "?="
+ public boolean readAffect() {
+ return readSymbol(ILisaacModel.symbol_affect_immediate) ||
+ readSymbol(ILisaacModel.symbol_affect_cast) ||
+ readSymbol(ILisaacModel.symbol_affect_code);
+ }
+
+ //-- style -> '-' | '+'
+ public char readStyle() {
+ char result;
+
+ if (readCharacter('-')) {
+ result = '-';
+ } else if (readCharacter('+')) {
+ result = '+';
+ } else {
+ result = ' ';
+ }
+ return result;
+ }
+
+ //-- identifier -> 'a'-'z' {'a'-'z' | '0'-'9' | '_'}
+ public boolean readIdentifier() {
+ boolean result=false;
+ int posold,idx;
+
+ if (! readSpace() || !Character.isLowerCase(lastCharacter())) {
+ result = false;
+ } else {
+ posold = position;
+ string_tmp = "";
+
+ while (lastCharacter() != 0 &&
+ (Character.isLowerCase(lastCharacter()) ||
+ Character.isDigit(lastCharacter()) ||
+ lastCharacter() == '_')) {
+ string_tmp += lastCharacter();
+ position++;
+ }
+ if (string_tmp.length() > 0) {
+ idx = string_tmp.lastIndexOf("__");
+ if (idx != -1) {
+ position = posold+idx;
+ reporter.syntaxError("Identifier is incorrect.", getPosition());
+ }
+ lastString = getString(string_tmp);
+ result = true;
+ }
+ }
+ return result;
+ }
+
+ public boolean readWord(String st) {
+ int posold,idx;
+ boolean result=false;
+
+ if (! readSpace()) {
+ result = false;
+ } else {
+ posold = position;
+ idx = 0;
+
+ while (idx <= st.length()-1 && lastCharacter() == st.charAt(idx)) {
+ position++;
+ idx++;
+ }
+ if (idx > st.length()-1) {
+ lastString = st;
+ result = true;
+ } else {
+ position = posold;
+ }
+ }
+ return result;
+ }
+
+ public boolean readThisKeyword(String st) {
+ return readWord(st);
+ }
+
+ //-- keyword -> 'A'-'Z' 'a'-'z' {'a'-'z' | '0'-'9' | '_'}
+ public boolean readKeyword() {
+ boolean result=false;
+
+ if (! readSpace() || ! Character.isUpperCase(lastCharacter())) {
+ result = false;
+ } else {
+ string_tmp = "";
+ string_tmp += lastCharacter();
+ position++;
+
+ if (Character.isLowerCase(lastCharacter())) {
+ string_tmp += lastCharacter();
+ position++;
+ while (lastCharacter() != 0 &&
+ (Character.isLowerCase(lastCharacter()) ||
+ Character.isDigit(lastCharacter()) ||
+ lastCharacter() == '_')) {
+ string_tmp += lastCharacter();
+ position++;
+ }
+ lastString = getString(string_tmp);
+ result = true;
+ } else {
+ position--;
+ result = false;
+ }
+ }
+ return result;
+ }
+
+ //-- cap_identifier -> 'A'-'Z' {'A'-'Z' | '0'-'9' | '_'}
+ public boolean readCapIdentifier() {
+ int posold,idx;
+ boolean result=false;
+ char car;
+
+ if (! readSpace() || ! Character.isUpperCase(lastCharacter())) {
+ result = false;
+ } else {
+ posold = position;
+ string_tmp = ""+lastCharacter();
+ position++;
+ isParameterType = true;
+ while (lastCharacter() != 0 &&
+ (Character.isUpperCase(lastCharacter()) ||
+ Character.isDigit(lastCharacter()) ||
+ lastCharacter() == '_')) {
+ car = lastCharacter();
+ isParameterType = isParameterType && (Character.isDigit(car));
+
+ string_tmp += car;
+ position++;
+ }
+ if (Character.isLetter(lastCharacter()) ||
+ Character.isDigit(lastCharacter()) ||
+ lastCharacter() == '_') {
+ reporter.syntaxError("Identifier is incorrect.", getPosition());
+ return false;
+ }
+ idx = string_tmp.lastIndexOf("__");
+ if (idx != -1) {
+ position = posold + idx;
+ reporter.syntaxError("Identifier is incorrect.", getPosition());
+ return false;
+ }
+ lastString = getString(string_tmp);
+ result = true;
+ }
+ return result;
+ }
+
+ //-- integer -> number
+ //-- number -> {'0'-'9'} ['d']
+ //-- | '0'-'9' {'0'-'9' | 'A'-'F' | 'a'-'f'} 'h'
+ //-- | {'0'-'7'} 'o'
+ //-- | {'0' | '1'} 'b'
+ public boolean readInteger() {
+ boolean result=false;
+ //int pos_old;
+
+ if (readSpace() && Character.isDigit(lastCharacter())) {
+ result = true;
+ string_tmp = ""+lastCharacter();
+ //pos_old = position;
+ position++;
+
+ while (isHexadecimalDigit(lastCharacter()) || lastCharacter() == '_') {
+ if (lastCharacter() != '_') {
+ string_tmp += lastCharacter();
+ }
+ position++;
+ }
+ if (lastCharacter() == 'h') {
+ try {
+ Integer integer = Integer.valueOf(string_tmp, 16);
+ lastInteger = integer.intValue();
+ } catch (Exception e) {
+ System.out.println("Warning readInteger : "+e);// FIXME hex string
+ lastInteger = 0;
+ }
+ position++;
+ } else {
+ if (string_tmp.charAt(string_tmp.length()-1) > '9') {
+ string_tmp = string_tmp.substring(0, string_tmp.length()-1);// remove last
+ position--;
+ }
+ if (lastCharacter() == 'o') {
+ if (!isOctal(string_tmp)) {
+ reporter.syntaxError("Incorrect octal number.", getPosition());
+ }
+ lastInteger = Integer.valueOf(string_tmp, 8).intValue();
+ position++;
+ } else if (lastCharacter() == 'b') {
+ if (!isBinary(string_tmp)) {
+ reporter.syntaxError("Incorrect binary number.", getPosition());
+ }
+ lastInteger = Integer.valueOf(string_tmp, 2).intValue();
+ position++;
+ } else {
+ if (lastCharacter() == 'd') {
+ position++;
+ }
+ if (! isInteger(string_tmp)) {
+ reporter.syntaxError("Incorrect decimal number.", getPosition());
+ }
+ lastInteger = Integer.valueOf(string_tmp);
+ }
+ }
+ }
+ return result;
+ }
+
+ private boolean isInteger(String s) {
+ try {
+ Integer.parseInt(s);
+ } catch (NumberFormatException e) {
+ return false;
+ }
+ return true;
+ }
+
+ // True when the contents is a sequence of bits (i.e., mixed
+ // characters `0' and characters `1').
+ private boolean isBinary(String s) {
+ boolean result;
+ int i;
+
+ i = s.length()-1;
+ result = true;
+ while (result && i != 0) {
+ result = s.charAt(i) == '0' || s.charAt(i) == '1';
+ i--;
+ }
+ return result;
+ }
+
+ private boolean isOctal(String s) {
+ try {
+ Integer.parseInt(s, 8);
+ } catch (NumberFormatException e) {
+ return false;
+ }
+ return true;
+ }
+
+ private boolean isHexadecimalDigit(char c) {
+ boolean result=false;
+
+ if (Character.isDigit(c)) {
+ result = true;
+ } else if (c >= 'a') {
+ result = c <= 'f';
+ } else if (c >= 'A') {
+ result = c <= 'F';
+ }
+ return result;
+ }
+
+ //-- real -> '0'-'9' {'0'-'9'_} [ '.' {'0'-'9'} ] [ 'E' ['+'|'-'] '0'-'9' {'0'-'9'}
+ public boolean readReal() {
+ boolean result=false;
+ int pos_old;
+
+ if (readSpace() && Character.isDigit(lastCharacter())) {
+ string_tmp = ""+lastCharacter();
+ pos_old = position;
+ position++;
+
+ while (Character.isDigit(lastCharacter()) || lastCharacter() == '_') {
+ if (lastCharacter() != '_') {
+ string_tmp += lastCharacter();
+ }
+ position++;
+ }
+ if (lastCharacter() == '.') {
+ string_tmp += '.';
+ position++;
+
+ if (Character.isDigit(lastCharacter())) {
+ result = true;
+ string_tmp += lastCharacter();
+ position++;
+
+ while (Character.isDigit(lastCharacter())) {
+ string_tmp += lastCharacter();
+ position++;
+ }
+ }
+ if (lastCharacter() == 'E') {
+ result = true;
+ string_tmp += 'E';
+ position++;
+
+ if (lastCharacter() == '+' || lastCharacter() == '-') {
+ string_tmp += lastCharacter();
+ position++;
+ }
+ if (Character.isDigit(lastCharacter())) {
+ string_tmp += lastCharacter();
+ position++;
+ while (Character.isDigit(lastCharacter())) {
+ string_tmp += lastCharacter();
+ position++;
+ }
+ } else {
+ reporter.syntaxError("Incorrect real number.", getPosition());
+ }
+ }
+ }
+ if (result) {
+ lastReal = getString(string_tmp);
+ } else {
+ position = pos_old;
+ }
+ }
+ return result;
+ }
+
+ public void readEscapeCharacter() {
+ int val;
+
+ if (isSeparator(lastCharacter())) {
+ position++;
+ while (lastCharacter() != 0 && isSeparator(lastCharacter())) {
+ position++;
+ }
+ if (lastCharacter() == '\\') {
+ string_tmp.substring(0, string_tmp.length()-2); // remove last
+ position++;
+ } else if (lastCharacter() != 0) {
+ reporter.syntaxError("Unknown escape sequence.", getPosition());
+ }
+ } else if (lastCharacter() != 0) {
+ char c = lastCharacter();
+
+ if (c == 'a' ||
+ c == 'b' ||
+ c == 'f' ||
+ c == 'n' ||
+ c == 'r' ||
+ c == 't' ||
+ c == 'v' ||
+ c == '\\' ||
+ c == '?' ||
+ c == '\'' ||
+ c == '\"') {
+ string_tmp += c;
+ position++;
+ } else if (lastCharacter() >= '0' && lastCharacter() <= '9') {
+ if (lastCharacter() == '0' &&
+ position < source.length() &&
+ ! isHexadecimalDigit(source.charAt(position+1))) {
+
+ string_tmp += lastCharacter();
+ position++;
+ } else {
+ String string_tmp2 = new String(string_tmp);
+ readInteger(); // result is Always TRUE.
+ string_tmp = string_tmp2;
+
+ if (lastInteger > 255) {
+ reporter.syntaxError("Invalid range character number [0,255].", getPosition());
+ }
+ val = (int) lastInteger;
+ string_tmp += (val / 64);
+ string_tmp += ((val % 64) / 8);
+ string_tmp += (val % 8);
+ if (lastCharacter() == '\\') {
+ position++;
+ } else {
+ reporter.syntaxError("Character '\' is needed.", getPosition());
+ }
+ }
+ } else {
+ reporter.syntaxError("Unknown escape sequence.", getPosition());
+ }
+ }
+ }
+
+ //-- character -> '\'' ascii '\''
+ public boolean readCharacters() {
+ boolean result=false;
+ int count=0;
+
+ if (readSpace() && lastCharacter() == '\'') {
+ //old_pos = position;
+ position++;
+ string_tmp = "";
+ while (lastCharacter() != 0 && lastCharacter() != '\n' && lastCharacter() != '\'') {
+ string_tmp += lastCharacter();
+ if (lastCharacter() == '\\') {
+ position++;
+ readEscapeCharacter();
+ count++;
+ } else {
+ position++;
+ count++;
+ }
+ }
+ if (lastCharacter() == '\'') {
+ position++;
+ lastString = getString(string_tmp);
+ if (count != 1) {
+ position = begin_position;
+ reporter.syntaxError("Character constant too long.", getPosition());
+ }
+ result = true;
+ } else {
+ position = begin_position;
+ reporter.syntaxError("Unterminated character constant.", getPosition());
+ }
+ }
+ return result;
+ }
+
+ //-- string -> '\"' ascii_string '\"'
+ public boolean readString() {
+ boolean result=false;
+ // int old_pos;
+
+ if (readSpace() && lastCharacter() == '\"') {
+ // old_pos = position;
+ position = position+1;
+ string_tmp = "";
+ while (lastCharacter() != 0 && lastCharacter() != '\n' && lastCharacter() != '\"') {
+ string_tmp += lastCharacter();
+ if (lastCharacter() == '\\') {
+ position = position+1;
+ readEscapeCharacter();
+ } else {
+ position = position+1;
+ }
+ }
+ if (lastCharacter() == '\"') {
+ position = position+1;
+ lastString = getString(string_tmp);
+ result = true;
+ } else {
+ position = begin_position;
+ reporter.syntaxError("Unterminated string constant.", getPosition());
+ }
+ }
+ return result;
+ }
+
+ //-- external -> '`' ascii_c_code '`'
+ public boolean readExternal() {
+ boolean result=false;
+ // int pos_old;
+
+ if ((! readSpace()) || lastCharacter() != '`') {
+ result = false;
+ } else {
+ // pos_old=position;
+ position = position+1;
+ string_tmp = "";
+ while (lastCharacter() != 0 && lastCharacter() != '`') {
+ string_tmp += lastCharacter();
+ if (lastCharacter() == '\\') {
+ position = position+1;
+ string_tmp += lastCharacter();
+ if (lastCharacter() != 0) {
+ position = position+1;
+ }
+ } else {
+ position = position+1;
+ }
+ }
+ if (lastCharacter() != 0) {
+ position = position+1;
+ lastString = getString(string_tmp);
+ result = true;
+ } else {
+ result = false;
+ }
+ }
+ return result;
+ }
+
+ private final String operators = "!@#$%^&<|*-+=~/?\\>";
+
+ //-- operator -> '!' | '@' | '#' | '$' | '%' | '^' | '&' | '<' | '|'
+ //-- | '*' | '-' | '+' | '=' | '~' | '/' | '?' | '\' | '>'
+ public boolean readOperator() {
+ boolean result=false;
+ // int old_pos;
+
+ readSpace();
+ // old_pos = position;
+ string_tmp = "";
+ while (lastCharacter() != 0 &&
+ operators.indexOf(lastCharacter()) != -1) {
+ string_tmp += lastCharacter();
+ position = position+1;
+ }
+ if (string_tmp.length() > 0) {
+ lastString = getString(string_tmp);
+ if (lastString.equals(ILisaacModel.symbol_affect_immediate) ||
+ lastString.equals(ILisaacModel.symbol_affect_code) ||
+ lastString.equals(ILisaacModel.symbol_affect_cast)) {
+ reporter.syntaxError("Incorrect operator.", getPosition());
+ }
+ result = true;
+ }
+ return result;
+ }
+
+ // True when character is a separator.
+ private boolean isSeparator(char c) {
+ return c == ' ' || c == '\t' || c == '\n' ||
+ c == '\r' || c == '\0' || c == '\f'; // || c == '\v';
+ }
+
+ public String getString(String str) {
+ if (model == null) {
+ return str;
+ }
+ return model.getAliasString().get(str);
+ }
+
+
+ public ILisaacErrorHandler getReporter() {
+ return reporter;
+ }
+}
diff --git a/src/org/eclipse/lisaac/model/LisaacCompletionParser.java b/src/org/eclipse/lisaac/model/LisaacCompletionParser.java
index 62c3862..419978a 100644
--- a/src/org/eclipse/lisaac/model/LisaacCompletionParser.java
+++ b/src/org/eclipse/lisaac/model/LisaacCompletionParser.java
@@ -19,17 +19,22 @@ import org.eclipse.lisaac.model.items.ITMRead;
import org.eclipse.lisaac.model.items.Prototype;
import org.eclipse.lisaac.model.items.Slot;
import org.eclipse.lisaac.model.types.IType;
-import org.eclipse.lisaac.model.types.TypeSimple;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchWindow;
public class LisaacCompletionParser extends LisaacParser {
+ protected static LisaacModel model;
protected Prototype currentPrototype;
protected Slot currentSlot;
- public LisaacCompletionParser(String contents) {
+ protected int endOffset;
+
+
+
+ public LisaacCompletionParser(String contents, LisaacModel model) {
super(contents);
+ LisaacCompletionParser.model = model;
}
/**
@@ -45,6 +50,7 @@ public class LisaacCompletionParser extends LisaacParser {
currentPrototype = LisaacModel.getCurrentPrototype();
currentSlot = currentPrototype.getSlot(startOffset);
+ endOffset = -1;
ICode code = readExpr();
if (code != null && currentPrototype != null) {
@@ -58,8 +64,8 @@ public class LisaacCompletionParser extends LisaacParser {
proposals.add(new CompletionProposal(""+type,baseOffset,0,0));
} else {
// partial slot name (first keyword)
- if (code instanceof ITMRead) {
- String prefix = ((ITMRead) code).getName();
+ if (code instanceof ITMRead) {
+ String prefix = ((ITMRead) code).getName();
currentPrototype.lookupSlotMatch(prefix, proposals, baseOffset, 0);
}
}
@@ -72,6 +78,9 @@ public class LisaacCompletionParser extends LisaacParser {
ICode result = readExprBase();
if (result != null) {
while (readCharacter('.')) {
+ if (endOffset != -1 && position == endOffset+1) {
+ break;
+ }
ICode lastResult = result;
result = readSendMsg(result);
if (result == null) {
@@ -100,6 +109,36 @@ public class LisaacCompletionParser extends LisaacParser {
return result;
}
+
+ public Prototype readReceiver(int startOffset, int endOffset, Prototype currentPrototype) throws CoreException {
+ Prototype result=null;
+ IType type;
+
+ this.currentPrototype = currentPrototype;//LisaacModel.getCurrentPrototype();
+ currentSlot = currentPrototype.getSlot(startOffset);
+ this.endOffset = endOffset;
+
+ setPosition(startOffset);
+ readSpace();
+
+ ICode code = readExpr();
+ if (code != null && currentPrototype != null) {
+ type = code.getType(currentSlot, currentPrototype);
+ if (type != null) {
+ //if (! type.equals(TypeSimple.getTypeSelf())) {
+ if ("SELF".compareTo(type.toString()) != 0) {
+ Prototype save = currentPrototype;
+ currentPrototype = findPrototype(type.toString());
+ if (currentPrototype == null) {
+ currentPrototype = save;
+ }
+ }
+ result = currentPrototype;
+ }
+ }
+ return result;
+ }
+
/**
* Find and parse a lisaac prototype according to its name.
*/
@@ -107,43 +146,47 @@ public class LisaacCompletionParser extends LisaacParser {
IProject project = null;
Prototype result = null;
- IWorkbenchWindow w = LisaacPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow();
- if (w == null) {
+ if (model == null) {
+ IWorkbenchWindow w = LisaacPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow();
+ if (w == null) {
+ return null;
+ }
+ IWorkbenchPart part = w.getPartService().getActivePart();
+ if (part instanceof LisaacEditor) {
+ project = ((LisaacEditor)part).getProject();
+ }
+ if (project != null) {
+ model = LisaacModel.getModel(project);
+ }
+ }
+ if (model == null) {
return null;
}
- IWorkbenchPart part = w.getPartService().getActivePart();
- if (part instanceof LisaacEditor) {
- project = ((LisaacEditor)part).getProject();
+ Prototype prototype = model.getPrototype(prototypeName);
+ if (prototype != null) {
+ // prototype is already cached
+ return prototype;
}
- if (project != null) {
- LisaacModel model = LisaacModel.getModel(project);
- Prototype prototype = model.getPrototype(prototypeName);
- if (prototype != null) {
- // prototype is already cached
- return prototype;
- }
-
- // cache new prototype
- String prototypePath = model.getPathManager().getFullPath(prototypeName);
- if (prototypePath != null) {
- IPath location = new Path(prototypePath);
+ // cache new prototype
+ String prototypePath = model.getPathManager().getFullPath(prototypeName);
+ if (prototypePath != null) {
+ IPath location = new Path(prototypePath);
- IFile file = project.getFile(location.lastSegment());
- if (! file.isAccessible()) {
- file.createLink(location, IResource.REPLACE, null);
- }
- result = model.parsePrototype(prototypeName, file.getContents(), new ILisaacErrorHandler() {
- public void fatalError(String msg, Position position) {
- }
- public void semanticError(String msg, Position position) {
- }
- public void syntaxError(String msg, Position position) {
- }
- public void warning(String msg, Position position) {
- }
- });
+ IFile file = project.getFile(location.lastSegment());
+ if (! file.isAccessible()) {
+ file.createLink(location, IResource.REPLACE, null);
}
+ result = model.parsePrototype(prototypeName, file.getContents(), new ILisaacErrorHandler() {
+ public void fatalError(String msg, Position position) {
+ }
+ public void semanticError(String msg, Position position) {
+ }
+ public void syntaxError(String msg, Position position) {
+ }
+ public void warning(String msg, Position position) {
+ }
+ });
}
return result;
}
@@ -153,7 +196,7 @@ public class LisaacCompletionParser extends LisaacParser {
*/
public static Prototype findPrototype(String prototypeName, LisaacModel model) throws CoreException {
Prototype result = null;
-
+
Prototype prototype = model.getPrototype(prototypeName);
if (prototype != null) {
// prototype is already cached
@@ -165,7 +208,7 @@ public class LisaacCompletionParser extends LisaacParser {
if (prototypePath != null) {
IPath location = new Path(prototypePath);
IProject project = model.getProject();
-
+
IFile file = project.getFile(location.lastSegment());
if (! file.isAccessible()) {
file.createLink(location, IResource.REPLACE | IResource.HIDDEN, null);
diff --git a/src/org/eclipse/lisaac/model/LisaacModel.java b/src/org/eclipse/lisaac/model/LisaacModel.java
index 32f2b9e..87f8545 100644
--- a/src/org/eclipse/lisaac/model/LisaacModel.java
+++ b/src/org/eclipse/lisaac/model/LisaacModel.java
@@ -15,6 +15,7 @@ import org.eclipse.lisaac.editors.AbstractLisaacEditor;
import org.eclipse.lisaac.editors.LisaacEditor;
import org.eclipse.lisaac.model.items.Prototype;
import org.eclipse.lisaac.model.lip.LIP;
+import org.eclipse.ui.IPartService;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchWindow;
@@ -29,13 +30,13 @@ public class LisaacModel implements ILisaacModel{
/** list of all legal prototypes path */
private LisaacPath modelPath;
-
+
/** list of all encountered prototypes */
private HashMap<String,Prototype> prototypes;
/** lip makefile of this model */
private LIP lipCode;
-
+
/** project associated with this model */
private IProject project;
@@ -44,27 +45,27 @@ public class LisaacModel implements ILisaacModel{
/** error handler */
private ILisaacErrorHandler reporter;
-
+
/** lisaac parser */
private LisaacParser parser;
-
+
/** string aliaser */
private AliasString aliasString;
-
+
public LisaacModel(IProject project) {
this.project = project;
prototypes = new HashMap<String,Prototype>();
aliasString = new AliasString();
-
+
builder = new LisaacBuilder(this);
-
+
// add this model to the model list
if (modelList == null) {
modelList = new HashMap<IProject,LisaacModel>();
}
modelList.put(project, this);
-
+
// create lisaac path
modelPath = new LisaacPath(project, "make.lip"); // TODO get lip from property page
}
@@ -76,7 +77,7 @@ public class LisaacModel implements ILisaacModel{
public void setProject(IProject project) {
this.project = project;
}
-
+
public LisaacBuilder getBuilder() {
return builder;
}
@@ -92,7 +93,7 @@ public class LisaacModel implements ILisaacModel{
public LIP getLipCode() {
return lipCode;
}
-
+
public Prototype getPrototype(String name) {
if (prototypes != null) {
return prototypes.get(name);
@@ -103,7 +104,7 @@ public class LisaacModel implements ILisaacModel{
public void buildAll() {
try {
builder.build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null, null);
-
+
// refresh editor coloring
IWorkbenchWindow w = LisaacPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow();
IWorkbenchPart part = w.getPartService().getActivePart();
@@ -114,14 +115,14 @@ public class LisaacModel implements ILisaacModel{
e.printStackTrace();
}
}
-
+
/** parse and create part of current model */
public Prototype parsePrototype(String name, InputStream contents, ILisaacErrorHandler reporter) {
this.reporter = reporter;
-
+
parser = new LisaacParser(contents, this);
Prototype prototype = new Prototype(name, extractPrototypeName(name),this);
-
+
ILisaacContext context = parser.readContext();
while (context != null) {
if (context.parseDefinition(prototype)) {
@@ -139,19 +140,19 @@ public class LisaacModel implements ILisaacModel{
public void removePrototype(IResource resource) {
prototypes.remove(extractPrototypeName(resource.getName()));
}
-
+
/** parse and create part of current model
* @throws CoreException */
public void parseLip(String name, InputStream contents, ILisaacErrorHandler reporter) throws CoreException {
this.reporter = reporter;
-
+
lipCode = new LIP(name);
LipParser lipParser = new LipParser(contents, this);
if (! lipParser.parse()) {
reporter.syntaxError("Syntax error.", lipParser.getPosition());
return;
}
-
+
// parse lip parents
for (int i=0; i<lipCode.getParentCount(); i++) {
String parent = lipCode.getParent(i);
@@ -168,12 +169,12 @@ public class LisaacModel implements ILisaacModel{
}
}
}
-
+
/** remove part of current model */
public void removeLip(IResource resource) {
// TODO remove lip
}
-
+
/** get little name of prototype instead of full path */
public static String extractPrototypeName(String s) {
int idx = s.indexOf('.');
@@ -182,11 +183,11 @@ public class LisaacModel implements ILisaacModel{
}
return s.toUpperCase();
}
-
+
public ILisaacErrorHandler getReporter() {
return reporter;
}
-
+
/**
* Get the lisaac model associated with the given project.
* @param p A lisaac project
@@ -198,15 +199,21 @@ public class LisaacModel implements ILisaacModel{
}
return null;
}
-
+
public static Prototype getCurrentPrototype() {
IWorkbenchWindow w = LisaacPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow();
-
- IWorkbenchPart part = w.getPartService().getActivePart();
+ if (w == null) {
+ return null;
+ }
+ IPartService service = w.getPartService();
+ if (service == null) {
+ return null;
+ }
+ IWorkbenchPart part = service.getActivePart();
if (part instanceof LisaacEditor) {
IProject project = ((LisaacEditor)part).getProject();
String filename = ((LisaacEditor)part).getFileName();
-
+
LisaacModel model = LisaacModel.getModel(project);
if (model != null) {
return model.getPrototype(extractPrototypeName(filename));
diff --git a/src/org/eclipse/lisaac/model/LisaacParser.java b/src/org/eclipse/lisaac/model/LisaacParser.java
index 64d325a..85b74f0 100644
--- a/src/org/eclipse/lisaac/model/LisaacParser.java
+++ b/src/org/eclipse/lisaac/model/LisaacParser.java
@@ -805,7 +805,7 @@ public class LisaacParser extends AbstractLisaacParser {
//++ EXPR_BASE -> "Old" EXPR
//++ | EXPR_PRIMARY
//++ | SEND_MSG
- protected ICode readExprBase() {
+ public ICode readExprBase() {
ICode result=null;
if (readThisKeyword(ILisaacModel.keyword_old)) {
@@ -1026,7 +1026,7 @@ public class LisaacParser extends AbstractLisaacParser {
}
//++ SEND_MSG -> identifier [ ARGUMENT { identifier ARGUMENT } ]
- protected ICode readSendMsg(ICode firstArg) {
+ public ICode readSendMsg(ICode firstArg) {
ICode result=null;
if (readIdentifier()) {
@@ -1414,6 +1414,42 @@ public class LisaacParser extends AbstractLisaacParser {
return true;
}
+ //++ SEND_MSG -> identifier [ ARGUMENT { identifier ARGUMENT } ]
+ public String readKeywordInSendMsg(String keyword, int keywordOffset) {
+ String result=null;
+ boolean keywordFound=false;
+
+ if (readIdentifier()) {
+ //
+ // Classic Message.
+ //
+ String n = getString(lastString);// create alias
+ if (n.compareTo(keyword) == 0 && position == keywordOffset+keyword.length()) {
+ keywordFound = true;
+ }
+ // Argument list.
+ ICode arg = readArgument();
+ if (arg != null) {
+ while (readIdentifier()) {
+ if (lastString.compareTo(keyword) == 0 && position == keywordOffset+keyword.length()) {
+ keywordFound = true;
+ }
+ n += "__" + lastString; // FIXME: alias pb
+ arg = readArgument();
+ if (arg == null) {
+ reporter.syntaxError("Incorrect argument.", getPosition());
+ return null;
+ }
+ }
+ }
+ // return slot full name
+ result = getString(n); // FIXME alias pb
+ }
+ if (! keywordFound) {
+ result = null;
+ }
+ return result;
+ }
/**
* Read the next context in lisaac code.
diff --git a/src/org/eclipse/lisaac/model/items/Prototype.java b/src/org/eclipse/lisaac/model/items/Prototype.java
index 546b7d2..3300509 100644
--- a/src/org/eclipse/lisaac/model/items/Prototype.java
+++ b/src/org/eclipse/lisaac/model/items/Prototype.java
@@ -7,9 +7,11 @@ import java.util.Iterator;
import java.util.List;
import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.lisaac.model.ILisaacModel;
import org.eclipse.lisaac.model.LisaacCompletionParser;
+import org.eclipse.lisaac.model.LisaacModel;
import org.eclipse.lisaac.model.LisaacParser;
import org.eclipse.lisaac.model.types.IType;
import org.eclipse.lisaac.outline.OutlineItem;
@@ -241,7 +243,121 @@ public class Prototype {
}
}
}
-
+
+ public Slot getSlotFromKeyword(String keyword, LisaacParser parser, int baseOffset) throws CoreException {
+ String source = parser.getSource();
+ int bracketLevel = 0;
+ Prototype receiver = null;
+ Slot result = null;
+ char c = 0;
+
+ int offset = baseOffset;
+ if (offset >= source.length()-1) {
+ return null;
+ }
+
+ while (offset > 0) {
+ //
+ // find beginning of SEND_MSG grammar rule
+ //
+
+ // Rewind to '(' ';' '[' '.'
+ c = source.charAt(offset);
+ if (c == ';' || c == '.') {
+ break;
+ }
+ if (c == '(' || c == '[') {
+ if (bracketLevel == 0) {
+ break;
+ }
+ bracketLevel--;
+ }
+ if (c == ')' || c == ']') {
+ bracketLevel++;
+ }
+
+ // look at indentation
+ if (c == '\n' && source.length() - offset > 4) {
+ if (source.charAt(offset+1) == ' ' &&
+ source.charAt(offset+2) == ' ' &&
+ (source.charAt(offset+3) == '+' || source.charAt(offset+3) == '-')) {
+ String slotName = parser.readSlotNameFromOffset(offset+4);
+ if (slotName != null) {
+ result = getSlot(slotName);
+ if (result == null) {
+ return null;
+ }
+ if (result.keywordCount() == 1) {
+ if (result.getName().compareTo(keyword) == 0) {
+ return result;
+ }
+ } else {
+ // find keyword next token
+ offset = baseOffset;
+ while (offset < source.length()-1 &&
+ Character.isJavaIdentifierPart(source.charAt(offset))) {
+ offset++;
+ }
+ // read space
+ while (offset < source.length()-1 &&
+ Character.isWhitespace(source.charAt(offset))) {
+ offset++;
+ }
+ if (source.charAt(offset) != ':') {
+ return result;// 'keyword' is a slot keyword
+ }
+ return null;
+ }
+ }
+ }
+ }
+ offset--;
+ }
+ if (result == null) {
+ // Slot Call.
+
+ if (c == '.') {
+ int pointOffset = offset;
+ offset--;
+ bracketLevel = 0;
+
+ // rewind until ';' '(' '['
+ while (offset > 0) {
+ c = source.charAt(offset);
+ if (c == ';') {
+ break;
+ }
+ if (c == '(' || c == '[') {
+ if (bracketLevel == 0) {
+ break;
+ }
+ bracketLevel--;
+ }
+ if (c == ')' || c == ']') {
+ bracketLevel++;
+ }
+ offset--;
+ }
+ if (offset > 0) {
+ LisaacCompletionParser p = new LisaacCompletionParser(source, (LisaacModel)getModel());
+ receiver = p.readReceiver(offset+1, pointOffset, this);
+
+ offset = pointOffset;
+ }
+ } else {
+ receiver = this;
+ }
+ parser.setPosition(offset+1);
+ parser.readSpace();
+ String slotName = parser.readKeywordInSendMsg(keyword, baseOffset);
+
+ if (slotName != null && receiver != null) {
+ result = receiver.lookupSlot(slotName);
+ }
+ }
+ return result;
+ }
+
public void addSlot(Slot s) {
slotList.put(s.getName(), s);
}
@@ -286,7 +402,7 @@ public class Prototype {
Slot slot = it.next();
slot.getSlotProposals(proposals, offset, length);
}
-
+
values = parentList.values();
it = values.iterator() ;
while (it.hasNext()) {
diff --git a/src/org/eclipse/lisaac/model/items/Slot.java b/src/org/eclipse/lisaac/model/items/Slot.java
index ac132d6..ce4ac7a 100644
--- a/src/org/eclipse/lisaac/model/items/Slot.java
+++ b/src/org/eclipse/lisaac/model/items/Slot.java
@@ -77,6 +77,10 @@ public class Slot {
public Position getPosition() {
return position;
}
+
+ public int keywordCount() {
+ return keywordList.length;
+ }
//
// Value.
@@ -235,5 +239,9 @@ public class Slot {
public boolean match(String n) {
return name.startsWith(n);
}
+
+ public String getHoverInformation() {
+ return getSignature(false);
+ }
}
--
Lisaac eclipse plugin
More information about the Lisaac-commits
mailing list