You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@corinthia.apache.org by pm...@apache.org on 2015/08/31 14:19:35 UTC

incubator-corinthia git commit: Flat: Option to print expressions as trees

Repository: incubator-corinthia
Updated Branches:
  refs/heads/master f1b74ba8e -> b35496cf7


Flat: Option to print expressions as trees

When printing out a grammar definition, add the ability to show the body
of each rule as an expression tree, with one node per line. This makes
it easier to understand the structure of a grammar. In the future, it
will also be useful for displaying information associated with each
node, such as when we implement type inference.

As an example, the following rule in the existing concrete format:

    Term    : $Add(Factor PLUS Term)
            | $Sub(Factor MINUS Term)
            | Factor;

look as follows when printed with the -e (or --exprtree) option:

    Term

        Choice
        |-- Label "Add"
        |   \-- Sequence
        |       |-- Ident "Factor"
        |       |-- Ident "PLUS"
        |       \-- Ident "Term"
        |-- Label "Sub"
        |   \-- Sequence
        |       |-- Ident "Factor"
        |       |-- Ident "MINUS"
        |       \-- Ident "Term"
        \-- Ident "Factor"


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

Branch: refs/heads/master
Commit: b35496cf73a8c79fc49a35d9b7ebbfa241dd455c
Parents: f1b74ba
Author: Peter Kelly <pe...@uxproductivity.com>
Authored: Mon Aug 31 19:15:23 2015 +0700
Committer: Peter Kelly <pe...@uxproductivity.com>
Committed: Mon Aug 31 19:15:23 2015 +0700

----------------------------------------------------------------------
 experiments/flat/src/Expression.c | 46 ++++++++++++++++++++++++++++++++++
 experiments/flat/src/Expression.h |  1 +
 experiments/flat/src/Grammar.c    | 23 ++++++++++++-----
 experiments/flat/src/Grammar.h    |  2 +-
 experiments/flat/src/Util.c       | 32 ++++++++++++-----------
 experiments/flat/src/Util.h       |  4 +--
 experiments/flat/src/flat.c       |  6 ++++-
 7 files changed, 90 insertions(+), 24 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/b35496cf/experiments/flat/src/Expression.c
----------------------------------------------------------------------
diff --git a/experiments/flat/src/Expression.c b/experiments/flat/src/Expression.c
index 9af0d2c..d3b1778 100644
--- a/experiments/flat/src/Expression.c
+++ b/experiments/flat/src/Expression.c
@@ -354,6 +354,52 @@ void ExpressionPrint(Expression *expr, int highestPrecedence, const char *indent
         printf(")");
 }
 
