浏览代码

expression parsing refactoring

Vladislav Folts 9 年之前
父节点
当前提交
4d74557932
共有 3 个文件被更改,包括 119 次插入97 次删除
  1. 二进制
      bin/compiled.zip
  2. 12 73
      src/ob/ContextExpression.ob
  3. 107 24
      src/ob/ExpressionTree.ob

二进制
bin/compiled.zip


+ 12 - 73
src/ob/ContextExpression.ob

@@ -9,7 +9,7 @@ TYPE
     END;
     PExpressionHandler* = POINTER TO ExpressionHandler;
 
-    SimpleExpression* = RECORD(ExpressionHandler)
+    SimpleExpression* = RECORD(ContextHierarchy.Node)
         PROCEDURE SimpleExpression*(parent: ContextHierarchy.PNode); 
         PROCEDURE handleOperator*(op: STRING);
 
@@ -19,9 +19,7 @@ TYPE
 
     ExpressionNode* = RECORD(ContextHierarchy.Node)
         PROCEDURE ExpressionNode*(parent: PExpressionHandler; node: ExpressionTree.PNode);
-        PROCEDURE handleSimple(s: ExpressionTree.PSimpleList);
 
-        relOps: ExpressionTree.POps;
         node-: ExpressionTree.PNode;
     END;
     PExpressionNode = POINTER TO ExpressionNode;
@@ -36,11 +34,9 @@ TYPE
     END;
 
     Term* = RECORD(ExpressionHandler)
-        PROCEDURE type(): Types.PType;
-        PROCEDURE handleOperator(op: ExpressionTree.BinaryOperator);
+        PROCEDURE Term*(parent: ContextHierarchy.PNode); 
 
-        expression: Expression.PType;
-        operator: ExpressionTree.BinaryOperator;
+        list: ExpressionTree.PTermList;
     END;
     PTerm = POINTER TO Term;
 
@@ -83,15 +79,8 @@ TYPE
     END;
 
 VAR
-    intOpTypeCheck: ExpressionTree.IntOpTypeCheck;
     globalOps: ExpressionTree.POps;
 
-PROCEDURE assertIntOp(type: Types.PType; literal: STRING; op: ExpressionTree.BinaryOperator): ExpressionTree.BinaryOperator;
-BEGIN
-    ExpressionTree.assertOpType(type, intOpTypeCheck, literal);
-    RETURN op;
-END;
-
 PROCEDURE promoteExpressionType(cx: ContextHierarchy.Root; left, right: Expression.PType);
 BEGIN
     IF left # NIL THEN
@@ -136,11 +125,6 @@ PROCEDURE SimpleExpression.SimpleExpression(parent: ContextHierarchy.PNode)
       list(parent(PExpressionNode).node.makeSimple());
 END; 
 
-PROCEDURE SimpleExpression.handleExpression(e: Expression.PType);
-BEGIN
-    SELF.list.addExpression(e);
-END;
-
 PROCEDURE SimpleExpression.handleLiteral(s: STRING);
 BEGIN
     SELF.list.unaryOp := s;
@@ -195,80 +179,35 @@ BEGIN
     RETURN TRUE;
 END;
 
-PROCEDURE Term.type(): Types.PType;
-VAR
-    result: Types.PType;
-BEGIN
-    IF SELF.expression # NIL THEN
-        result := SELF.expression.type();
-    ELSE
-        result := SELF.attributes.designator.type();
-    END;
-    RETURN result;
-END;
-
-PROCEDURE Term.handleOperator(op: ExpressionTree.BinaryOperator);
-BEGIN
-    ExpressionTree.notTypeId(SELF.expression);
-    SELF.operator := op;
-END;
+PROCEDURE Term.Term(parent: ContextHierarchy.PNode)
+    | SUPER(parent),
+      list(NEW ExpressionTree.TermList());
+END; 
 
 PROCEDURE Term.handleExpression(e: Expression.PType);
 BEGIN
-    promoteExpressionType(SELF.root()^, SELF.expression, e);
-    IF SELF.operator = NIL THEN
-        SELF.expression := e;
-    ELSIF SELF.expression # NIL THEN
-        ExpressionTree.notTypeId(e);
-        SELF.expression := SELF.operator(SELF.expression, e);
-    END;
+    SELF.list.addExpression(e);
 END;
 
 PROCEDURE Term.endParse(): BOOLEAN;
 VAR
     const: ConstValue.PType;
 BEGIN
-    e <- SELF.expression;
-    IF e = NIL THEN
+    IF SELF.list.expression = NIL THEN
         d <- SELF.attributes.designator;
         info <- d.info();
         IF info IS Types.PConst THEN
             const := info.value;
         END;
-        e := Expression.make(d.code(), d.type(), d, const);
+        SELF.list.addExpression(Expression.make(d.code(), d.type(), d, const));
     END;
