RPA Toolkit
added --dump-alias. Work on the RJS.
authorMartin Stoilov <martin@rpasearch.com>
Thu, 28 Apr 2011 04:07:15 +0000 (21:07 -0700)
committerMartin Stoilov <martin@rpasearch.com>
Thu, 28 Apr 2011 04:07:15 +0000 (21:07 -0700)
14 files changed:
rgrep/rpagrep.c
rgrep/rpagrep.h
rgrep/unix/main.c
rjs/ecma262.rpa
rjs/rjs.c
rjs/rjs.h
rjs/rjscompiler.c
rjs/rjscompiler.h
rjs/rjsexec.c
rjs/rjsuids.h [new file with mode: 0644]
rpa2/rpadbex.c
rpa2/rpadbex.h
rpa2/rpaparser.c
rpa2/rpaparser.h

index f8cbd46..ad90f09 100644 (file)
@@ -187,6 +187,13 @@ void rpa_grep_dump_pattern_info(rpa_grep_t *pGrep)
 }
 
 
+void rpa_grep_dump_alias_info(rpa_grep_t *pGrep)
+{
+       rpa_dbex_compile(pGrep->hDbex);
+       rpa_dbex_dumpalias(pGrep->hDbex);
+}
+
+
 int rpa_grep_match(rpa_grep_t *pGrep, const char* buffer, unsigned long size)
 {
        int ret = 0;
index a09626f..bf07cba 100644 (file)
@@ -83,6 +83,7 @@ void rpa_grep_setup_matched_callback(rpa_grep_t *pGrep, rpa_buffer_t *pattern);
 void rpa_grep_dump_pattern_tree(rpa_grep_t *pGrep, rpa_buffer_t *pattern);
 void rpa_grep_dump_pattern_records(rpa_grep_t *pGrep);
 void rpa_grep_dump_pattern_info(rpa_grep_t *pGrep);
+void rpa_grep_dump_alias_info(rpa_grep_t *pGrep);
 void rpa_grep_optimizations(rpa_grep_t *pGrep, rulong allow);
 
 void rpa_buffer_destroy(rpa_buffer_t *str);
index ae28297..f50b2f2 100644 (file)
@@ -57,6 +57,7 @@ int usage(int argc, const char *argv[])
                fprintf(stderr, "\t-v                       Display version information.\n");
                fprintf(stderr, "\t-h, --help               Display this help.\n");
                fprintf(stderr, "\t    --dump-info          Display rules info.\n");
+               fprintf(stderr, "\t    --dump-alias         Display alias info.\n");
                fprintf(stderr, "\t    --dump-records       Display rules parsing records.\n");
                fprintf(stderr, "\t    --no-optimizations   Disable optimizations.\n");
 
@@ -155,6 +156,12 @@ int main(int argc, const char *argv[])
                }
        }
 
