Flex/Bison 开始条件

Flex/Bison start condition

如何在规则开始时启用开始条件并在规则结束时禁用它?我必须仅使用一些野牛规则来忽略空格。 如何忽略嵌套括号内的空格。

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)

词法分析器和解析器部分实现。我的问题是如何处理@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
;

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

I have to ignore whitespace with some bison rules only. How to ignore whitespace inside nested brackets.

正如我在评论中所说,您通过让解析器规则操纵扫描器启动条件以某种方式执行此操作的实现想法几乎是行不通的。算了。

因为显然您的扫描器 不会 ,一般来说,忽略空格,它必须发出代表空格的标记,或者可能代表其他东西加上空格的标记(丑陋)。如果它发出空白标记,那么要做的就是在你的语法规则中考虑它们。这是完全可能的。事实上,您可以在扫描器之上为任何上下文无关语言构建一个解析器,该扫描器只是 returns 每个字符都作为其自己的标记。扫描器/解析器二分法是一种功能和概念上的便利,而不是必需的。

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

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
  ;

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