corinthia-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From pmke...@apache.org
Subject incubator-corinthia git commit: Flat: Label expressions
Date Sat, 08 Aug 2015 17:40:39 GMT
Repository: incubator-corinthia
Updated Branches:
  refs/heads/master 02c9f1d8a -> 305e9e792


Flat: Label expressions

Add a new expression type, Label, which associated an identifier with
parse tree nodes created from a particular portion of the grammar. This
is useful when you have multiple alternatives in a rule that you want to
distinguish by name, e.g.:

    Term    : $Add(Factor PLUS Term)
            | $Sub(Factor MINUS Term)
            | Factor;
    Factor  : $Mul(Primary TIMES Factor)
            | $Div(Primary SLASH Factor)
            | Primary;

A label expression is written as $SomeLabel(...); it does not affect the
set of possible input strings affected by the parser, but simply
instructs it to create an extra node in the parse tree with the label
"SomeLabel". In the above example, taken from arithmetic.flat, each type
of expression is labeled with the appropriate constructor.

The parse trees we've created so far have all contained lots of nodes,
particularly for intermediate expressions like rule references, choices,
sequences, optional types, and lists. With explicit labels/constructors
as above, we are now part way to being able to construct simpler parse
trees which only store the semantically-important information in the
abstract syntax tree.


Project: http://git-wip-us.apache.org/repos/asf/incubator-corinthia/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-corinthia/commit/305e9e79
Tree: http://git-wip-us.apache.org/repos/asf/incubator-corinthia/tree/305e9e79
Diff: http://git-wip-us.apache.org/repos/asf/incubator-corinthia/diff/305e9e79

Branch: refs/heads/master
Commit: 305e9e7924013714fd1875aadc52350b50bd5548
Parents: 02c9f1d
Author: Peter Kelly <peter@uxproductivity.com>
Authored: Sun Aug 9 00:36:25 2015 +0700
Committer: Peter Kelly <peter@uxproductivity.com>
Committed: Sun Aug 9 00:36:25 2015 +0700

----------------------------------------------------------------------
 experiments/flat/grammars/arithmetic.flat | 12 ++++----
 experiments/flat/grammars/flat.flat       |  1 +
 experiments/flat/src/BuildGrammar.c       | 16 +++++++++--
 experiments/flat/src/Builtin.c            |  2 ++
 experiments/flat/src/Builtin.h            |  1 +
 experiments/flat/src/Expression.c         | 40 ++++++++++++++++++++++++++
 experiments/flat/src/Expression.h         | 15 ++++++++++
 experiments/flat/src/Parser.c             |  6 ++++
 experiments/flat/src/Term.c               |  3 ++
 9 files changed, 87 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/305e9e79/experiments/flat/grammars/arithmetic.flat
----------------------------------------------------------------------
diff --git a/experiments/flat/grammars/arithmetic.flat b/experiments/flat/grammars/arithmetic.flat
index 46e2e5d..6f9c1e1 100644
--- a/experiments/flat/grammars/arithmetic.flat
+++ b/experiments/flat/grammars/arithmetic.flat
@@ -2,14 +2,14 @@
 # supposed to be left recursive, but we don't support that yet.
 Start   : Expr !.;
 Expr    : Term;
-Term    : Factor PLUS Term
-        | Factor MINUS Term
+Term    : $Add(Factor PLUS Term)
+        | $Sub(Factor MINUS Term)
         | Factor;
-Factor  : Primary TIMES Factor
-        | Primary SLASH Factor
+Factor  : $Mul(Primary TIMES Factor)
+        | $Div(Primary SLASH Factor)
         | Primary;
-Primary : ID
-        | INT
+Primary : $Ident(ID)
+        | $Integer(INT)
         | OPEN Expr CLOSE;
 PLUS    : "+" Spacing;
 MINUS   : "-" Spacing;

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/305e9e79/experiments/flat/grammars/flat.flat
----------------------------------------------------------------------
diff --git a/experiments/flat/grammars/flat.flat b/experiments/flat/grammars/flat.flat
index bf6e794..4fe4293 100644
--- a/experiments/flat/grammars/flat.flat
+++ b/experiments/flat/grammars/flat.flat
@@ -6,6 +6,7 @@ Prefix     : (AND | NOT)? Suffix;
 Suffix     : Primary (QUESTION | STAR | PLUS)?;
 Primary    : Identifier !COLON
            | DOLLAR OPEN Expression CLOSE
