2

我必须为类 c 语言创建一个词法和语法分析器。在这种语言中,我们将注释定义为“在符号 % 之后直到行尾存在的所有内容”。以下声明是否正确?

Flex
...
[%][^\n]*[\n]  { return T_COMMENT; }
[\n]   { return T_NEWLINE; }

Bison
...
comment:com text newline;
text: |name text|digit text;

...
com: T_COMMENT   { printf("%s",yytext); };
newline: T_NEWLINE  { printf("%s",yytext); };

我还需要定义引号“。以下是否正确(flex)?

"\""   { return T_QUOTE; }

flex 和 bison 输入文件中没有编译错误,但是当我使用用这种类似 c 语言编写的程序作为测试输入时,我在第 1 行得到了词法错误。这一行没有词法错误。我的程序必须以这样的方式开始:

"PROGRAM"  { return T_PROGRAM; }

野牛

%start programma
%token T_PROGRAM
...
programma:PROGRAM name newline function STARTMAIN dec_var command ENDMAIN eof;
...
PROGRAM: T_PROGRAM  { printf("%s",yytext); };
...

(大写的单词被定义为PROGRAM,因为它们是语言的一部分)我写错了吗?我认为问题在于换行定义,但我不确定。

提前感谢您的任何回答。对不起,很长的帖子。

4

1 回答 1

2

通常,注释由词法分析器处理,而不是传递给解析器。如果您的语言真正类似于 C,那么在大多数情况下,换行符应该像任何其他空格一样对待。注释和引用的字符串是值得注意的例外。带引号的字符串通常由词法分析器使用开始状态捕获并传递给整个解析器。

你的弹性代码使用了太多的字符集。如果您只想匹配一个特定的字符,则无需设置;只需放置字符,如果需要,使用反斜杠转义。此外,.表示任何非换行符。

name_of_program此外,您对令牌没有任何定义。假设它是一个 C 风格的标识符,您可以在 flex 中声明一个标识符模式和标记并将其传递给 bison。

最后,您可能希望采用命名约定,即对从 flex 传递给 bison 的标记使用全部大写,对在 bison 中使用的标记使用小写。

因此,根据您的描述,我有以下内容:

例子.l:

%%

\%.* /* comment */
\n { return T_NEWLINE; }
\' { return T_QUOTE; }
PROGRAM { return T_PROGRAM; }
[A-Za-z_][A-Za-z0-9_]* { yylval.id = yytext; return T_IDENTIFIER; }

%%

例子.y:

%%

programma: T_PROGRAM T_IDENTIFIER T_NEWLINE function STARTMAIN dec_var command ENDMAIN eof;

text: 
    | name text
    | digit text;

%%

我不确定你是否需要eof那里的令牌。

我希望这有帮助。

于 2010-09-12T03:13:49.370 回答