忽略每个令牌,但忽略规则中的令牌

时间:2017-12-04 07:47:34

标签: bison flex-lexer yacc lex

所以,我试图在flex / bison中创建一个简单的C语法分析器,我只需要解析函数和变量声明及其用法。

示例,使用yyin = fopen()我想解析这个.c文件:

#include <stdio.h>
int main()
{
    int firstNumber, secondNumber, sumOfTwoNumbers;

    printf("Enter two integers: ");

    // Two integers entered by user is stored using scanf() function
    scanf("%d %d", &firstNumber, &secondNumber);

    // sum of two numbers in stored in variable sumOfTwoNumbers
    sumOfTwoNumbers = firstNumber + secondNumber;

    // Displays sum
    printf("%d + %d = %d", firstNumber, secondNumber, sumOfTwoNumbers);

    return 0;
}

解析器应检测

  

int firstNumber, secondNumber, sumOfTwoNumbers;

作为变量声明,并计算变量的每次使用。

我已经可以这样做了,事情是,我只需要解析那些特定情况,而不是像“=,+”标记或//注释那样,但它们可以在文件中。

我希望有一种方法可以忽略每个令牌但是那些匹配规则的令牌,以便yyparse在无法识别令牌时不会调用yyerror,所以解析文件的时候我只做函数/ var声明的动作,其他所有内容都可以顺利运行直到EOF。

1 个答案:

答案 0 :(得分:0)

您的第一个要求相对容易满足:C中的每个变量声明都以说明符和限定符列表开头,因此您的规则可能如下所示: var_declaration: spec_or_qual_list identifiers ';' { ... }以及一些规则,例如

func: 
  spec_or_qual_list identifier '(' well_nested_tokens ')'';' {...}
| spec_or_qual_list identifier 
  '(' well_nested_tokens ')''{' body_tokens '}' {...}
| other_token well_nested_tokens ';' { ... process uses ... } 

body_tokens:
  %empty                        {...}
| body_tokens var_declaration {...}
| body_tokens func             {...}

请注意,上述简单规则只能解析“平面”问题。 C文件就像你在问题中给出的那样(没有结构声明的函数和声明列表或者函数体之外的其他块)。

一旦你决定添加块,你就必须添加类似于上面func的规则,这样你就可以递归下降到块并解析那里的声明。你不能简单地忽略它们,因为那样你就会错过块之后可能出现的声明的开头。如果你让结构进入,你有一个更难以区分结构成员和变量的任务(或者你可能不希望在哪种情况下结构可以作为块处理,仅在语法上,因为范围规则是非常不同的)。请注意,所有这些方法都忽略了作用域规则,因此,在您的情况下,您将无法跟踪变量与其声明之间的关联(因为变量可以在块内重新声明为完全不同的东西)。最后,如果你允许使用typedef名称,那么所有的地狱都会崩溃(查找&#39; lexer hack&#39;)你也可以写一个完整的解析器。

所有这些的道德是:如果你试图解析的文件有任何类型的非平凡结构,你最终将解析C语法的重要部分。我可以建议的另一个简化技巧是为C 表达式编写一个(完整)解析器并使用它来解析C 声明符(例如(* pfunc)(int))。这不适用于所有C11声明者,但会处理大多数普通的声明。那些。你仍然需要处理块。