+           | DOLLAR Identifier OPEN Expression CLOSE
            | OPEN Expression CLOSE
            | Literal
            | Class

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/305e9e79/experiments/flat/src/BuildGrammar.c
----------------------------------------------------------------------
diff --git a/experiments/flat/src/BuildGrammar.c b/experiments/flat/src/BuildGrammar.c
index ea546e3..b34a7aa 100644
--- a/experiments/flat/src/BuildGrammar.c
+++ b/experiments/flat/src/BuildGrammar.c
@@ -303,15 +303,25 @@ static Expression *buildPrimary(Builder *builder, Term *term)
             return ExpressionNewString(result);
         }
         case 2: {
+            assert(isSequence(choice,5));
+            Term *ident = TermChildAt(choice,1);
+            char *label = identifierString(builder,ident);
+            Term *expression = TermChildAt(choice,3);
+            Expression *result = buildExpression(builder,expression);
+            result = ExpressionNewLabel(label,result);
+            free(label);
+            return result;
+        }
+        case 3: {
             assert(isSequence(choice,3));
             Term *expression = TermChildAt(choice,1);
             return buildExpression(builder,expression);
         }
-        case 3:
-            return buildLiteral(builder,choice);
         case 4:
-            return buildClass(builder,choice);
+            return buildLiteral(builder,choice);
         case 5:
+            return buildClass(builder,choice);
+        case 6:
             return buildDot(builder,choice);
         default:
             assert(!"Invalid choice for Primary");

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/305e9e79/experiments/flat/src/Builtin.c
----------------------------------------------------------------------
diff --git a/experiments/flat/src/Builtin.c b/experiments/flat/src/Builtin.c
index ce060cb..291272b 100644
--- a/experiments/flat/src/Builtin.c
+++ b/experiments/flat/src/Builtin.c
@@ -88,6 +88,7 @@ Grammar *GrammarNewBuiltin(void)
 
     // Primary : Identifier !COLON
     //         | DOLLAR OPEN Expression CLOSE
+    //         | DOLLAR Identifier OPEN Expression CLOSE
     //         | OPEN Expression CLOSE
     //         | Literal
     //         | Class
@@ -95,6 +96,7 @@ Grammar *GrammarNewBuiltin(void)
     GrammarDefine(gram,"Primary",
                   choice(seq(ref("Identifier"),not(ref("COLON"))),
                          seq(ref("DOLLAR"),ref("OPEN"),ref("Expression"),ref("CLOSE")),
+                         seq(ref("DOLLAR"),ref("Identifier"),ref("OPEN"),ref("Expression"),ref("CLOSE")),
                          seq(ref("OPEN"),ref("Expression"),ref("CLOSE")),
                          ref("Literal"),
                          ref("Class"),

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/305e9e79/experiments/flat/src/Builtin.h
----------------------------------------------------------------------
diff --git a/experiments/flat/src/Builtin.h b/experiments/flat/src/Builtin.h
index 76d3f38..14a2f71 100644
--- a/experiments/flat/src/Builtin.h
+++ b/experiments/flat/src/Builtin.h
@@ -31,6 +31,7 @@
  *     Suffix     : Primary (QUESTION | STAR | PLUS)?;
  *     Primary    : Identifier !COLON
  *                | DOLLAR OPEN Expression CLOSE
+ *                | DOLLAR Identifier OPEN Expression CLOSE
  *                | OPEN Expression CLOSE
  *                | Literal
  *                | Class

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/305e9e79/experiments/flat/src/Expression.c
----------------------------------------------------------------------
diff --git a/experiments/flat/src/Expression.c b/experiments/flat/src/Expression.c
index ad2fc2e..9af0d2c 100644
--- a/experiments/flat/src/Expression.c
+++ b/experiments/flat/src/Expression.c
@@ -61,6 +61,8 @@ const char *ExprKindAsString(ExprKind kind)
             return "Range";
         case StringExpr:
             return "String";
+        case LabelExpr:
+            return "Label";
     }
     return "?";
 }
@@ -197,6 +199,17 @@ Expression *ExpressionNewString(Expression *child)
     return expr;
 }
 
+Expression *ExpressionNewLabel(const char *label, Expression *child)
+{
+    assert(child != NULL);
+    Expression *expr = (Expression *)calloc(1,sizeof(Expression)+1*sizeof(Expression *));
+    expr->kind = LabelExpr;
+    expr->value = strdup(label);
+    expr->count = 1;
+    expr->children[0] = child;
+    return expr;
+}
+
 void ExpressionFree(Expression *expr)
 {
     if (expr == NULL)
@@ -232,6 +245,7 @@ static int ExprKindPrecedence(ExprKind kind)
         case DotExpr:
             return 5;
         case StringExpr:
+        case LabelExpr:
             return 6;
         case RangeExpr:
             return 7;
@@ -329,6 +343,12 @@ void ExpressionPrint(Expression *expr, int highestPrecedence, const char
*indent
             ExpressionPrint(ExprStringChild(expr),highestPrecedence,NULL);
             printf(")");
             break;
+        case LabelExpr:
+            printf("$%s(",ExprLabelIdent(expr));
+            highestPrecedence = 1; // because of brackets
+            ExpressionPrint(ExprLabelChild(expr),highestPrecedence,NULL);
+            printf(")");
+            break;
     }
     if (brackets)
         printf(")");
@@ -494,3 +514,23 @@ Expression *ExprStringChild(Expression *expr)
     assert(expr->children[0] != NULL);
     return expr->children[0];
 }
