Ragel FSM用于解析类似SQL的语句

时间:2013-06-04 20:31:04

标签: lexer ragel

我对Ragel有点问题,主要原因是仍然试图掌握整个过程的运作方式。

我正在尝试为类似于SQL的语言(但不太灵活)创建一个简单的解析器,其中包含函数(全部大写),标识符(全部小写)以及可以在函数中嵌套函数的位置。

这是我到目前为止所拥有的:

#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,我无法想到如何让函数在函数内部工作。

关于我在这里做错了什么提示?

1 个答案:

答案 0 :(得分:4)

标准方法是创建一个词法分析器(用Ragel或GNU Flex编写),它只是标记你的语言输入。然后令牌由一个解析器(不是用Ragel编写)消耗,该解析器能够解析递归结构(例如嵌套函数) - 使用像GNU Bison这样的解析器生成器。

请注意,Ragel包含(作为高级功能)指令来管理堆栈(这使您能够解析递归结构) - 但是,您可以在ragel规范中保留您正在使用的常规语言域。因此,您可以编写一个能够使用Ragel完全解析嵌套函数的解析器。但是一个适当的分层架构(第一层:词法分析器,第二层:解析器......)简化了任务,即部件更容易调试,测试和维护。