Micro Parser Combinators(mpc)以无限循环运行

时间:2015-04-10 20:15:08

标签: c++ c parsing mpc

我正在用C ++编写一个编译器(使用Visual Studio)来编写一个小脚本语言,我使用this C parsing library

所以,我按照文档中的说明进行操作,最后我得到了代码的和平:

int main()
{
    mpc_parser_t* Int = mpc_new("int");
    mpc_parser_t* Char = mpc_new("char");
    mpc_parser_t* String = mpc_new("string");
    mpc_parser_t* Id = mpc_new("id");
    mpc_parser_t* Type = mpc_new("type");
    mpc_parser_t* Formal = mpc_new("formal");
    mpc_parser_t* Header = mpc_new("header");
    mpc_parser_t* FuncDecl = mpc_new("funcdecl");
    mpc_parser_t* VarDef = mpc_new("vardef");
    mpc_parser_t* Expr = mpc_new("expr");
    mpc_parser_t* Call = mpc_new("call");
    mpc_parser_t* Atom = mpc_new("atom");
    mpc_parser_t* Simple = mpc_new("simple");
    mpc_parser_t* SimpleList = mpc_new("simplelist");
    mpc_parser_t* Stmt = mpc_new("stmt");
    mpc_parser_t* FuncDef = mpc_new("funcdef");
    mpc_parser_t* Program = mpc_new("program");

    /* Define them with the following Language */
    mpca_lang(MPCA_LANG_DEFAULT,
    "                                                                                        \
    int        : /-?[0-9]+/                                                                ; \
    char       : /'[a-zA-Z0-9!@#$%^&*()\\_+-,.\\/<>?;'|\"`~]'/                             ; \
    string     : /\"(\\\\.|[^\"])*\"/                                                      ; \
    id         : /[a-zA-Z][a-zA-Z0-9_-]*/                                                  ; \
    type       : \"int\" | \"bool\" | \"char\" | <type> '[' ']' | \"list\" '[' <type> ']'  ; \
    formal     : (\"ref\")? <type> <id> (',' <id>)*                                        ; \
    header     : <type>? <id> '(' (<formal> (';' <formal>)*)? ')'                          ; \
    funcdecl   : \"decl\" <header>                                                         ; \
    vardef     : <type> <id> (',' <id>)*                                                   ; \
    expr       : <atom> | <int> | <char> | '(' <expr> ')'                                    \
                 | ('+' | '-') <expr> | <expr> ('+' | '-' | '*' | '/' | \"mod\") <expr>      \
                 | <expr> ('=' | \"<>\" | '<' | '>' | \"<=\" | \">=\") <expr>                \
                 | \"true\" | \"false\" | \"not\" <expr> | <expr> (\"and\" | \"or\") <expr>  \
                 | \"new\" <type> '[' <expr> ']' | \"nil\" | \"nil?\" '(' <expr> ')'         \
                 | <expr> '#' <expr> | \"head\" '(' <expr> ')' | \"tail\" '(' <expr> ')'   ; \
    call       : <id> '(' (<expr> (',' <expr>)*)? ')'                                      ; \
    atom       : <id> | <string> | <atom> '[' <expr> ']' | <call>                          ; \
    simple     : \"skip\" | <atom> \":=\" <expr> | <call>                                  ; \
    simplelist : <simple> (',' <simple>)*                                                  ; \
    stmt       : <simple> | \"exit\" | \"return\" <expr>                                     \
                 | \"if\" <expr> ':' <stmt>+ (\"elif\" <expr> ':' <stmt>+)*                  \
                     (\"else\" ':' <stmt>+)? \"end\"                                         \
                 | \"for\" <simplelist> ';' <expr> ';' <simplelist> ':' <stmt>+ \"end\"    ; \
    funcdef    : \"def\" <header> ':' (<funcdef> | <funcdecl> | <vardef>)* <stmt>+ \"end\" ; \
    program    : /^/ <funcdef> /$/                                                         ; \
    ",
    Int, Char, String, Id, Type, Formal, Header, FuncDecl, VarDef, Expr,
    Call, Atom, Simple, SimpleList, Stmt, FuncDef, Program);

    mpc_result_t r;
    char* input = "def hey () : return 1 end";
    if(mpc_parse("input", input, Program, &r))
    {
        mpc_ast_print((mpc_ast_t*)r.output);
        mpc_ast_delete((mpc_ast_t*)r.output);
    }
    else
    {
        mpc_err_print(r.error);
        mpc_err_delete(r.error);
    }

    PAUSE("Press any key to continue . . .");

    /* Undefine and Delete our Parsers */
    mpc_cleanup(17, Int, Char, String, Id, Type, Formal, Header, FuncDecl, VarDef, Expr,
                Call, Atom, Simple, SimpleList, Stmt, FuncDef, Program);
    return 0;
}

问题是我在mpc_parse遇到了一个巨大的循环。那个循环实际上从未到达终点。一段时间后,我得到了这个例外:

Unhandled exception at 0x00CBBC9C in TonyCC.exe: 0xC0000005: Access violation reading location 0x0000000C.

我不知道为什么。我怀疑我的语法有问题,但我无法弄清楚是什么。

如果之前有人使用过此库,您是否知道问题可能是什么?

注意:我知道很难从C代码中读取语法,所以这里是语法的图像:

enter image description here

0 个答案:

没有答案