mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-15 12:15:47 +02:00
new draft of type parsing.
This commit is contained in:
parent
4c4433067c
commit
6818565686
1 changed files with 352 additions and 0 deletions
|
@ -0,0 +1,352 @@
|
||||||
|
package org.eclipse.cdt.debug.mi.core;
|
||||||
|
/*
|
||||||
|
* Created on May 26, 2003
|
||||||
|
*
|
||||||
|
* To change this generated comment go to
|
||||||
|
* Window>Preferences>Java>Code Generation>Code and Comments
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author alain
|
||||||
|
*
|
||||||
|
* To change this generated comment go to
|
||||||
|
* Window>Preferences>Java>Code Generation>Code and Comments
|
||||||
|
*/
|
||||||
|
public class GDBTypeParser {
|
||||||
|
|
||||||
|
// GDB type parsing from whatis command
|
||||||
|
// declarator: type dcl
|
||||||
|
// type: (name)+
|
||||||
|
// dcl: ('*' | '&')* direct-decl
|
||||||
|
// direct-dcl: '(' dcl ')'
|
||||||
|
// direct-dcl '(' ')'
|
||||||
|
// direct-dcl '[' integer ']'
|
||||||
|
// name: ([a-zA-z][0-9])+
|
||||||
|
// integer ([0-9)+
|
||||||
|
|
||||||
|
final static int EOF = -1;
|
||||||
|
final static int NAME = 0;
|
||||||
|
final static int PARENS = 1;
|
||||||
|
final static int BRACKETS = 2;
|
||||||
|
|
||||||
|
String line;
|
||||||
|
int index;
|
||||||
|
int tokenType;
|
||||||
|
String token;
|
||||||
|
String dataType;
|
||||||
|
String name;
|
||||||
|
String out;
|
||||||
|
GDBType gdbType;
|
||||||
|
|
||||||
|
public class GDBType {
|
||||||
|
public final static int GENERIC = 0;
|
||||||
|
public final static int POINTER = 1;
|
||||||
|
public final static int REFERENCE= 2;
|
||||||
|
public final static int ARRAY = 3;
|
||||||
|
public final static int FUNCTION = 4;
|
||||||
|
|
||||||
|
String name;
|
||||||
|
int type;
|
||||||
|
|
||||||
|
public GDBType(String n) {
|
||||||
|
this(n, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GDBType(int t) {
|
||||||
|
this ("", t);
|
||||||
|
}
|
||||||
|
|
||||||
|
GDBType (String n, int t) {
|
||||||
|
name = n;
|
||||||
|
type = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class GDBDerivedType extends GDBType {
|
||||||
|
GDBType child;
|
||||||
|
int dimension;
|
||||||
|
public GDBDerivedType(GDBType c, int i) {
|
||||||
|
this(c, i, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GDBDerivedType(GDBType c, int t, int dim) {
|
||||||
|
super(t);
|
||||||
|
child = c;
|
||||||
|
dimension = dim;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GDBType getChild() {
|
||||||
|
return child;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasChild() {
|
||||||
|
return child != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDimension() {
|
||||||
|
return dimension;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
StringBuffer sb = new StringBuffer();
|
||||||
|
switch (getType()) {
|
||||||
|
case FUNCTION:
|
||||||
|
sb.append(" Function returning " + (hasChild() ? child.toString() : ""));
|
||||||
|
break;
|
||||||
|
case ARRAY:
|
||||||
|
sb.append(" Array[" + dimension + "]" + " to " + (hasChild() ? child.toString() : ""));
|
||||||
|
break;
|
||||||
|
case REFERENCE:
|
||||||
|
sb.append(" Reference to " + (hasChild() ? child.toString() : ""));
|
||||||
|
break;
|
||||||
|
case POINTER:
|
||||||
|
sb.append(" Pointer to " + (hasChild() ? child.toString() : ""));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public GDBTypeParser() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public GDBType getGDBType() {
|
||||||
|
return gdbType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void verbose() {
|
||||||
|
System.out.println(name + " --> " + out + dataType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void parse(String s) {
|
||||||
|
// Sanity.
|
||||||
|
if (s == null) {
|
||||||
|
s = new String();
|
||||||
|
}
|
||||||
|
s = s.trim();
|
||||||
|
|
||||||
|
// Initialize.
|
||||||
|
line = s;
|
||||||
|
index = 0;
|
||||||
|
token = "";
|
||||||
|
dataType = "";
|
||||||
|
|
||||||
|
out = "";
|
||||||
|
name = "";
|
||||||
|
|
||||||
|
// Fetch the datatype.
|
||||||
|
while (getToken() == NAME) {
|
||||||
|
dataType += " " + token;
|
||||||
|
}
|
||||||
|
|
||||||
|
gdbType = new GDBType(dataType);
|
||||||
|
|
||||||
|
// After getting the type move back
|
||||||
|
//ungetch();
|
||||||
|
dcl(tokenType);
|
||||||
|
}
|
||||||
|
|
||||||
|
int getch() {
|
||||||
|
if (index >= line.length() || index < 0) {
|
||||||
|
return EOF;
|
||||||
|
}
|
||||||
|
return line.charAt(index++);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ungetch() {
|
||||||
|
if (index > 0) {
|
||||||
|
index--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if the character is an alphabet
|
||||||
|
boolean isCIdentifierStart(int c) {
|
||||||
|
if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || c == '_') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check is the character is alpha numeric
|
||||||
|
// [a-zA-Z0-9]
|
||||||
|
boolean isCIdentifierPart(int c) {
|
||||||
|
if ((c >= '0' && c <= 9) || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || c == '_') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isCSpace(int c) {
|
||||||
|
if (c == ' ' || c == '\t' || c == '\f' || c == '\n') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// method returns the next token
|
||||||
|
int getToken() {
|
||||||
|
token = "";
|
||||||
|
|
||||||
|
int c = getch();
|
||||||
|
char character = (char)c;
|
||||||
|
|
||||||
|
// Skip over any space
|
||||||
|
while (isCSpace(c)) {
|
||||||
|
c = getch();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c == '(') {
|
||||||
|
if ((c = getch()) == ')') {
|
||||||
|
token = "()";
|
||||||
|
tokenType = PARENS;
|
||||||
|
} else {
|
||||||
|
ungetch();
|
||||||
|
tokenType = '(';
|
||||||
|
}
|
||||||
|
} else if (c == '[') {
|
||||||
|
while ((c = getch()) != ']' && c != EOF) {
|
||||||
|
token += (char)c;
|
||||||
|
}
|
||||||
|
tokenType = BRACKETS;
|
||||||
|
} else if (isCIdentifierStart(c)) {
|
||||||
|
token = "" + (char)c;
|
||||||
|
while (isCIdentifierPart((c = getch())) && c != EOF) {
|
||||||
|
token += (char)c;
|
||||||
|
}
|
||||||
|
ungetch();
|
||||||
|
tokenType = NAME;
|
||||||
|
} else if (c == '{') {
|
||||||
|
// Swallow gdb sends things like "struct foobar {..} *"
|
||||||
|
// FIXME: if the bracket is not terminate do we throw exception?
|
||||||
|
int count = 1;
|
||||||
|
do {
|
||||||
|
c = getch();
|
||||||
|
if (c == '{') {
|
||||||
|
count++;
|
||||||
|
} else if (c == '}') {
|
||||||
|
count--;
|
||||||
|
}
|
||||||
|
} while (count > 0 && c != EOF);
|
||||||
|
} else {
|
||||||
|
tokenType = c;
|
||||||
|
}
|
||||||
|
return tokenType;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dcl() {
|
||||||
|
dcl(getToken());
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse a declarator
|
||||||
|
void dcl(int c) {
|
||||||
|
int nstar = 0;
|
||||||
|
int namp = 0;
|
||||||
|
if (c == '*') {
|
||||||
|
nstar++;
|
||||||
|
for (; getToken() == '*'; nstar++) {
|
||||||
|
}
|
||||||
|
} else if (c == '&') {
|
||||||
|
namp++;
|
||||||
|
for (; getToken() == '&'; namp++) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dirdcl();
|
||||||
|
while (nstar-- > 0) {
|
||||||
|
out += " pointer to ";
|
||||||
|
gdbType = new GDBDerivedType(gdbType, GDBDerivedType.POINTER);
|
||||||
|
}
|
||||||
|
while (namp-- > 0) {
|
||||||
|
out += " reference to";
|
||||||
|
gdbType = new GDBDerivedType(gdbType, GDBDerivedType.REFERENCE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse a direct declarator
|
||||||
|
void dirdcl() {
|
||||||
|
int type;
|
||||||
|
|
||||||
|
if (tokenType == '(') {
|
||||||
|
dcl();
|
||||||
|
if (tokenType != ')') {
|
||||||
|
// FIXME: Do we throw an exception ? not terminate parenthese
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else if (tokenType == NAME) {
|
||||||
|
// Useless we do not need the name of the variable
|
||||||
|
name = " " + token;
|
||||||
|
} else {
|
||||||
|
// FIXME: another oops bad declaration
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((type = getToken()) == PARENS || type == BRACKETS) {
|
||||||
|
if (type == EOF) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (type == PARENS) {
|
||||||
|
out += " function returning ";
|
||||||
|
gdbType = new GDBDerivedType(gdbType, GDBType.FUNCTION);
|
||||||
|
} else {
|
||||||
|
int len = 0;
|
||||||
|
if (token.length() > 0) {
|
||||||
|
try {
|
||||||
|
out += "" + " array[";
|
||||||
|
len = Integer.parseInt(token);
|
||||||
|
out += len + "]";
|
||||||
|
out += " of ";
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
out += " array[0] of ";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
out += " array of ";
|
||||||
|
}
|
||||||
|
gdbType = new GDBDerivedType(gdbType, GDBType.ARRAY, len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
GDBTypeParser parser = new GDBTypeParser();
|
||||||
|
System.out.println("char **argv");
|
||||||
|
parser.parse("unsigned long long int **argv");
|
||||||
|
System.out.println(parser.getGDBType());
|
||||||
|
|
||||||
|
System.out.println("int (*daytab)[13]");
|
||||||
|
parser.parse("int (*daytab)[13]");
|
||||||
|
parser.verbose();
|
||||||
|
System.out.println(parser.getGDBType());
|
||||||
|
|
||||||
|
System.out.println("int *daytab[13]");
|
||||||
|
parser.parse("int *daytab[13]");
|
||||||
|
System.out.println(parser.getGDBType());
|
||||||
|
|
||||||
|
System.out.println("void *comp()");
|
||||||
|
parser.parse("void *comp()");
|
||||||
|
System.out.println(parser.getGDBType());
|
||||||
|
|
||||||
|
System.out.println("void (*comp)()");
|
||||||
|
parser.parse("void (*comp)()");
|
||||||
|
System.out.println(parser.getGDBType());
|
||||||
|
|
||||||
|
System.out.println("int (*func[15])()");
|
||||||
|
parser.parse("int (*func[15])()");
|
||||||
|
System.out.println(parser.getGDBType());
|
||||||
|
|
||||||
|
System.out.println("char (*(*x())[])()");
|
||||||
|
parser.parse("char (*(*x())[])()");
|
||||||
|
System.out.println(parser.getGDBType());
|
||||||
|
|
||||||
|
System.out.println("char (*(*x[3])())[5]");
|
||||||
|
parser.parse("char (*(*x[3])())[5]");
|
||||||
|
System.out.println(parser.getGDBType());
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue