Skip to content
Browse files

some bugfixes

restored CamelCasing dialect
add short dialect version of math example



git-svn-id: https://tinyap.googlecode.com/svn/trunk@94 26adf5cf-fd31-0410-b5e7-cb6bf36da140
  • Loading branch information...
1 parent 6c651f5 commit d695490f779ffee92276d73c7a3c8707f77f0ae9 damien.leroux committed May 11, 2008
Showing with 189 additions and 129 deletions.
  1. +10 −10 configure
  2. +1 −1 configure.in
  3. +0 −1 examples/math.gram
  4. +22 −0 examples/math.short
  5. +4 −1 reformatting_output_for_C
  6. +84 −6 src/bootstrap.c
  7. +0 −103 src/main.c
  8. +2 −2 src/tokenizer.c
  9. +65 −4 src/tutorial.h
  10. +1 −1 src/unparser.c
View
20 configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.61 for tinyap 1.4-rc1.
+# Generated by GNU Autoconf 2.61 for tinyap 1.4-0.
#
# Report bugs to <damien.leroux@gmail.com>.
#
@@ -728,8 +728,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
# Identity of this package.
PACKAGE_NAME='tinyap'
PACKAGE_TARNAME='tinyap'
-PACKAGE_VERSION='1.4-rc1'
-PACKAGE_STRING='tinyap 1.4-rc1'
+PACKAGE_VERSION='1.4-0'
+PACKAGE_STRING='tinyap 1.4-0'
PACKAGE_BUGREPORT='damien.leroux@gmail.com'
ac_unique_file="src"
@@ -1391,7 +1391,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures tinyap 1.4-rc1 to adapt to many kinds of systems.
+\`configure' configures tinyap 1.4-0 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1461,7 +1461,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of tinyap 1.4-rc1:";;
+ short | recursive ) echo "Configuration of tinyap 1.4-0:";;
esac
cat <<\_ACEOF
@@ -1563,7 +1563,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-tinyap configure 1.4-rc1
+tinyap configure 1.4-0
generated by GNU Autoconf 2.61
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -1577,7 +1577,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by tinyap $as_me 1.4-rc1, which was
+It was created by tinyap $as_me 1.4-0, which was
generated by GNU Autoconf 2.61. Invocation command line was
$ $0 $@
@@ -2271,7 +2271,7 @@ fi
# Define the identity of the package.
PACKAGE='tinyap'
- VERSION='1.4-rc1'
+ VERSION='1.4-0'
cat >>confdefs.h <<_ACEOF
@@ -21625,7 +21625,7 @@ exec 6>&1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by tinyap $as_me 1.4-rc1, which was
+This file was extended by tinyap $as_me 1.4-0, which was
generated by GNU Autoconf 2.61. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -21678,7 +21678,7 @@ Report bugs to <bug-autoconf@gnu.org>."
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF
ac_cs_version="\\
-tinyap config.status 1.4-rc1
+tinyap config.status 1.4-0
configured by $0, generated by GNU Autoconf 2.61,
with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
View
2 configure.in
@@ -2,7 +2,7 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.61)
-AC_INIT([tinyap], [1.4-rc1], [damien.leroux@gmail.com])
+AC_INIT([tinyap], [1.4-0], [damien.leroux@gmail.com])
AC_CONFIG_SRCDIR([src])
AC_CONFIG_HEADER([config.h])
View
1 examples/math.gram
@@ -1,4 +1,3 @@
-#number ::= /[0-9]+(\.[0-9]*)?/.
number ::= /[0-9]+/.
m_expr ::= <expr4>.
View
22 examples/math.short
@@ -0,0 +1,22 @@
+number ::= /[0-9]+/.
+
+m_expr ::= expr4.
+
+m_minus ::= "-" number.
+m_div ::= ( m_div "/" expr0 | expr0 "/" expr0 ).
+m_mul ::= ( m_mul "*" expr1 | expr1 "*" expr1 ).
+m_sub ::= ( m_sub "-" expr2 | expr2 "-" expr2 ).
+m_add ::= ( m_add "+" expr3 | expr3 "+" expr3 ).
+
+expr0 = ( m_minus | number | "(" m_expr ")" ).
+expr1 = ( m_div | expr0 ).
+expr2 = ( m_mul | expr1 ).
+expr3 = ( m_sub | expr2 ).
+expr4 = ( m_add | expr3 ).
+
+_expr = m_expr ";".
+
+_start = ( _EOF
+ | _expr _start
+ ).
+
View
5 reformatting_output_for_C
@@ -1 +1,4 @@
-tinyap -g short -i explicit.gram -p -o -|sed 's/(Tran\|(Oper\|(Comm/\n&/g' |sed -e 's/\\/\\\\/g' -e 's/"/\\"/g' | sed 's/\(.*\) \?/"\1\\n"/g'
+#!/bin/sh
+INPUT="$1"
+shift
+tinyap $* -i $INPUT -p -o -|sed 's/(Tran\|(Oper\|(Comm/\n&/g' |sed -e 's/\\/\\\\/g' -e 's/"/\\"/g' | sed 's/\(.*\) \?/"\1\\n"/g'
View
90 src/bootstrap.c
@@ -80,7 +80,7 @@ const char*short_rules = "((Grammar\n"
"(TransientRule alt_elem (Alt (NT Seq) (NT rule_elem)))\n"
"(TransientRule alt_expr (Alt (Seq (NT alt_expr) (T |) (NT Space) (NT alt_elem)) (NT alt_elem)))\n"
"(TransientRule rule_elem (Alt (Seq (Alt (NT EOF) (NT Comment) (NT Rep) (NT rule_elem_atom)) (NT Space))))\n"
-"(TransientRule rule_elem_atom (Alt (NT epsilon) (NT T) (NT NT) (NT RPL) (NT RE) (NT Alt) (NT Prefix) (NT Postfix)))\n"
+"(TransientRule rule_elem_atom (Alt (NT Epsilon) (NT T) (NT NT) (NT RPL) (NT RE) (NT Alt) (NT Prefix) (NT Postfix)))\n"
"(Comment)\n"
"(Comment \\ Entry\\ point)\n"
"(Comment)\n"
@@ -91,7 +91,7 @@ const char*short_rules = "((Grammar\n"
"(Comment \\ Builtins)\n"
"(Comment)\n"
"(OperatorRule EOF (T _EOF))\n"
-"(OperatorRule epsilon (T _epsilon))\n"
+"(OperatorRule Epsilon (T _epsilon))\n"
"(OperatorRule Space (T Space))\n"
"(OperatorRule NewLine (T NewLine))\n"
"(OperatorRule Indent (T Indent))\n"
@@ -158,7 +158,7 @@ const char*explicit_bnff_rules = "((Grammar "
"(TransientRule alt_elem (Alt (NT Seq) (NT rule_elem))) \n"
"(TransientRule alt_expr (Alt (Seq (NT alt_expr) (T |) (NT Space) (NT alt_elem)) (NT alt_elem))) \n"
"(TransientRule rule_elem (Alt (Seq (Alt (NT EOF) (NT Comment) (NT Rep) (NT rule_elem_atom)) (NT Space)))) \n"
-"(TransientRule rule_elem_atom (Alt (NT epsilon) (NT T) (NT NT) (NT RPL) (NT RE) (NT Alt) (NT Prefix) (NT Postfix))) \n"
+"(TransientRule rule_elem_atom (Alt (NT Epsilon) (NT T) (NT NT) (NT RPL) (NT RE) (NT Alt) (NT Prefix) (NT Postfix))) \n"
"(Comment ) \n"
"(Comment \\ Entry\\ point) \n"
"(Comment ) \n"
@@ -169,7 +169,7 @@ const char*explicit_bnff_rules = "((Grammar "
"(Comment \\ Builtins) \n"
"(Comment ) \n"
"(OperatorRule EOF (T EOF)) \n"
-"(OperatorRule epsilon (T epsilon)) \n"
+"(OperatorRule Epsilon (T epsilon)) \n"
"(OperatorRule Space (T Space)) \n"
"(OperatorRule NewLine (T NewLine)) \n"
"(OperatorRule Indent (T Indent)) \n"
@@ -188,6 +188,84 @@ const char*explicit_bnff_rules = "((Grammar "
"(OperatorRule Comment (Alt (Seq (Alt (RPL #\\([^\\r\\n]*\\) \\\\1) (T #)) (NT NewLine))))))\n";
+const char* CamelCased_bnff_rules = "((Grammar \n"
+"(Comment \\ TinyaP\\ :\\ this\\ is\\ not\\ yet\\ another\\ parser.) \n"
+"(Comment \\ Copyright\\ \\(C\\)\\ 2007\\ Damien\\ Leroux) \n"
+"(Comment \\ Grammar\\ for\\ 'CamelCasing'\\ dialect.) \n"
+"(Comment \\ This\\ program\\ is\\ free\\ software;\\ you\\ can\\ redistribute\\ it\\ and/or) \n"
+"(Comment \\ modify\\ it\\ under\\ the\\ terms\\ of\\ the\\ GNU\\ General\\ Public\\ License) \n"
+"(Comment \\ as\\ published\\ by\\ the\\ Free\\ Software\\ Foundation;\\ either\\ version\\ 2) \n"
+"(Comment \\ of\\ the\\ License,\\ or\\ \\(at\\ your\\ option\\)\\ any\\ later\\ version.) \n"
+"(Comment \\ This\\ program\\ is\\ distributed\\ in\\ the\\ hope\\ that\\ it\\ will\\ be\\ useful,) \n"
+"(Comment \\ but\\ WITHOUT\\ ANY\\ WARRANTY;\\ without\\ even\\ the\\ implied\\ warranty\\ of) \n"
+"(Comment \\ MERCHANTABILITY\\ or\\ FITNESS\\ FOR\\ A\\ PARTICULAR\\ PURPOSE.\\ \\ See\\ the) \n"
+"(Comment \\ GNU\\ General\\ Public\\ License\\ for\\ more\\ details.) \n"
+"(Comment \\ You\\ should\\ have\\ received\\ a\\ copy\\ of\\ the\\ GNU\\ General\\ Public\\ License) \n"
+"(Comment \\ along\\ with\\ this\\ program;\\ if\\ not,\\ write\\ to\\ the\\ Free\\ Software) \n"
+"(Comment \\ Foundation,\\ Inc.,\\ 59\\ Temple\\ Place\\ -\\ Suite\\ 330,\\ Boston,\\ MA\\ \\ 02111-1307,\\ USA.) \n"
+"(Comment ) \n"
+"(Comment \\ Production\\ Atoms) \n"
+"(Comment ) \n"
+"(TransientRule camelIdent (RE \\([A-Z][0-9a-z]*\\)+)) \n"
+"(TransientRule elem (RE [_a-zA-Z][0-9a-zA-Z_]*)) \n"
+"(OperatorRule T (RPL \"\\(\\([^\\\\\"]|[\\\\][\"\\ trnb]\\)*\\)\" \\\\1)) \n"
+"(OperatorRule NT (Seq (T <) (NT elem) (T >))) \n"
+"(TransientRule re_re (RE \\([^\\\\/]|[\\\\][][\\\\/\\ <>trnb\"]\\)*)) \n"
+"(OperatorRule RE (Seq (T /) (NT re_re) (T /))) \n"
+"(OperatorRule RPL (Seq (T //) (NT re_re) (T /) (RE \\([^\\r\\n\\\\/]+|[\\\\][\\\\/0-9]\\)+) (T /))) \n"
+"(Comment ) \n"
+"(Comment \\ Rules) \n"
+"(Comment ) \n"
+"(TransientRule rule (Alt (NT OperatorRule) (NT TransientRule))) \n"
+"(OperatorRule OperatorRule (Seq (NT camelIdent) (NT Space) (T ::=) (NT Space) (NT rule_expr) (T .) (NT NewLine))) \n"
+"(OperatorRule TransientRule (Seq (NT elem) (NT Space) (T ::=) (NT Space) (NT rule_expr) (T .) (NT NewLine))) \n"
+"(Comment ) \n"
+"(Comment \\ Expressions) \n"
+"(Comment ) \n"
+"(TransientRule rule_expr (Alt (NT Alt) (NT Seq) (NT rule_elem))) \n"
+"(OperatorRule Prefix (Seq (T [) (NT rule_expr) (T ]) (NT rule_elem_atom))) \n"
+"(OperatorRule Postfix (Seq (T {) (NT rule_expr) (T }) (NT rule_elem_atom))) \n"
+"(OperatorRule Seq (Seq (NT rule_elem) (NT seq_expr))) \n"
+"(OperatorRule Alt (Seq (T \\() (NT Space) (NT alt_expr) (T \\)))) \n"
+"(Comment ) \n"
+"(Comment \\ Helpers) \n"
+"(Comment ) \n"
+"(TransientRule seq_expr (Alt (Seq (NT seq_expr) (NT rule_elem)) (NT rule_elem))) \n"
+"(TransientRule alt_elem (Alt (NT Seq) (NT rule_elem))) \n"
+"(TransientRule alt_expr (Alt (Seq (NT alt_expr) (T |) (NT Space) (NT alt_elem)) (NT alt_elem))) \n"
+"(TransientRule rule_elem (Alt (Seq (Alt (NT EOF) (NT Comment) (NT Rep) (NT rule_elem_atom)) (NT Space)))) \n"
+"(TransientRule rule_elem_atom (Alt (NT Epsilon) (NT T) (NT NT) (NT RPL) (NT RE) (NT Alt) (NT Prefix) (NT Postfix))) \n"
+"(Comment ) \n"
+"(Comment \\ Entry\\ point) \n"
+"(Comment ) \n"
+"(TransientRule _start (NT Grammar)) \n"
+"(OperatorRule Grammar (NT _loop)) \n"
+"(TransientRule _loop (Alt (NT EOF) (Seq (Alt (NT Comment) (NT rule)) (NT _loop)))) \n"
+"(Comment ) \n"
+"(Comment \\ Builtins) \n"
+"(Comment ) \n"
+"(OperatorRule EOF (T EOF)) \n"
+"(OperatorRule Epsilon (T epsilon)) \n"
+"(OperatorRule Space (T Space)) \n"
+"(OperatorRule NewLine (T NewLine)) \n"
+"(OperatorRule Indent (T Indent)) \n"
+"(OperatorRule Dedent (T Dedent)) \n"
+"(TransientRule _whitespace (RE \\([\\ \\r\\n\\t]\\)+)) \n"
+"(Comment ) \n"
+"(Comment \\ Repetitions) \n"
+"(Comment ) \n"
+"(OperatorRule Rep1N (Seq (NT rule_elem_atom) (T +))) \n"
+"(OperatorRule Rep0N (Seq (NT rule_elem_atom) (T *))) \n"
+"(OperatorRule Rep01 (Seq (NT rule_elem_atom) (T ?))) \n"
+"(TransientRule Rep (Alt (NT Rep1N) (NT Rep0N) (NT Rep01))) \n"
+"(Comment ) \n"
+"(Comment \\ Comments) \n"
+"(Comment ) \n"
+"(OperatorRule Comment (Alt (Seq (Alt (RPL #\\([^\\r\\n]*\\) \\\\1) (T #)) (NT NewLine))))))\n";
+
+
+
+
ast_node_t init_BNF_rules() {
return ast_unserialize(explicit_bnff_rules);
}
@@ -203,8 +281,8 @@ ast_node_t tinyap_get_ruleset(const char*name) {
// printf("before tinyap_get_ruleset : %li nodes (%i alloc'd so far)\n",node_pool_size(),_node_alloc_count);
if(!strcmp(name,GRAMMAR_EXPLICIT)) {
ret=ast_unserialize(explicit_bnff_rules);
- /*} else if(!strcmp(name,GRAMMAR_CAMELCASING)) {*/
- /*ret=ast_unserialize(CamelCased_bnff_rules);*/
+ } else if(!strcmp(name,GRAMMAR_CAMELCASING)) {
+ ret=ast_unserialize(CamelCased_bnff_rules);
} else if(!strcmp(name,GRAMMAR_SHORT)) {
ret=ast_unserialize(short_rules);
} else if(!stat(name,&st)) {
View
103 src/main.c
@@ -35,7 +35,6 @@
void ast_serialize(const ast_node_t ast,char**output);
-void print_rules(ast_node_t rs);
ast_node_t grammar,ast;
@@ -153,105 +152,3 @@ int main(int argc, char**argv) {
}
-
-
-void print_rule_elem(ast_node_t e) {
- const char*tag;
- //ast_node_t t;
-
- if(!e) {
- return;
- }
-
- if(tinyap_node_is_string(e)) {
- printf("[OUPS L'ATOME %s] ",tinyap_node_get_string(e));
- }
-
- assert(tinyap_node_is_list(e));
-
- tag=tinyap_node_get_operator(e);
-
- if(!strcmp(tag,"OperatorRule")) {
- const char*id=tinyap_node_get_string(tinyap_node_get_operand(e,0));
-
- printf("%s ::= ",id);
- print_rule_elem(tinyap_node_get_operand(e,1));
- printf(".\n");
- } else if(!strcmp(tag,"TransientRule")) {
- const char*id=tinyap_node_get_string(tinyap_node_get_operand(e,0));
- printf("%s = ",id);
- print_rule_elem(tinyap_node_get_operand(e,1));
- printf(".\n");
- } else if(!strcmp(tag,"Postfix")) {
- /*const char*id=tinyap_node_get_string(tinyap_node_get_operand(e,0));*/
- printf("{");
- print_rule_elem(tinyap_node_get_operand(e,0));
- printf("} ");
- print_rule_elem(tinyap_node_get_operand(e,1));
- } else if(!strcmp(tag,"Prefix")) {
- /*const char*id=tinyap_node_get_string(tinyap_node_get_operand(e,0));*/
- printf("[");
- print_rule_elem(tinyap_node_get_operand(e,0));
- printf("] ");
- print_rule_elem(tinyap_node_get_operand(e,1));
- } else if(!strcmp(tag,"Seq")) {
- int n=tinyap_node_get_operand_count(e);
- int i;
- for(i=0;i<n;i++) {
- print_rule_elem(tinyap_node_get_operand(e,i));
- }
- /*printf(" ");*/
- } else if(!strcmp(tag,"Alt")) {
- int n=tinyap_node_get_operand_count(e);
- int i;
- printf("( ");
- print_rule_elem(tinyap_node_get_operand(e,0));
- for(i=1;i<n;i++) {
- printf("| ");
- print_rule_elem(tinyap_node_get_operand(e,i));
- }
- printf(") ");
- } else if(!strcmp(tag,"RE")) {
- const char*esc=tinyap_serialize_to_string(tinyap_node_get_operand(e,0));
- printf("/%s/ ",esc);
- free((char*)esc);
- } else if(!strcmp(tag,"RPL")) {
- const char*esc=tinyap_serialize_to_string(tinyap_node_get_operand(e,0));
- const char*esc2=tinyap_serialize_to_string(tinyap_node_get_operand(e,1));
- printf("//%s/%s/ ",esc,esc2);
- free((char*)esc);
- free((char*)esc2);
- } else if(!strcmp(tag,"NT")) {
- const char*esc=tinyap_node_get_string(tinyap_node_get_operand(e,0));
- printf("<%s> ",esc);
- } else if(!strcmp(tag,"T")) {
- const char*esc=tinyap_serialize_to_string(tinyap_node_get_operand(e,0));
- printf("\"%s\" ",esc);
- free((char*)esc);
- } else if(!strcmp(tag,"epsilon")) {
- printf("epsilon ");
- } else if(!strcmp(tag,"EOF")) {
- printf("EOF ");
- } else {
- printf("[NOT IMPLEMENTED [%s]] ",tag);
- }
-
-}
-
-
-void print_rules_sub(ast_node_t rs) {
- int n=tinyap_node_get_operand_count(rs);
- int i;
- assert(!strcmp(tinyap_node_get_operator(rs),"Grammar"));
- for(i=0;i<n;i++) {
- print_rule_elem(tinyap_node_get_operand(rs,i));
- }
-}
-
-void print_rules(ast_node_t rs) {
- if(!rs) return;
-
- print_rules_sub(tinyap_list_get_element(rs,0));
-}
-
-
View
4 src/tokenizer.c
@@ -556,7 +556,7 @@ ast_node_t token_produce_any(token_context_t*t,ast_node_t expr,int strip_T) {
col = t->pos_cache.col;
if(isAtom(expr)) {
- if(!strcmp(Value(expr),"epsilon")) {
+ if(!strcmp(Value(expr),"Epsilon")) {
return newPair(newAtom("strip.me",0,0),NULL,row,col);
} else if(!strcmp(Value(expr),"EOF")) {
_filter_garbage(t);
@@ -613,7 +613,7 @@ ast_node_t token_produce_any(token_context_t*t,ast_node_t expr,int strip_T) {
// key = node_tag(Cdr(expr));
} else if(!strcmp(tag,"EOF")) {
typ = OP_EOF;
- } else if(!strcmp(tag,"epsilon")) {
+ } else if(!strcmp(tag,"Epsilon")) {
return newPair(newAtom("strip.me",0,0),NULL,row,col);
}
View
69 src/tutorial.h
@@ -10,6 +10,7 @@
* \ref t_usag <br/>
* \ref t_srlz <br/>
* \ref t_walk <br/>
+ * \ref t_uprs <br/>
* \ref t_api <br/>
* </div>
* \endsection
@@ -38,10 +39,10 @@
* <p>First, get the source code.</p>
* <ul>
* <li><b>download a tarball</b> :
- * (version 1.3-0 in used the example below, you can download the latest at http://code.google.com/p/tinyap/downloads/list).
+ * (version 1.4-0 in used the example below, you can download the latest at http://code.google.com/p/tinyap/downloads/list).
* \code
- * $ wget http://tinyap.googlecode.com/files/tinyap-1.3-0.tar.gz
- * $ tar xzf tinyap-1.3-0.tar.gz
+ * $ wget http://tinyap.googlecode.com/files/tinyap-1.4-0.tar.gz
+ * $ tar xzf tinyap-1.4-0.tar.gz
* \endcode
* <li><b>using SVN</b> :
* \code
@@ -189,7 +190,67 @@
*
* \endsection
*
- * \section t_api VI. C API
+ * \section t_uprs VI. Unparsing
+ *
+ * With using a grammar and an AST, create back the text buffer that generated this AST when parsed with this grammar.
+ *
+ * This can be useful for data (un)serialization, as well as syntax highlighting and source code reformatting.
+ *
+ * Tinyap recognizes the special pseudo-elements \c Space, \c Indent, \c Dedent, and \c NewLine. These elements are ignored
+ * when parsing text, and used to perform indentation when unparsing an AST. A special grammar rule indent may
+ * define the indentation string. Tinyap defaults to the tab character if this rule is not defined. Space is used
+ * to force a white space between similar tokens, or to ensure formatting. Many Space elements in a row will insert
+ * only one space.
+ *
+ * \note Note that the grammar used to unparse is not required to be the same grammar used for parsing. It is only required
+ * to define all the rules that match the AST labels.
+ *
+ * \note Since tinyap doesn't recover from parse errors yet, the unparsing feature can't be trivially used to format
+ * source code while it is edited. This should be handled in the next release (<b>Help wanted ! I haven't defined yet
+ * how to behave when encountering errors, since I'm busy by now it may take some time before tinyap is able to handle
+ * errors, unless people come to help with this feature</b>).
+ *
+ * Detailed pseudo-elements behaviour :
+ * - \c Space : insert one space into output text. More than one \c Space elements in a row will produce one single space character in the output text.
+ * - \c NewLine : insert a NewLine ('\n') character into output text, followed by as many \c _indent strings as the current indent level.
+ * - \c Indent : increment indent level and insert one \c _indent string into the output text.
+ * - \c Dedent : decrement indent level and remove the last \c _indent string from output text.
+ *
+ * Quick output formatting how-to :
+ *
+ * It is quite straightforward to include formatting elements in a grammar, for instance to add color or typefaces to the
+ * output text, without interfering with parsing input text.
+ *
+ * Using terminals and the \c ? operator, one can define optional elements that will be taken into account only at unparsing
+ * time. Example :
+ * \code
+ * _start = foobar.
+ * foobar ::= "<em>"? /(foo|bar|baz)+/ "</em>"?.
+ * \endcode
+ * The text "foobarbazfoo" will be recognized by this rule, because the \c ? operators allow the terminals to be omitted.
+ * The corresponding AST (foobar foobarbazfoo) will be unparsed to "<em>foobarbazfoo</em>" because unparsing always tries
+ * to produce optional elements.
+ *
+ * Moreover, it is easy to define <b>configurable</b> formatters :
+ * \code
+ * _start = foobar.
+ * foo_prefix = ( "<em>" ).
+ * foo_suffix = ( "</em>" ).
+ * foobar ::= foo_prefix? /(foo|bar|baz)+/ foo_suffix?.
+ * \endcode
+ *
+ * Prefix and Suffix are defined as pluggable rules. Now, just plug a new formatting terminal in each rule. Unparsing will
+ * always use the last formatting terminal plugged in.
+ *
+ * For instance :
+ * - Unparsing (foobar foobarbazfoo) gives "<em>foobarbazfoo</em>".
+ * - Plug "PFX" into \c foo_prefix.
+ * - Plug "SFX" into \c foo_suffix.
+ * - Unparsing (foobar foobarbazfoo) now gives "PFXfoobarbazfooSFX".
+ *
+ * \endsection
+ *
+ * \section t_api VII. C API
*
* \see tinyap.h
* \see tinyape.h
View
2 src/unparser.c
@@ -374,7 +374,7 @@ int unproduce(wast_iterator_t grammar, wast_iterator_t expr, wast_iterator_t ast
wi_next(expr);
}
wi_up(expr);
- } else if(!strcmp(wi_op(expr), "epsilon")) {
+ } else if(!strcmp(wi_op(expr), "Epsilon")) {
status = 1;
} else if(!strcmp(wi_op(expr), "EOF")) {
/*printf("on EOF.... ast = ");*/

0 comments on commit d695490

Please sign in to comment.
Something went wrong with that request. Please try again.