-    SELF.parent()(PSimpleExpression).handleExpression(e);
+    SELF.parent()(PSimpleExpression).list.addTerm(SELF.list);
     RETURN TRUE;
 END;
 
 PROCEDURE MulOperator.handleLiteral(s: STRING);
-VAR
-    o: ExpressionTree.BinaryOperator;
 BEGIN
-    parent <- SELF.parent()(PTerm);
-    type <- parent.type();
-    IF s = "*" THEN
-        o := ExpressionTree.assertNumericOrSetOp(type, s, Operator.mulReal, Operator.mulInt, Operator.setIntersection);
-    ELSIF s = "/" THEN
-        IF Types.isInt(type) THEN
-            Errors.raise("operator DIV expected for integer division");
-        END;
-        o := ExpressionTree.assertNumericOrSetOp(type, s, Operator.divReal, NIL, Operator.setSymmetricDiff);
-    ELSIF s = "DIV" THEN
-        o := assertIntOp(type, s, Operator.divInt);
-    ELSIF s = "MOD" THEN
-        o := assertIntOp(type, s, Operator.mod);
-    ELSIF s = "&" THEN
-        IF type # Types.basic.bool THEN
-            Errors.raise("BOOLEAN expected as operand of '&', got '"
-                                 + type.description() + "'");
-        END;
-        o := Operator.and;
-    ELSE
-        ASSERT(FALSE);
-    END;
-
-    parent.handleOperator(o);
+    SELF.parent()^(Term).list.addOp(s);
 END;
 
 PROCEDURE AddOperator.handleLiteral(s: STRING);

+ 107 - 24
src/ob/ExpressionTree.ob

@@ -27,9 +27,29 @@ TYPE
     END;
     POps* = POINTER TO Ops;
 
+    PTermItemOp = POINTER TO TermItemOp;
+    TermItem* = RECORD
+        expression-: Expression.PType;
+        next: PTermItemOp;
+    END;
+
+    TermItemOp = RECORD (TermItem)
+        PROCEDURE TermItemOp(op: STRING);
+
+        op: STRING;
+    END;
+
+    TermList* = RECORD (TermItem)
+        PROCEDURE addExpression*(e: Expression.PType);
+        PROCEDURE addOp*(op: STRING);
+
+        last: PTermItemOp;
+    END;
+    PTermList* = POINTER TO TermList;
+
     PSimpleItemOp = POINTER TO SimpleItemOp;
     SimpleItem = RECORD
-        expression: Expression.PType;
+        term: PTermList;
         next: PSimpleItemOp;
     END;
 
@@ -40,7 +60,7 @@ TYPE
     END;
 
     SimpleList* = RECORD (SimpleItem)
-        PROCEDURE addExpression*(e: Expression.PType);
+        PROCEDURE addTerm*(t: PTermList);
         PROCEDURE addOp*(op: STRING);
 
         unaryOp*: STRING;
@@ -87,6 +107,7 @@ TYPE
     END;
 
 VAR
+    intOpTypeCheck: IntOpTypeCheck;
     numericOpTypeCheck: NumericOpTypeCheck;
     numericOrSetOpTypeCheck: NumericOrSetOpTypeCheck;
 
@@ -241,14 +262,20 @@ PROCEDURE useIntEqOp(t: Types.PType): BOOLEAN;
         OR (t = Types.nil);
 END;
 
-PROCEDURE assertOpType*(type: Types.PType; check: OpTypeCheck; literal: STRING);
+PROCEDURE assertOpType(type: Types.PType; check: OpTypeCheck; literal: STRING);
 BEGIN
     IF ~check.check(type) THEN
         throwOperatorTypeMismatch(literal, check.expect(), type);
     END;
 END;
 
-PROCEDURE assertNumericOrSetOp*(type: Types.PType; literal: STRING; op: BinaryOperator; intOp, setOp: BinaryOperator): BinaryOperator;
+PROCEDURE assertIntOp(type: Types.PType; literal: STRING; op: BinaryOperator): BinaryOperator;
+BEGIN
+    assertOpType(type, intOpTypeCheck, literal);
+    RETURN op;
+END;
+
+PROCEDURE assertNumericOrSetOp(type: Types.PType; literal: STRING; op: BinaryOperator; intOp, setOp: BinaryOperator): BinaryOperator;
 VAR
     result: BinaryOperator;
 BEGIN
@@ -262,20 +289,7 @@ BEGIN
     END;
     RETURN result;
 END;
