Flex / Bison启动条件

时间:2018-07-06 20:28:36

标签: c bison flex-lexer

如何在规则的开头启用开始条件并在规则的结尾禁用它?我只需要用一些野牛规则来忽略空白。 如何忽略嵌套括号内的空格。

define_directive:
    DEFINE '(' class_name ')'{ ... }
;

我正在尝试为此示例代码编写一个解析器,并提供更多规则。

@/*
  * @Template Family
  * @Description sample script template for Mate Programming language
  * (multi-line comment)
  */

@namespace(sample)

@require(String fatherName)
@require(String motherName)
@require(Array childrenNames)
@define(Family : Template) @// end of header anything can go in body section below (comment)

Family Description
==================

    Father's Name: @(fatherName)
    Mother's Name: @(motherName)
    Number of child: @(childrenNamesCount,0) @// valuation operator is null safe (comment)

    List of children's names
    ------------------------
    @foreach(childName:childrenNames)
        > @(childName)
    @empty
        > there is no child name to display.
    @end

    @@(varName) @// this should not be interpreted because escaped with @ (comment)

Lexer和解析器已部分实现。我的问题是如何处理@ foreach,@ require之类的语句关键字内的空格。 对于这些,应该忽略空格。

所需的样品输出

Family Description
==================

    Father's Name: Mira
    Mother's Name: James
    Number of child: 0

    List of children's names
    ------------------------

        > there is no child name to display.

    @@(varName)

野牛文件内容

command:
    fileword
    | valuation
    | alternative
    | loop
    | command_directive
;
fileword: 
    tokenword { scriptlangy_echo(yytext,"fileword.tokenword"); }
    | MAGICESC { scriptlangy_echo("@","fileword.MAGICESC"); }
;
tokenword:
    IDENTIFIER | NUMBER | STRING_LITERAL | WHITESPACE
    | INC_OP | DEC_OP | AND_OP | OR_OP | LE_OP | GE_OP | EQ_OP | NE_OP | L_OP | G_OP
    | ';' | ',' | ':' | '=' | ']' | '.' | '&' | '[' | '!' | '~' | '-' | '+' | '*' | '/' | '%' | '^' | '|' | ')' | '}' | '?' | '{' | '('
;
valuation:
    '@' '(' expression ')' {
        fprintf(yyout, "<val>");
    }
    | '@' '(' expression ',' default_value ')' {
        fprintf(yyout, "<val>");
    }
;
loop:
    for_loop
    | foreach_loop
    | while_loop
;
while_loop:
    WHILE '(' expression ')' end_block
    | WHILE '(' expression ')' commands end_block
;
for_loop:
    FOR '(' expression_statement expression_statement expression')' end_block
    | FOR '(' expression_statement expression_statement expression')' commands end_block
;
foreach_loop:
    foreach_block end_block
    | foreach_block empty_block end_block
;
foreach_block:
    FOREACH '(' IDENTIFIER ')'
    | FOREACH '(' IDENTIFIER ':' expression')' commands
;

1 个答案:

答案 0 :(得分:1)

您的问题的关键部分似乎是这样:

  

我只用一些野牛规则来忽略空白。如何忽略   嵌套括号内的空白。

正如我在评论中提到的那样,您的解析器规则通过操纵扫描程序的启动条件以某种方式实现此目标的想法几乎是没有启动的。算了吧。

由于显然您的扫描仪不会,因此通常忽略空白,它必须发出表示空白的令牌,或者可能表示表示其他内容的令牌加上空白(难看)。如果它发出空白标记,那么要做的只是在语法规则中考虑它们。这是完全可能的。实际上,您可以在仅返回每个字符作为其自身标记的扫描器之上,为任何上下文无关的语言构建解析器。扫描仪/解析器二分法是功能上和概念上的便利,而不是必需的。

例如,假设我们希望能够解析数字数组文字,该数字文字是用大括号括起来的非空,逗号分隔的十进制数字列表,并在逗号和括号内具有可选的空格。进一步假设我们可以使用这些终端符号:

OPEN  // open brace
CLOSE // close brace
NUM   // maximal sequence of one or more decimal digits
COMMA // a comma
WS    // a maximal run of whitespace

然后我们可以编写以下规则:

array: array_start array_elements CLOSE;

array_start: OPEN
    | OPEN WS
  ;

array_elements: array_element
    | array_elements array_separator array_element
  ;

array_element: NUM
    | NUM WS
  ;

array_separator: COMMA
    | COMMA WS
  ;

当然,还有许多其他方法可以设置细节,但是,一般来说,是您使用解析器规则处理空格的方法:不是通过忽略它,而是通过接受