2013-06-04 34 views
1

我對Ragel有點問題,主要原因是仍然試圖掌握整個事情的工作原理。我試圖做一個類似於SQL(但不太靈活)的語言,你有函數(全部大寫),標識符(全部小寫),你可以在函數內嵌套功能的地方做一個簡單的解析器。用於解析類似SQL的語句的Ragel FSM

這是我到目前爲止有:

#include <stdlib.h> 
#include <string.h> 
#include <stdio.h> 

typedef struct Parser { 
    int current_line; 
    int nesting; 

    /* Ragel FSM */ 
    int cs; 
    const char *ts; 
    const char *te; 
    int act; 
} Parser; 

%%{ 
    machine gql; 
    access parser->; 

    Function = [A-Z][A-Z_]+ ; 

    Identifier = [a-z][a-z_]+ ; 
    Integer  = [0-9]+ ; 

    Parameter = (Identifier | Integer)+ ; 

    WhiteSpace = [ \t\r\n] ; 

    action function_call { 
    parser->nesting++; 
    printf("FUNCTION CALL\n"); 
    } 

    action function_finish { 
    parser->nesting--; 
    printf("FUNCTION FINISH!\n"); 
    } 

    action function_add_identifier { 
    printf("FUNCTION ADD IDENTIFIER\n"); 
    } 

    FunctionCall = 
    Function @function_call WhiteSpace* "(" 
     Parameter %function_add_identifier 
     (WhiteSpace* ',' WhiteSpace* Parameter %function_add_identifier)* WhiteSpace* 
    %function_finish ')' ; 

    main := FunctionCall ; 
}%% 


%% write data; 

void Parser_Init(Parser *parser) { 
    parser->current_line = 1; 
    parser->nesting  = 0; 
    %% write init; 
} 

void Parser_Execute(Parser *parser, const char *buffer, size_t len) { 
    if(len == 0) return; 

    const char *p, *pe, *eof; 
    p = buffer; 
    pe = buffer+len; 
    eof = pe; 

    %% write exec; 
} 

int main(int argc, char *argv[]) { 
    Parser *parser = malloc(sizeof(Parser)); 
    Parser_Init(parser); 

    printf("Parsing:\n%s\n\n\n", argv[1]); 

    Parser_Execute(parser, argv[1], sizeof(argv[1])); 

    printf("Parsed %d lines\n", parser->current_line); 
    return 0; 
} 

這是每個字符調用function_call動作一次,而不是拿起Parameter秒,我想不出如何使功能在裏面工作的功能。

關於我在做什麼錯誤的提示?

回答

4

標準方法是創建一個詞法分析器(用Ragel或GNU Flex編寫),它可以標記您的語言輸入。這些令牌然後被解析器(不是用Ragel寫的)解析遞歸結構(例如嵌套函數) - 使用像GNU Bison這樣的解析器生成器。

請注意,Ragel包含(作爲高級功能)指令來管理堆棧(它使您可以解析遞歸結構) - 但是由於您離開了常規語言的域,否則您正在使用ragel規範。因此,你可以編寫一個解析器,它能夠用Ragel完全解析嵌套函數。但是,一個正確的分層架構(第一層:詞法分析器,第二層:分析器,...)簡化了任務,即部件更易於調試,測試和維護。