+void ExpressionPrintTree(Expression *expr, const char *indent, int startCol)
+{
+    int col = startCol;
+    if (ExpressionKind(expr) == IdentExpr) {
+        col += printf("%s \"%s\"",ExprKindAsString(ExpressionKind(expr)),ExprIdentValue(expr));
+    }
+    else if (ExpressionKind(expr) == LabelExpr) {
+        col += printf("%s \"%s\"",ExprKindAsString(ExpressionKind(expr)),ExprLabelIdent(expr));
+    }
+    else if (ExpressionKind(expr) == LitExpr) {
+        col += printf("%s ",ExprKindAsString(ExpressionKind(expr)));
+        col += printLiteral(ExprLitValue(expr));
+    }
+    else {
+        col += printf("%s",ExprKindAsString(ExpressionKind(expr)));
+    }
+
+    // col is not currently used, but exists currently in anticipation of needing to display
+    // type information about each node in the tree on the right side of the output
+
+    printf("\n");
+
+    if (ExpressionKind(expr) == IdentExpr)
+        return;
+
+    int indentLen = strlen(indent);
+    char *nextIndent = (char *)malloc(indentLen+5);
+
+    int count = ExpressionCount(expr);
+    for (int i = 0; i < count; i++) {
+        Expression *child = ExpressionChildAt(expr,i);
+        if (i+1 < count) {
+            printf("%s|-- ",indent);
+            snprintf(nextIndent,indentLen+5,"%s|   ",indent);
+            ExpressionPrintTree(child,nextIndent,startCol+4);
+        }
+        else {
+            printf("%s\\-- ",indent);
+            snprintf(nextIndent,indentLen+5,"%s    ",indent);
+            ExpressionPrintTree(child,nextIndent,startCol+4);
+        }
+    }
+
+    free(nextIndent);
+}
+
 ExprKind ExpressionKind(Expression *expr)
 {
     return expr->kind;

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/b35496cf/experiments/flat/src/Expression.h
----------------------------------------------------------------------
diff --git a/experiments/flat/src/Expression.h b/experiments/flat/src/Expression.h
index 3d81460..9c26543 100644
--- a/experiments/flat/src/Expression.h
+++ b/experiments/flat/src/Expression.h
@@ -120,6 +120,7 @@ Expression *ExpressionNewString(Expression *child);
 Expression *ExpressionNewLabel(const char *label, Expression *child);
 void ExpressionFree(Expression *expr);
 void ExpressionPrint(Expression *expr, int highestPrecedence, const char *indent);
+void ExpressionPrintTree(Expression *expr, const char *indent, int startCol);
 
 ExprKind ExpressionKind(Expression *expr);
 int ExpressionCount(Expression *expr);

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/b35496cf/experiments/flat/src/Grammar.c
----------------------------------------------------------------------
diff --git a/experiments/flat/src/Grammar.c b/experiments/flat/src/Grammar.c
index 6743953..5cba326 100644
--- a/experiments/flat/src/Grammar.c
+++ b/experiments/flat/src/Grammar.c
@@ -106,7 +106,7 @@ void GrammarResolve(Grammar *gram)
         GrammarResolveRecursive(gram,def->expr,def->name);
 }
 
-void GrammarPrint(Grammar *gram)
+void GrammarPrint(Grammar *gram, int exprAsTree)
 {
     int maxNameLen = 0;
     for (Rule *def = gram->defList; def != NULL; def = def->next) {
@@ -122,11 +122,22 @@ void GrammarPrint(Grammar *gram)
     for (Rule *def = gram->defList; def != NULL; def = def->next) {
         int nameLen = strlen(def->name);
         printf("%s",def->name);
-        for (int i = nameLen; i < maxNameLen+1; i++)
-            printf(" ");
-        printf(": ");
-        ExpressionPrint(def->expr,0,prefix);
-        printf(";\n");
+        if (exprAsTree) {
+            // Print the expression in tree format, with one line per node
+            printf("\n");
+            printf("\n");
+            printf("    ");
+            ExpressionPrintTree(def->expr,"    ",4);
+            printf("\n");
+        }
+        else {
+            // Print the expression in compact format, with one line per alternative
+            for (int i = nameLen; i < maxNameLen+1; i++)
+                printf(" ");
+            printf(": ");
+            ExpressionPrint(def->expr,0,prefix);
+            printf(";\n");
+        }
     }
 
     free(prefix);

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/b35496cf/experiments/flat/src/Grammar.h
----------------------------------------------------------------------
diff --git a/experiments/flat/src/Grammar.h b/experiments/flat/src/Grammar.h
index f51bd18..d0cd067 100644
--- a/experiments/flat/src/Grammar.h
+++ b/experiments/flat/src/Grammar.h
@@ -27,5 +27,5 @@ void GrammarFree(Grammar *gram);
 void GrammarDefine(Grammar *gram, const char *name, Expression *expr);
 Expression *GrammarLookup(Grammar *gram, const char *name);
 void GrammarResolve(Grammar *gram);
-void GrammarPrint(Grammar *gram);
+void GrammarPrint(Grammar *gram, int exprAsTree);
 const char *GrammarFirstRuleName(Grammar *gram);

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/b35496cf/experiments/flat/src/Util.c
----------------------------------------------------------------------
diff --git a/experiments/flat/src/Util.c b/experiments/flat/src/Util.c
index 5c53057..066aee7 100644
--- a/experiments/flat/src/Util.c
+++ b/experiments/flat/src/Util.c
@@ -77,47 +77,51 @@ uint32_t UTF8NextChar(const char *str, size_t *offsetp)
     }
 }
 