-(*
-PROCEDURE assertNumericOp*(type: Types.PType; literal: STRING; op, intOp: ExpressionTree.BinaryOperator): ExpressionTree.BinaryOperator;
-VAR
-    result: ExpressionTree.BinaryOperator;
-BEGIN
-    assertOpType(type, numericOpTypeCheck, literal);
-    IF (intOp # NIL) & Types.isInt(type) THEN
-        result := intOp;
-    ELSE
-        result := op;
-    END;
-    RETURN result;
-END;
-*)
+
 PROCEDURE notTypeId*(e: Expression.PType);
 BEGIN
     d <- e.designator();
@@ -358,11 +372,56 @@ BEGIN
     RETURN o;
 END;
 
-PROCEDURE makeFirstFromSimpleList(list: SimpleList): Expression.PType;
+PROCEDURE mulOp(s: STRING; type: Types.PType): BinaryOperator;
+VAR
+    o: BinaryOperator;
+BEGIN
+    IF s = "*" THEN
+        o := assertNumericOrSetOp(type, s, Operator.mulReal, Operator.mulInt, Operator.setIntersection);
+    ELSIF s = "/" THEN
+        IF Types.isInt(type) THEN
+            Errors.raise("operator DIV expected for integer division");
+        END;
+        o := assertNumericOrSetOp(type, s, Operator.divReal, NIL, Operator.setSymmetricDiff);
+    ELSIF s = "DIV" THEN
+        o := assertIntOp(type, s, Operator.divInt);
+    ELSIF s = "MOD" THEN
+        o := assertIntOp(type, s, Operator.mod);
+    ELSIF s = "&" THEN
+        IF type # Types.basic.bool THEN
+            Errors.raise("BOOLEAN expected as operand of '&', got '"
+                                 + type.description() + "'");
+        END;
+        o := Operator.and;
+    ELSE
+        ASSERT(FALSE);
+    END;
+    RETURN o;
+END;
+
+PROCEDURE makeFromTermList(list: TermList; root: ContextHierarchy.Root): Expression.PType;
+BEGIN
+	result <- list.expression;
+	next <- list.next;
+	WHILE next # NIL DO
+        notTypeId(result);
+		e <- next.expression;
+        notTypeId(e);
+        type <- result.type();
+        o <- mulOp(next.op, type);
+		checkImplicitCast(root, e.type(), type);
+		result := o(result, e); 
+
+        next := next.next;
+	END;
+	RETURN result;
+END;
+
+PROCEDURE makeFirstFromSimpleList(list: SimpleList; root: ContextHierarchy.Root): Expression.PType;
 VAR
     o: PROCEDURE(e: Expression.PType): Expression.PType;
 BEGIN
-    result <- list.expression;
+    result <- makeFromTermList(list.term^, root);
     IF list.unaryOp = "-" THEN
         type <- result.type();
         IF Types.isInt(type) THEN
@@ -405,11 +464,11 @@ END;
 
 PROCEDURE makeFromSimpleList(list: SimpleList; ops: Ops; cx: ContextHierarchy.Root): Expression.PType;
 BEGIN
-    result <- makeFirstFromSimpleList(list);
+    result <- makeFirstFromSimpleList(list, cx);
     next <- list.next;
     WHILE next # NIL DO
         notTypeId(result);
-        e <- next.expression;
+        e <- makeFromTermList(next.term^, cx);
         notTypeId(e);
         o <- matchAddOperator(ops, next.op, result.type());
         checkImplicitCast(cx, e.type(), result.type());
@@ -624,7 +683,7 @@ PROCEDURE Ops.plusExpect(): STRING;
     RETURN "numeric type or SET";
 END;
 
-PROCEDURE ItemOp.ItemOp(op: STRING)
+PROCEDURE TermItemOp.TermItemOp(op: STRING)
     | op(op);
 END;
 
@@ -632,7 +691,11 @@ PROCEDURE SimpleItemOp.SimpleItemOp(op: STRING)
     | op(op);
 END;
 
-PROCEDURE SimpleList.addExpression(e: Expression.PType);
+PROCEDURE ItemOp.ItemOp(op: STRING)
+    | op(op);
+END;
+
+PROCEDURE TermList.addExpression(e: Expression.PType);
 BEGIN
     IF SELF.expression = NIL THEN
         SELF.expression := e;
@@ -641,6 +704,26 @@ BEGIN
     END;
 END;
 
+PROCEDURE TermList.addOp(op: STRING);
+BEGIN
+    next <- NEW TermItemOp(op);
+    IF SELF.last = NIL THEN
+        SELF.next := next;
+    ELSE
+        SELF.last.next := next;
+    END;
+    SELF.last := next;
+END;
+
+PROCEDURE SimpleList.addTerm(t: PTermList);
+BEGIN
+    IF SELF.term = NIL THEN
+        SELF.term := t;
+    ELSE
+        SELF.last.term := t;
+    END;
+END;
+
 PROCEDURE SimpleList.addOp(op: STRING);
 BEGIN
     next <- NEW SimpleItemOp(op);