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/08 19:01:45 UTC
incubator-corinthia git commit: Flat: Support parsing using custom
grammars
Repository: incubator-corinthia
Updated Branches:
refs/heads/master 79101d29e -> 02c9f1d8a
Flat: Support parsing using custom grammars
Add the ability to use the flat command-line tool to specify both a
grammar file and an input which should be parsed using that grammar.
After a successful parse, the parse tree is printed to standard output.
This is what makes Flat a parser *interpreter*, rather than a parser
*generator*. There is no need for the an intermediate step of compiling
generated files as with many other parsing tools like Bison/Flex, ANTLR,
JavaCC, or Stratego/XT. We can (and probably will) choose to add code
generation as an optional feature later on, but it's not a fundamental
requirement.
Project: http://git-wip-us.apache.org/repos/asf/incubator-corinthia/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-corinthia/commit/02c9f1d8
Tree: http://git-wip-us.apache.org/repos/asf/incubator-corinthia/tree/02c9f1d8
Diff: http://git-wip-us.apache.org/repos/asf/incubator-corinthia/diff/02c9f1d8
Branch: refs/heads/master
Commit: 02c9f1d8a0123cee8b5e6ca16b1d51e830ba7dc4
Parents: 79101d2
Author: Peter Kelly <pe...@uxproductivity.com>
Authored: Sat Aug 8 23:53:23 2015 +0700
Committer: Peter Kelly <pe...@uxproductivity.com>
Committed: Sat Aug 8 23:53:23 2015 +0700
----------------------------------------------------------------------
experiments/flat/grammars/arithmetic.flat | 22 +++++++++
experiments/flat/src/BuildGrammar.c | 2 +
experiments/flat/src/Grammar.c | 8 ++++
experiments/flat/src/Grammar.h | 1 +
experiments/flat/src/flat.c | 62 +++++++++++++++++++-------
5 files changed, 80 insertions(+), 15 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/02c9f1d8/experiments/flat/grammars/arithmetic.flat
----------------------------------------------------------------------
diff --git a/experiments/flat/grammars/arithmetic.flat b/experiments/flat/grammars/arithmetic.flat
new file mode 100644
index 0000000..46e2e5d
--- /dev/null
+++ b/experiments/flat/grammars/arithmetic.flat
@@ -0,0 +1,22 @@
+# Note: The Term and Factor rules are right recursive. They are actually
+# supposed to be left recursive, but we don't support that yet.
+Start : Expr !.;
+Expr : Term;
+Term : Factor PLUS Term
+ | Factor MINUS Term
+ | Factor;
+Factor : Primary TIMES Factor
+ | Primary SLASH Factor
+ | Primary;
+Primary : ID
+ | INT
+ | OPEN Expr CLOSE;
+PLUS : "+" Spacing;
+MINUS : "-" Spacing;
+TIMES : "*" Spacing;
+SLASH : "/" Spacing;
+OPEN : "(" Spacing;
+CLOSE : ")" Spacing;
+ID : $([a-zA-Z_] [a-zA-Z_0-9]*) Spacing;
+INT : $([1-9] [0-9]*) Spacing;
+Spacing : $((" " | "\t" | "\r" | "\n")*);
http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/02c9f1d8/experiments/flat/src/BuildGrammar.c
----------------------------------------------------------------------
diff --git a/experiments/flat/src/BuildGrammar.c b/experiments/flat/src/BuildGrammar.c
index 7425878..ea546e3 100644
--- a/experiments/flat/src/BuildGrammar.c
+++ b/experiments/flat/src/BuildGrammar.c
@@ -474,6 +474,8 @@ static void buildGrammar(Builder *builder, Term *term)
GrammarDefine(builder->gram,ruleName,ruleExpr);
free(ruleName);
}
+
+ GrammarResolve(builder->gram);
}
// This function creates a new Grammar object from the result of parsing a file usin the built-in
http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/02c9f1d8/experiments/flat/src/Grammar.c
----------------------------------------------------------------------
diff --git a/experiments/flat/src/Grammar.c b/experiments/flat/src/Grammar.c
index f015dfb..6743953 100644
--- a/experiments/flat/src/Grammar.c
+++ b/experiments/flat/src/Grammar.c
@@ -131,3 +131,11 @@ void GrammarPrint(Grammar *gram)
free(prefix);
}
+
+const char *GrammarFirstRuleName(Grammar *gram)
+{
+ if (gram->defList == NULL)
+ return NULL;
+ else
+ return gram->defList->name;
+}
http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/02c9f1d8/experiments/flat/src/Grammar.h
----------------------------------------------------------------------
diff --git a/experiments/flat/src/Grammar.h b/experiments/flat/src/Grammar.h
index e94e51b..f51bd18 100644
--- a/experiments/flat/src/Grammar.h
+++ b/experiments/flat/src/Grammar.h
@@ -28,3 +28,4 @@ void GrammarDefine(Grammar *gram, const char *name, Expression *expr);
Expression *GrammarLookup(Grammar *gram, const char *name);
void GrammarResolve(Grammar *gram);
void GrammarPrint(Grammar *gram);
+const char *GrammarFirstRuleName(Grammar *gram);
http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/02c9f1d8/experiments/flat/src/flat.c
----------------------------------------------------------------------
diff --git a/experiments/flat/src/flat.c b/experiments/flat/src/flat.c
index 8aa4f74..ee3c2bb 100644
--- a/experiments/flat/src/flat.c
+++ b/experiments/flat/src/flat.c
@@ -44,6 +44,29 @@ static char *readStringFromFile(const char *filename)
return data;
}
+static Grammar *grammarFromFile(const char *filename)
+{
+ char *input = readStringFromFile(filename);
+ if (input == NULL) {
+ perror(filename);
+ exit(1);
+ }
+
+ Grammar *flatGrammar = GrammarNewBuiltin();
+ Term *term = parse(flatGrammar,"Grammar",input,0,strlen(input));
+ if (term == NULL) {
+ fprintf(stderr,"%s: Parse failed\n",filename);
+ exit(1);
+ }
+
+ Grammar *builtGrammar = grammarFromTerm(term,input);
+
+ free(input);
+ GrammarFree(flatGrammar);
+
+ return builtGrammar;
+}
+
int main(int argc, const char **argv)
{
@@ -71,27 +94,31 @@ int main(int argc, const char **argv)
GrammarFree(gram);
}
else if ((argc == 3) && !strcmp(argv[1],"-b")) {
- const char *filename = argv[2];
- char *input = readStringFromFile(filename);
- if (input == NULL) {
- perror(filename);
+ Grammar *built = grammarFromFile(argv[2]);
+ GrammarPrint(built);
+ GrammarFree(built);
+ }
+ else if (argc == 3) {
+ const char *grammarFilename = argv[1];
+ const char *inputFilename = argv[2];
+
+ char *inputStr = readStringFromFile(inputFilename);
+ if (inputStr == NULL) {
+ perror(inputFilename);
exit(1);
}
- Grammar *gram = GrammarNewBuiltin();
- Term *term = parse(gram,"Grammar",input,0,strlen(input));
- if (term == NULL) {
- fprintf(stderr,"%s: Parse failed\n",filename);
+ Grammar *builtGrammar = grammarFromFile(grammarFilename);
+ const char *firstRuleName = GrammarFirstRuleName(builtGrammar);
+ Term *inputTerm = parse(builtGrammar,firstRuleName,inputStr,0,strlen(inputStr));
+ if (inputTerm == NULL) {
+ fprintf(stderr,"%s: Parse failed\n",inputFilename);
exit(1);
}
+ TermPrint(inputTerm,inputStr,"");
-
- Grammar *built = grammarFromTerm(term,input);
- GrammarPrint(built);
-
- free(input);
- GrammarFree(gram);
- GrammarFree(built);
+ free(inputStr);
+ GrammarFree(builtGrammar);
}
else {
printf("Usage:\n"
@@ -109,6 +136,11 @@ int main(int argc, const char **argv)
"\n"
" Parse FILENAME using the built-in PEG grammar, then use the resulting parse\n"
" tree to build a Grammar object, and print out the constructed grammar.\n"
+ "\n"
+ "flat GRAMMAR INPUT\n"
+ "\n"
+ " Use the grammar defined in file GRAMMAR to parse the file INPUT, and print\n"
+ " out the resulting parse tree\n"
"\n");
return 1;