+
+// Label
+
+const char *ExprLabelIdent(Expression *expr)
+{
+    assert(expr->kind == LabelExpr);
+    assert(expr->count == 1);
+    assert(expr->value != NULL);
+    assert(expr->children[0] != NULL);
+    return expr->value;
+}
+
+Expression *ExprLabelChild(Expression *expr)
+{
+    assert(expr->kind == LabelExpr);
+    assert(expr->count == 1);
+    assert(expr->value != NULL);
+    assert(expr->children[0] != NULL);
+    return expr->children[0];
+}

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/305e9e79/experiments/flat/src/Expression.h
----------------------------------------------------------------------
diff --git a/experiments/flat/src/Expression.h b/experiments/flat/src/Expression.h
index 1058be0..3d81460 100644
--- a/experiments/flat/src/Expression.h
+++ b/experiments/flat/src/Expression.h
@@ -73,6 +73,14 @@
  * StringExpr - Instructs the parser to construct a single node in the parse tree representing
  * everything within the child expression. Doesn't have any effect on what is or isn't accepted
  * by the parser.
+ *
+ * LabelExpr - Instructs the parser to construct a label node in the parse tree, indicating
+ * semantically important information. Many nodes in the parse tree are there simply because
+ * they formed part of the call tree used during parsing, but do not necessarily have any
+ * use for subsequent analysis of the tree. Label expressions are intended to, in the future,
+ * allow us to have simpler trees which only contain the information necessary for analysing
+ * a syntax tree. Like String expressions, Label expressions do not have any effect on what
is or
+ * isn't accepted by the parser.
  */
 
 typedef enum {
@@ -89,6 +97,7 @@ typedef enum {
     DotExpr,
     RangeExpr,
     StringExpr,
+    LabelExpr,
 } ExprKind;
 
 typedef struct Expression Expression;
@@ -108,6 +117,7 @@ Expression *ExpressionNewClass(int count, Expression **children);
 Expression *ExpressionNewDot(void);
 Expression *ExpressionNewRange(int lo, int hi);
 Expression *ExpressionNewString(Expression *child);
+Expression *ExpressionNewLabel(const char *label, Expression *child);
 void ExpressionFree(Expression *expr);
 void ExpressionPrint(Expression *expr, int highestPrecedence, const char *indent);
 
@@ -153,3 +163,8 @@ int ExprRangeEnd(Expression *expr);
 // String
 
 Expression *ExprStringChild(Expression *expr);
+
+// Label
+
+const char *ExprLabelIdent(Expression *expr);
+Expression *ExprLabelChild(Expression *expr);

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/305e9e79/experiments/flat/src/Parser.c
----------------------------------------------------------------------
diff --git a/experiments/flat/src/Parser.c b/experiments/flat/src/Parser.c
index 74c1e28..5c76a1a 100644
--- a/experiments/flat/src/Parser.c
+++ b/experiments/flat/src/Parser.c
@@ -212,6 +212,12 @@ static Term *parseExpr(Parser *p, Expression *expr)
             // (which can be recovered from the input, and the start and end fields of the
term).
             return TermNew(expr,startPos,p->pos,NULL);
         }
+        case LabelExpr: {
+            Term *term = parseExpr(p,ExprLabelChild(expr));
+            if (term == NULL)
+                return NULL;
+            return TermNew(expr,startPos,p->pos,TermListNew(term,NULL));
+        }
     }
     assert(!"unknown expression type");
     return NULL;

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/305e9e79/experiments/flat/src/Term.c
----------------------------------------------------------------------
diff --git a/experiments/flat/src/Term.c b/experiments/flat/src/Term.c
index e3fc44b..f0369eb 100644
--- a/experiments/flat/src/Term.c
+++ b/experiments/flat/src/Term.c
@@ -105,6 +105,9 @@ void TermPrint(Term *term, const char *input, const char *indent)
         case IdentExpr:
             printf("%s %s\n",ExprKindAsString(ExpressionKind(term->type)),ExprIdentValue(term->type));
             break;
+        case LabelExpr:
+            printf("%s %s\n",ExprKindAsString(ExpressionKind(term->type)),ExprLabelIdent(term->type));
+            break;
         case LitExpr:
         case RangeExpr:
         case DotExpr:


Mime
View raw message