使用Flex / Lex识别函数调用模式

时间:2018-06-27 04:19:07

标签: bison flex-lexer yacc

我正在尝试编写Cminus(C子集)编译器,但是我的教授要求我们能够将input()output()函数作为系统调用来处理(在上一学期实现的可以处理这些指令的RISC CPU。

对于input()部分,我在第一次尝试中就设法弄对了(只是做一个匹配"input()"的模式),但是问题出在output()上。由于此函数应该采用数组或变量作为参数,因此我假设在Lex模式上,我需要具有以下内容(引用我读到的here):

digito          [0-9]
numero          {digito}+
letra           [a-zA-Z]
identificador   {letra}+({letra}|{digito})*
input           "input()"
outputStart     "output("
outputSimple    {identificador}
outputComplex   {identificador}"["identificador"]"
outputEnd       ")"
output          {outputStart} ({outputSimple} | {outputComplex}){outputEnd}

但是我的语法有以下定义:

type: INT | VOID;
fun_decl: type ID LPAREN params RPAREN comp_decl;

其中ID是当Lex与identificador的字符串匹配时从Lex给Bison的令牌。

我的问题是只有fun_decl被匹配,但我离题了。

总而言之,如何将output(var)output(array[i])与模式匹配?甚至有可能吗?

编辑1: 阅读了@rici的回复后,我设法为产品制作了以下代码,将所有内容从Lex / Flex移开了,只处理了Bison-YACC(为清晰起见,其余代码被省略了):

ativacao    : id LPAREN args RPAREN
                {   
                    if(strcmp($1->attr.name, "output") == 0)
                    {
                        /*code for output system call*/
                    }
                    else if(strcmp($1->attr.name, "input") == 0)
                    {
                        /*code for input system call*/
                    } else{
                        /*code for other function activations*/
                    }
                }
            ;

2 个答案:

答案 0 :(得分:2)

鉴于您有一个产生式可以识别函数声明:

fun_decl: type ID LPAREN params RPAREN comp_decl;

您似乎有一个可以识别函数调用的产品:

expr     : /* ... */
         | ID LPAREN arguments RPAREN

arguments: /* empty */
         | exprs
exprs    : expr
         | exprs COMMA expr

这涵盖了语法部分。尝试在词法分析器中进行任何操作都违反了词法分析和语法分析之间的明显区别,您可能要检查一下。 (此外,正如您所发现的,这将是不可行的。)

在语义动作中,您需要检查函数调用中的ID是什么,并在发现是系统调用时插入适当的代码。

答案 1 :(得分:-1)

array[0]array[1]怎么样?他们被允许吗?我看不到fun_dec1如何匹配,因为这里没有指定返回类型-我猜您在语法中也有一个函数调用定义,肯定会与之匹配吗?

一个函数调用语法定义就足够了,我不确定为什么您要尝试将input / output函数硬编码为语法。