使用 Flex/Lex 识别函数调用模式
Recognizing function call pattern with Flex/Lex
我正在尝试编写一个 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(->attr.name, "output") == 0)
{
/*code for output system call*/
}
else if(strcmp(->attr.name, "input") == 0)
{
/*code for input system call*/
} else{
/*code for other function activations*/
}
}
;
array[0]
或 array[1]
呢?他们被允许吗?我看不出 fun_dec1 如何匹配,因为这里没有指定 return 类型 - 我猜你的语法中也有一个函数调用定义,它肯定会匹配吗?
一个函数调用语法定义就足够了,我不确定您为什么要将 input
/output
函数硬编码到语法中。
假设您有一个识别函数声明的产生式:
fun_decl: type ID LPAREN params RPAREN comp_decl;
你有一个产品来识别函数调用似乎是合理的:
expr : /* ... */
| ID LPAREN arguments RPAREN
arguments: /* empty */
| exprs
exprs : expr
| exprs COMMA expr
这涵盖了语法部分。尝试在词法分析器中执行任何此类操作都会违反词法分析和语法分析之间的明确区别,您可能需要复习一下。 (另外,正如您所发现的那样,它会被证明是不可行的。)
在语义操作中,您需要检查函数调用中的 ID
是什么,如果它是系统调用,则插入适当的代码。
我正在尝试编写一个 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
我的问题是只有 fun_decl
被匹配,但我跑题了。
总而言之,如何将 output(var)
或 output(array[i])
与模式匹配?有可能吗?
编辑1: 在阅读了@rici 的回复后,我设法为作品想出了这段代码,将所有内容从 Lex/Flex 移开,只处理 Bison-YACC(为清楚起见省略了其余代码):
ativacao : id LPAREN args RPAREN
{
if(strcmp(->attr.name, "output") == 0)
{
/*code for output system call*/
}
else if(strcmp(->attr.name, "input") == 0)
{
/*code for input system call*/
} else{
/*code for other function activations*/
}
}
;
array[0]
或 array[1]
呢?他们被允许吗?我看不出 fun_dec1 如何匹配,因为这里没有指定 return 类型 - 我猜你的语法中也有一个函数调用定义,它肯定会匹配吗?
一个函数调用语法定义就足够了,我不确定您为什么要将 input
/output
函数硬编码到语法中。
假设您有一个识别函数声明的产生式:
fun_decl: type ID LPAREN params RPAREN comp_decl;
你有一个产品来识别函数调用似乎是合理的:
expr : /* ... */
| ID LPAREN arguments RPAREN
arguments: /* empty */
| exprs
exprs : expr
| exprs COMMA expr
这涵盖了语法部分。尝试在词法分析器中执行任何此类操作都会违反词法分析和语法分析之间的明确区别,您可能需要复习一下。 (另外,正如您所发现的那样,它会被证明是不可行的。)
在语义操作中,您需要检查函数调用中的 ID
是什么,如果它是系统调用,则插入适当的代码。