+       for (i = 1; i < argc; i++) {
+               if (strcmp(argv[i], "--dump-alias") == 0) {
+                       rpa_grep_dump_alias_info(pGrep);
+                       goto end;
+               }
+       }
 
        for (i = 1; i < argc; i++) {
                if (strcmp(argv[i], "--dump-records") == 0) {
index 9dd923f..8434c38 100644 (file)
 #!emit Expression
 #!emit MemberExpressionIndexOp
 #!emit MemberExpressionDotOp
-#!emit MemberExpressionBase
 #!emit IdentifierName
 #!emit CallExpression
+#!emit AssignmentExpressionOp
 
-#!uid Program 1
-#!uid PostfixExpressionValOp 2
+#!uid Program                                          RJS_PROGRAM                                             1
+#!uid PostfixExpressionValOp           RJS_POSTFIXEXPRESSIONVALOP                      2
+#!uid Expression                                       RJS_EXPRESSION                                          3
+#!uid LeftHandSideExpression           RJS_LEFTHANDSIDEEXPRESSION                      4 
 
 
 # 6 Source Text
@@ -101,7 +103,7 @@ IdentifierPart                      ::= <IdentifierStart> |
                                                <UnicodeDigit> 
 UnicodeDigit                   ::= [0-9] | [#0x0660-#0x0669]                                   # TBD
 
-ReservedWord                   ::= <Keyword>
+ReservedWord                   ::= <Keyword> |
                                                        <FutureReservedWord> |
                                                        <NullLiteral> |
                                                        <BooleanLiteral>
@@ -279,7 +281,8 @@ LogicalORExpression                         ::= <LogicalOROp> |
 ConditionalExpression                  ::= <LogicalORExpression> ( <S>? '?' <S>? <AssignmentExpression> <S>? ':' <S>? <AssignmentExpression> )?
 
 # 11.13 Assignment Operators
-AssignmentExpression                   ::= <LeftHandSideExpression> <S>? <AssignmentOperator> <S>? <AssignmentExpression> | <ConditionalExpression>
+AssignmentExpressionOp                         ::= <LeftHandSideExpression> <S>? <AssignmentOperator> <S>? <AssignmentExpression>
+AssignmentExpression                   ::= <AssignmentExpressionOp> | <ConditionalExpression>
 AssignmentOperator                             ::= '=' | '*=' | '/=' | '%=' | '+=' | '-=' | '<<=' | '>>=' | '>>>=' | '&=' | '^=' | '|='
 
 
@@ -417,6 +420,6 @@ SourceElement                                               ::= <FunctionDeclaration> |
                                                                        <Statement>
 Program                                                        ::= <SourceElements>
 # The root rule, it is anonymous
-<Expression>
+<Program>
        
 
index 80e6c33..7d43249 100644 (file)
--- a/rjs/rjs.c
+++ b/rjs/rjs.c
@@ -1,3 +1,4 @@
+#include "rmem.h"
 #include "rjs.h"
 
 
@@ -5,3 +6,105 @@ const rchar *rjs_version()
 {
        return RJS_VERSION_STRING;
 }
+
+
+rjs_engine_t *rjs_engine_create()
+{
+       rjs_engine_t *jse = (rjs_engine_t *) r_zmalloc(sizeof(*jse));
+
+       jse->pa = rjs_parser_create();
+       jse->cpu = rvm_cpu_create_default();
+       return jse;
+}
+
+
+void rjs_engine_destroy(rjs_engine_t *jse)
+{
+       if (jse) {
+               rjs_parser_destroy(jse->pa);
+               rvm_cpu_destroy(jse->cpu);
+               rjs_compiler_destroy(jse->co);
+               r_free(jse);
+       }
+}
+
+
+rint rjs_engine_open(rjs_engine_t *jse)
+{
+       return 0;
+}
+
+
+static rint rjs_engine_parse(rjs_engine_t *jse, const rchar *script, rsize_t size, rarray_t **records)
+{
+       rlong res = 0;
+       res = rjs_parser_exec(jse->pa, script, size, records);
+       return res;
+}
+
+
+rint rjs_engine_compile(rjs_engine_t *jse, const rchar *script, rsize_t size)
+{
+       rarray_t *records = NULL;
+       if (jse->co)
+               rjs_compiler_destroy(jse->co);
+       jse->co = rjs_compiler_create(jse->cpu);
+       jse->co->debug = jse->debugcompile;
+
+       if (rjs_engine_parse(jse, script, size, &records) < 0) {
+
+               goto err;
+       }
+
+       if (rjs_compiler_compile(jse->co, records) < 0) {
+
+               goto err;
+       }
+
+       r_array_destroy(records);
+       return 0;
+
+err:
+       r_array_destroy(records);
+       return -1;
+}
+
+
+rint rjs_engine_dumpast(rjs_engine_t *jse, const rchar *script, rsize_t size)
+{
+       rarray_t *records = NULL;
+       if (rjs_engine_parse(jse, script, size, &records) < 0) {
+
+
+               return -1;
+       }
+
+       if (records) {
+               rlong i;
+               for (i = 0; i < r_array_length(records); i++)
+                       rpa_record_dump(records, i);
+       }
+
+       r_array_destroy(records);
+       return 0;
+}
+
+
+rint rjs_engine_compile_s(rjs_engine_t *jse, const rchar *script)
+{
+       return rjs_engine_compile(jse, script, r_strlen(script));
+}
+
+
+rint rjs_engine_close(rjs_engine_t *jse)
+{
+
+       return 0;
+}
+
+
+rint rjs_engine_run(rjs_engine_t *jse)
+{
+
+       return 0;
+}
index 8aa2391..007b14f 100644 (file)
--- a/rjs/rjs.h
+++ b/rjs/rjs.h
@@ -7,7 +7,17 @@ extern "C" {
 #endif
 
 #include "rtypes.h"
+#include "rvmcpu.h"
 #include "rjsparser.h"
+#include "rjscompiler.h"
+
+typedef struct rjs_engine_s {
+       rjs_parser_t *pa;
+       rjs_compiler_t *co;
+       rvmcpu_t *cpu;
+       rlong debugcompile:1;
+} rjs_engine_t;
+
 
 #define RJS_VERSION_MAJOR 0
 #define RJS_VERSION_MINOR 51
@@ -16,6 +26,15 @@ extern "C" {
 
 const rchar *rjs_version();
 
+rjs_engine_t *rjs_engine_create();
+void rjs_engine_destroy(rjs_engine_t *jse);
+rint rjs_engine_open(rjs_engine_t *jse);
+rint rjs_engine_compile(rjs_engine_t *jse, const rchar *script, rsize_t size);
+rint rjs_engine_compile_s(rjs_engine_t *jse, const rchar *script);
+rint rjs_engine_close(rjs_engine_t *jse);
+rint rjs_engine_run(rjs_engine_t *jse);
+rint rjs_engine_dumpast(rjs_engine_t *jse, const rchar *script, rsize_t size);
+
 
 #ifdef __cplusplus
 }
index 7442b5c..6c927f2 100644 (file)
@@ -2,11 +2,64 @@
 #include "rjscompiler.h"
 
 
-rjs_compiler_t *rjs_compiler_create()
+void rjs_compiler_debughead(rjs_compiler_t *co, rarray_t *records, rlong rec, rparecord_t *prec)
+{
+       if (co->debug) {
+               rpa_record_dump(records, rec);
+
+       }
+}
+
+
+void rjs_compiler_debugtail(rjs_compiler_t *co, rarray_t *records, rlong rec, rparecord_t *prec)
+{
+       if (co->debug) {
+
+       }
+
+}
+
+
+rint rjs_compiler_rh_program(rjs_compiler_t *co, rarray_t *records, rlong rec, rparecord_t *prec)
+{
+       rjs_compiler_debughead(co, records, rec, prec);
+
+       rjs_compiler_debugtail(co, records, rec, prec);
+       return 0;
+}
+
+
+rint rjs_compiler_rh_expression(rjs_compiler_t *co, rarray_t *records, rlong rec, rparecord_t *prec)
+{
+       rjs_compiler_debughead(co, records, rec, prec);
+
+       rjs_compiler_debugtail(co, records, rec, prec);
+       return 0;
+}
+
+
+rint rjs_compiler_rh_lefthandsideexpression(rjs_compiler_t *co, rarray_t *records, rlong rec, rparecord_t *prec)
+{
+       rjs_compiler_debughead(co, records, rec, prec);
+
+       rjs_compiler_debugtail(co, records, rec, prec);
+       return 0;
+}
+
+
+rjs_compiler_t *rjs_compiler_create(rvmcpu_t *cpu)
 {
        rjs_compiler_t *co = (rjs_compiler_t *) r_zmalloc(sizeof(*co));
 
        co->cg = rvm_codegen_create();
+       co->coexp = r_array_create(sizeof(rjs_coexp_t));
+       co->cpu = cpu;
+       r_memset(co->handlers, 0, sizeof(co->handlers));
+
+       co->handlers[RJS_PROGRAM] = rjs_compiler_rh_program;
+       co->handlers[RJS_EXPRESSION] = rjs_compiler_rh_expression;
+       co->handlers[RJS_LEFTHANDSIDEEXPRESSION] = rjs_compiler_rh_lefthandsideexpression;
+
        return co;
 }
 
@@ -15,6 +68,30 @@ void rjs_compiler_destroy(rjs_compiler_t *co)
 {
        if (co) {
                rvm_codegen_destroy(co->cg);
+               r_array_destroy(co->coexp);
+               co->cpu = NULL;
                r_free(co);
        }
 }
+
+
+rint rjs_compiler_compile(rjs_compiler_t *co, rarray_t *records)
+{
+       rlong i;
+       rparecord_t *prec;
+
+       if (!co || !records) {
+
+               return -1;
+       }
+
+
+       for (i = 0; i < r_array_length(records); i++) {
+               prec = (rparecord_t *)r_array_slot(records, i);
+               if (prec->ruleuid >= 0 && prec->ruleuid < RJS_COMPILER_NHANDLERS && co->handlers[prec->ruleuid]) {
+                       co->handlers[prec->ruleuid](co, records, i, prec);
+               }
+       }
+
+       return 0;
+}
index d806337..f184629 100644 (file)
@@ -9,15 +9,32 @@ extern "C" {
 #include "rtypes.h"
 #include "rarray.h"
 #include "rvmcodegen.h"
+#include "rvmcpu.h"
+#include "rjsuids.h"
+#include "rparecord.h"
 
+#define RJS_COMPILER_NHANDLERS 128
 
-typedef struct rjs_compiler_s {
+typedef struct rjs_coexp_s {
+       rlong codeoff;
+} rjs_coexp_t;
+
+
+typedef struct rjs_compiler_s rjs_compiler_t;
+typedef rint (*RJS_COMPILER_RH)(rjs_compiler_t *co, rarray_t *records, rlong rec, rparecord_t *prec);
+
+struct rjs_compiler_s {
+       rvmcpu_t *cpu;
        rvm_codegen_t *cg;
-} rjs_compiler_t;
+       rarray_t *coexp;
+       rulong debug:1;
+       RJS_COMPILER_RH handlers[RJS_COMPILER_NHANDLERS];
+};
 
 
-rjs_compiler_t *rjs_compiler_create();
-void rjs_compiler_destroy(rjs_compiler_t *parser);
+rjs_compiler_t *rjs_compiler_create(rvmcpu_t *cpu);
+void rjs_compiler_destroy(rjs_compiler_t *co);
+rint rjs_compiler_compile(rjs_compiler_t *co, rarray_t *records);
 
 
 #ifdef __cplusplus
index 34a2c12..b28fdbc 100644 (file)
 #include "rparecord.h"
 
 
+static int debuginfo = 0;
+static int parseinfo = 0;
+static int compileonly = 0;
+static int debugcompileonly = 0;
+
 
 void rjs_unmap_file(rstr_t *buf)
 {
@@ -62,20 +67,33 @@ error:
 int main(int argc, char *argv[])
 {
        rint i;
-       rlong res;
        rstr_t *script = NULL, *unmapscript = NULL;
-       rjs_parser_t *parser = rjs_parser_create();
-       rarray_t *records = 0;
+       rstr_t line;
+       rjs_engine_t *jse = rjs_engine_create();
+
+       for (i = 1; i < argc; i++) {
+               if (r_strcmp(argv[i], "-L") == 0) {
+
+               } else if (r_strcmp(argv[i], "-d") == 0) {
+                       debuginfo = 1;
+               } else if (r_strcmp(argv[i], "-p") == 0) {
+                       parseinfo = 1;
+               } else if (r_strcmp(argv[i], "-C") == 0) {
+                       debugcompileonly = 1;
+               } else if (r_strcmp(argv[i], "-c") == 0) {
+                       compileonly = 1;
+               } else if (r_strcmp(argv[i], "-m") == 0) {
+
+               }
+       }
 
-       if (!parser)
-               return 1;
-       r_printf("RJS Version: %s\n", rjs_version());
 
        for (i = 1; i < argc; i++) {
                if (r_strcmp(argv[i], "-e") == 0) {
                        if (++i < argc) {
-                               rstr_t script = { argv[i], r_strlen(argv[i]) };
-                               res = rjs_parser_exec(parser, script.str, script.size, &records);
+                               line.str = argv[i];
+                               line.size = r_strlen(argv[i]);
+                               script = &line;
                        }
                        goto exec;
                }
@@ -86,7 +104,6 @@ int main(int argc, char *argv[])
                        if (++i < argc) {
                                script = rjs_map_file(argv[i]);
                                if (script) {
-                                       res = rjs_parser_exec(parser, script->str, script->size, &records);;
                                        unmapscript = script;
                                }
                        }
@@ -95,13 +112,23 @@ int main(int argc, char *argv[])
        }
 
 exec:
-       if (records) {
-               rlong i;
-               for (i = 0; i < r_array_length(records); i++)
-                       rpa_record_dump(records, i);
+       if (!script)
+               goto end;
+       if (parseinfo) {
+               rjs_engine_dumpast(jse, script->str, script->size);
        }
-       rjs_parser_destroy(parser);
+
+       if (debugcompileonly) {
+               jse->debugcompile = 1;
+               rjs_engine_compile(jse, script->str, script->size);
+               jse->debugcompile = 0;
+       }
+
+end:
+       rjs_engine_destroy(jse);
        if (unmapscript)
                rjs_unmap_file(unmapscript);
+       if (debuginfo)
+               fprintf(stdout, "\nRJS Version: %s, memory: %ld KB (leaked %ld Bytes)\n", rjs_version(), (rlong)r_debug_get_maxmem()/1000, (rlong)r_debug_get_allocmem());
        return 0;
 }
diff --git a/rjs/rjsuids.h b/rjs/rjsuids.h
new file mode 100644 (file)
index 0000000..290d923
--- /dev/null
@@ -0,0 +1,4 @@
+#define RJS_PROGRAM 1
+#define RJS_POSTFIXEXPRESSIONVALOP 2
+#define RJS_EXPRESSION 3
+#define RJS_LEFTHANDSIDEEXPRESSION 4
index 1e600b5..9c65c19 100644 (file)
@@ -100,7 +100,7 @@ static rint rpa_record2long(rparecord_t *prec, ruint32 *num)
        rchar *endptr = NULL;
        rchar buffer[64];
 
-       if (prec->inputsiz == 0 || prec->inputsiz >= sizeof(buffer))
+       if (!prec || !num || prec->inputsiz == 0 || prec->inputsiz >= sizeof(buffer))
                return -1;
        r_memset(buffer, 0, sizeof(buffer));
        r_memcpy(buffer, prec->input, prec->inputsiz);
@@ -125,13 +125,18 @@ static rint rpa_dbex_rh_uid(rpadbex_t *dbex, rlong rec)
 
        if (prec->type & RPA_RECORD_START) {
                if (rpa_dbex_rulename(dbex, rec, &name, &namesize) < 0) {
+                       RPA_DBEX_SETERRINFO_CODE(dbex, RPA_E_SYNTAX_ERROR);
                        return -1;
                }
                pnumrec = rpa_dbex_record(dbex, rpa_recordtree_lastchild(dbex->records, rec, RPA_RECORD_END));
-               if (!pnumrec)
+               if (!pnumrec) {
+                       RPA_DBEX_SETERRINFO_CODE(dbex, RPA_E_SYNTAX_ERROR);
                        return -1;
-               if (rpa_record2long(pnumrec, &uid) < 0)
+               }
+               if (rpa_record2long(pnumrec, &uid) < 0) {
+                       RPA_DBEX_SETERRINFO_CODE(dbex, RPA_E_SYNTAX_ERROR);
                        return -1;
+               }
                rpa_compiler_rulepref_set_ruleuid(dbex->co, name, namesize, uid);
        } else if (prec->type & RPA_RECORD_END) {
 
@@ -1212,6 +1217,47 @@ rint rpa_dbex_dumpinfo(rpadbex_t *dbex)
 }
 
 
+rint rpa_dbex_dumpalias(rpadbex_t *dbex)
+{
+       rlong i;
+       rlong rec;
+       rpa_ruleinfo_t *info;
+       rchar *buffer = r_zmalloc(32 * sizeof(rchar));
+
+       if (!dbex)
+               return -1;
+       if (!dbex->rules) {
+               RPA_DBEX_SETERRINFO_CODE(dbex, RPA_E_NOTCLOSED);
+               return -1;
+       }
+       for (i = 0; i < r_array_length(dbex->rules->names); i++) {
+               info = (rpa_ruleinfo_t *)r_harray_get(dbex->rules, i);
+               if (info->type == RPA_RULEINFO_DIRECTIVE) {
+                       rparecord_t *prec = rpa_dbex_record(dbex, rpa_recordtree_get(dbex->records, info->startrec, RPA_RECORD_END));
+                       if (prec->ruleuid == RPA_PRODUCTION_DIRECTIVEUID && prec->inputsiz) {
+                               rec = rpa_recordtree_firstchild(dbex->records, info->startrec, RPA_RECORD_START);
+                               while (rec >= 0) {
+                                       prec = rpa_dbex_record(dbex, rpa_recordtree_get(dbex->records, rec, RPA_RECORD_END));
+                                       if (prec->ruleuid == RPA_PRODUCTION_ALIASNAME) {
+                                               ruint32 dec;
+                                               if (rpa_record2long(rpa_dbex_record(dbex, rpa_recordtree_next(dbex->records, rec, RPA_RECORD_END)), &dec) < 0)
+                                                       break;
+                                               buffer = r_realloc(buffer, prec->inputsiz + 1);
+                                               r_memset(buffer, 0, prec->inputsiz + 1);
+                                               r_memcpy(buffer, prec->input, prec->inputsiz);
+                                               r_printf("#define %s %d\n", buffer, dec);
+                                               break;
+                                       }
+                                       rec = rpa_recordtree_next(dbex->records, rec, RPA_RECORD_START);
+                               }
+                       }
+               }
+       }
+       r_free(buffer);
+       return 0;
+}
+
+
 rint rpa_dbex_dumpcode(rpadbex_t* dbex, const rchar *rulename)
 {
        rpa_ruleinfo_t *info;
index faf4dd1..0b23fd4 100644 (file)
@@ -63,6 +63,7 @@ rint rpa_dbex_dumptree(rpadbex_t *dbex, const rchar *rulename, rsize_t namesize,
 rint rpa_dbex_dumprules(rpadbex_t *dbex);
 rint rpa_dbex_dumpinfo(rpadbex_t *dbex);
 rint rpa_dbex_dumpcode(rpadbex_t* dbex, const rchar *rule);
+rint rpa_dbex_dumpalias(rpadbex_t *dbex);
 
 #define RPA_DBEXCFG_OPTIMIZATIONS 1
 rlong rpa_dbex_cfgset(rpadbex_t *dbex, rulong cfg, rulong val);
index 24438e8..3b083e0 100644 (file)
@@ -186,6 +186,8 @@ static void rpa_production_directive_uid(rpa_parser_t *pa)
        rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
        rpa_compiler_reference_nan_s(co, "space");
        rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
+       rpa_compiler_reference_opt_s(co, "aliasname");
+       rpa_compiler_reference_opt_s(co, "space");
        rpa_compiler_reference_nan_s(co, "dec");
        rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
 
@@ -433,6 +435,37 @@ static void rpa_production_rulename(rpa_parser_t *pa)
 }
 
 
+static void rpa_production_aliasname(rpa_parser_t *pa)
+{
+       rpa_compiler_t *co = pa->co;
+
+       rpa_compiler_rulepref_set_ruleuid_flags_s(co, "aliasname", RPA_PRODUCTION_ALIASNAME, RPA_RFLAG_EMITRECORD);
+       rpa_compiler_rule_begin_s(co, "aliasname");
+
+       rpa_compiler_class_begin(co, RPA_MATCH_NONE);
+       rvm_codegen_addins(co->cg, rvm_asm2(RPA_MATCHRNG_NAN, DA, XX, XX, 'a', 'z'));
+       rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BGRE, DA, XX, XX, 0));
+       rvm_codegen_addins(co->cg, rvm_asm2(RPA_MATCHRNG_NAN, DA, XX, XX, 'A', 'Z'));
+       rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BGRE, DA, XX, XX, 0));
+       rpa_compiler_class_end(co);
+       rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
+
+       rpa_compiler_class_begin(co, RPA_MATCH_MULTIOPT);
+       rvm_codegen_addins(co->cg, rvm_asm2(RPA_MATCHRNG_NAN, DA, XX, XX, 'a', 'z'));
+       rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BGRE, DA, XX, XX, 0));
+       rvm_codegen_addins(co->cg, rvm_asm2(RPA_MATCHRNG_NAN, DA, XX, XX, 'A', 'Z'));
+       rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BGRE, DA, XX, XX, 0));
+       rvm_codegen_addins(co->cg, rvm_asm2(RPA_MATCHRNG_NAN, DA, XX, XX, '0', '9'));
+       rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BGRE, DA, XX, XX, 0));
+       rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR_NAN, DA, XX, XX, '_'));
+       rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BGRE, DA, XX, XX, 0));
+       rpa_compiler_class_end(co);
+       rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
+
+       rpa_compiler_rule_end(co);
+}
+
+
 static void rpa_production_assign(rpa_parser_t *pa)
 {
        rpa_compiler_t *co = pa->co;
@@ -1420,6 +1453,7 @@ static rint rpa_parser_init(rpa_parser_t *pa)
        rpa_production_space(pa);
        rpa_production_assign(pa);
        rpa_production_rulename(pa);
+       rpa_production_aliasname(pa);
        rpa_production_namedrule(pa);
        rpa_production_anonymousrule(pa);
        rpa_production_comment(pa);
index 925f59a..b21fc12 100644 (file)
@@ -15,6 +15,7 @@ enum {
        RPA_PRODUCTION_BNF,
        RPA_PRODUCTION_NAMEDRULE,
        RPA_PRODUCTION_ANONYMOUSRULE,
+       RPA_PRODUCTION_ALIASNAME,
        RPA_PRODUCTION_RULENAME,
        RPA_PRODUCTION_REGEXCHAR,
        RPA_PRODUCTION_CHAR,