我必须为类似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 name_of_program和一个compalsory新行 我做了以下声明: 挠性
"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,因为它们是语言的一部分) 我写错了吗?我认为问题在于换行定义,但我不确定。
提前感谢您的回答。对不起,很长的帖子。
答案 0 :(得分:2)
通常,注释由词法分析器处理,而不是传递给解析器。如果您的语言真的像C一样,那么在大多数情况下,换行应该像任何其他空格一样对待。注释和引用的字符串是值得注意的例外。带引号的字符串通常由词法分析器使用开始状态捕获并传递给整个解析器。
您的flex代码使用的字符集太多了。如果您只想匹配一个特定字符,则无需创建集合;只需要放置角色,如果需要可以使用反斜杠。此外,.
表示任何非换行符。
此外,您没有name_of_program
令牌的任何定义。假设它是C风格的标识符,您可以在flex中声明标识符模式和标记,并将其传递给bison。
最后,您可能希望采用命名惯例,即对从flex传递给bison的标记使用全部大写,对于在野牛中使用的标记使用小写。
因此,根据您的描述,我有以下内容:
example.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; }
%%
example.y:
%%
programma: T_PROGRAM T_IDENTIFIER T_NEWLINE function STARTMAIN dec_var command ENDMAIN eof;
text:
| name text
| digit text;
%%
我不确定你需要eof
令牌。
我希望这会有所帮助。