Hallo zusammen!
Ich bastle gerade an einer Templateing-eingine und definiere definiere dafür eine eigene, kleine Sprache. Die Sprache soll mit JFlex und java_cup analysiert werden und damit ein Code-Baum erzeugt werden, welcher dann interpretiert wird.
Ich hab dabei u.a. folgende Anforderung: Es gibt if-statements, welche conditions auswerten und je nach dem ihren "Körper" ausführen oder nicht.
Eine Art der Conditions sind Relationale Bedingungen, also Vergleiche von Werten, wie 5 >= 3, a < 7 oder b + 4 < 6 *(a -1). Neben numerischen Werten gibts auch Strings und logische Werte, welche bei Vergleichen auch berücksichtigt werden müssen (also z.B. a == "hallo welt" soll möglich sein)!
a und b sind hier Variablen, die über ihren Namen (= Identifier) angesprochen werden können.
Der Kern meines Problem sieht so aus (ohne actions o. überflüssiges Zeug):
Wie man sieht ist das nonterminal id sowohl in der Regel für value als auch für arith enthalten. Das das nicht gut geht und es zu Konflikten kommt, ist mir mittlerweile klar, nur weis ich nicht, wie ich das lösen soll.
Die Vergleiche an sich sind so implementiert, dass sie nur einen Wert (value) wollen und zur Laufzeit entscheiden ob die beiden Werte überhaupt verglichen werden können. Ich kann auch zur Laufzeit bestimmen ob hinter a ein String oder ein DWORD oder sowas steht (Typ ist also bekannt).
Weis jemand wie man so ein Problem lösen kann? Mir raucht schon ganz schön der Kopf...
Gruß,
adalbert
Ich bastle gerade an einer Templateing-eingine und definiere definiere dafür eine eigene, kleine Sprache. Die Sprache soll mit JFlex und java_cup analysiert werden und damit ein Code-Baum erzeugt werden, welcher dann interpretiert wird.
Ich hab dabei u.a. folgende Anforderung: Es gibt if-statements, welche conditions auswerten und je nach dem ihren "Körper" ausführen oder nicht.
Eine Art der Conditions sind Relationale Bedingungen, also Vergleiche von Werten, wie 5 >= 3, a < 7 oder b + 4 < 6 *(a -1). Neben numerischen Werten gibts auch Strings und logische Werte, welche bei Vergleichen auch berücksichtigt werden müssen (also z.B. a == "hallo welt" soll möglich sein)!
a und b sind hier Variablen, die über ihren Namen (= Identifier) angesprochen werden können.
Der Kern meines Problem sieht so aus (ohne actions o. überflüssiges Zeug):
Code:
// ########################################################
// # Terminals
// ########################################################
terminal LPA, RPA; // ( and )
terminal STRING, BOOLEAN, INT, WORD; // Literals for Strings, Logic values and numeric values
terminal EQ, LT; // rel. operators == <
terminal IF, THEN, ENDIF;
terminal BODY; // all real statements
terminal PLUS, MINUS; // arith. operators
terminal IDENTIFIER; // identifier which can be resolved to a value
// ########################################################
// # NonTerminals
// ########################################################
non terminal prog; // the goal
non terminal if;
non terminal condition;
non terminal num_lit, str_lit, log_lit; // literals for numeric, string and logic values
non terminal id;
non terminal value; // any kind of value
non terminal arith; // any kind of arith. expression
// ########################################################
// # Precedences
// ########################################################
precedence left PLUS, MINUS;
precedence left LPA;
// ########################################################
// # Production rules
// ########################################################
prog ::= if;
if ::= IF condition THEN BODY ENDIF;
condition
::= value EQ value
| value LT value
;
value ::= str_lit
| log_lit
| arith
| id
;
str_lit ::= STRING;
log_lit ::= BOOLEAN;
num_lit ::= INT
| WORD
;
arith ::= arith PLUS arith
| arith MINUS arith
| LPA arith RPA
;
arith ::= num_lit
| id
;
id ::= IDENTIFIER
;
Wie man sieht ist das nonterminal id sowohl in der Regel für value als auch für arith enthalten. Das das nicht gut geht und es zu Konflikten kommt, ist mir mittlerweile klar, nur weis ich nicht, wie ich das lösen soll.
Die Vergleiche an sich sind so implementiert, dass sie nur einen Wert (value) wollen und zur Laufzeit entscheiden ob die beiden Werte überhaupt verglichen werden können. Ich kann auch zur Laufzeit bestimmen ob hinter a ein String oder ein DWORD oder sowas steht (Typ ist also bekannt).
Weis jemand wie man so ein Problem lösen kann? Mir raucht schon ganz schön der Kopf...
Gruß,
adalbert