-void printEscapedRangeChar(char c)
+int printEscapedRangeChar(char c)
 {
+    int chars = 0;
     switch (c) {
         case '[':
-            printf("\\[");
+            chars += printf("\\[");
             break;
         case ']':
-            printf("\\]");
+            chars += printf("\\]");
             break;
         case '\\':
-            printf("\\\\");
+            chars += printf("\\\\");
             break;
         default:
-            printf("%c",c);
+            chars += printf("%c",c);
             break;
     }
+    return chars;
 }
 
-void printLiteral(const char *value)
+int printLiteral(const char *value)
 {
-    printf("\"");
+    int chars = 0;
+    chars += printf("\"");
     for (int i = 0; value[i] != '\0'; i++) {
         switch (value[i]) {
             case '\r':
-                printf("\\r");
+                chars += printf("\\r");
                 break;
             case '\n':
-                printf("\\n");
+                chars += printf("\\n");
                 break;
             case '\t':
-                printf("\\t");
+                chars += printf("\\t");
                 break;
             case '\"':
-                printf("\\\"");
+                chars += printf("\\\"");
                 break;
             case '\\':
-                printf("\\\\");
+                chars += printf("\\\\");
                 break;
             default:
-                printf("%c",value[i]);
+                chars += printf("%c",value[i]);
         }
     }
-    printf("\"");
+    chars += printf("\"");
+    return chars;
 }

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/b35496cf/experiments/flat/src/Util.h
----------------------------------------------------------------------
diff --git a/experiments/flat/src/Util.h b/experiments/flat/src/Util.h
index 2fc9c6b..98f18e7 100644
--- a/experiments/flat/src/Util.h
+++ b/experiments/flat/src/Util.h
@@ -21,5 +21,5 @@
 #include <stdint.h>
 
 uint32_t UTF8NextChar(const char *str, size_t *offsetp);
-void printEscapedRangeChar(char c);
-void printLiteral(const char *value);
+int printEscapedRangeChar(char c);
+int printLiteral(const char *value);

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/b35496cf/experiments/flat/src/flat.c
----------------------------------------------------------------------
diff --git a/experiments/flat/src/flat.c b/experiments/flat/src/flat.c
index 49a9846..a29f771 100644
--- a/experiments/flat/src/flat.c
+++ b/experiments/flat/src/flat.c
@@ -62,6 +62,7 @@ void usage(void)
            "Options:\n"
            "\n"
            "  -b, --builtin   Use the built-in grammar instead of a user-supplied one\n"
+           "  -e, --exprtree  Print expressions as trees (only relevant if -g also given)\n"
            "  -g, --grammar   Don't parse input; just show the grammar that would be used\n"
            "  -h, --help      Print this message\n"
            "\n"
@@ -101,6 +102,7 @@ int main(int argc, const char **argv)
     char *inputStr = NULL;
     int useBuiltinGrammar = 0;
     int showGrammar = 0;
+    int exprAsTree = 0;
     Grammar *builtGrammar = NULL;
     Term *inputTerm = NULL;
 
@@ -109,6 +111,8 @@ int main(int argc, const char **argv)
             useBuiltinGrammar = 1;
         else if (!strcmp(argv[i],"-g") || !strcmp(argv[i],"--grammar"))
             showGrammar = 1;
+        else if (!strcmp(argv[i],"-e") || !strcmp(argv[i],"--exprtree"))
+            exprAsTree = 1;
         else if (!strcmp(argv[i],"-h") || !strcmp(argv[i],"--help"))
             usage();
         else if ((strlen(argv[i]) > 1) && argv[i][0] == '-')
@@ -153,7 +157,7 @@ int main(int argc, const char **argv)
     }
 
     if (showGrammar) {
-        GrammarPrint(useGrammar);
+        GrammarPrint(useGrammar,exprAsTree);
     }
     else if (inputTerm != NULL) {
         TermPrint(inputTerm,inputStr,"");