%token <lexeme> LPAREN RPAREN LBRACE RBRACE LSQUARE RSQUARE
时间: 2024-03-29 13:34:16 浏览: 169
这里的LPAREN、RPAREN、LBRACE、RBRACE、LSQUARE、RSQUARE是一些常见的标点符号,在编程语言中也有着重要的作用。它们分别代表着左圆括号、右圆括号、左花括号、右花括号、左方括号和右方括号。在编程语言中,这些符号通常用于表示代码块的开始和结束位置,进行函数调用时也需要使用这些符号来标记参数列表的起始和结束位置。
相关问题
#include <iostream> #include <string> using namespace std; enum TokenType { BEGIN, IF, THEN, WHILE, DO, END, ID, NUM, ASSIGN, PLUS, MINUS, MUL, DIV, LPAREN, RPAREN, SEMICOLON, LESS, GREATER, NEQ, LESS_EQUAL, GREATER_EQUAL, END_OF_FILE, COLON }; struct Token { TokenType type; string lexeme; }; Token currentToken; void getNextToken() { // 词法分析的代码,略去不写,将结果保存在currentToken中 } void match(TokenType expectedType) { if (currentToken.type == expectedType) { getNextToken(); } else { cout << "error" << endl; exit(1); } } void program(); void stmts(); void stmt(); void exp(); void items(); void item(); void factors(); void factor(); void program() { match(BEGIN); stmts(); match(END); } void stmts() { stmt(); while (currentToken.type == SEMICOLON) { match(SEMICOLON); stmt(); } } void stmt() { if (currentToken.type == ID) { match(ID); match(ASSIGN); exp(); } else { cout << "error" << endl; exit(1); } } void exp() { item(); items(); } void items() { if (currentToken.type == PLUS || currentToken.type == MINUS) { match(currentToken.type); item(); items(); } } void item() { factor(); factors(); } void factors() { if (currentToken.type == MUL || currentToken.type == DIV) { match(currentToken.type); factor(); factors(); } } void factor() { if (currentToken.type == ID || currentToken.type == NUM) { match(currentToken.type); } else if (currentToken.type == LPAREN) { match(LPAREN); exp(); match(RPAREN); } else { cout << "error" << endl; exit(1); } } int main() { // 词法分析部分的代码,略去不写,将结果保存在currentToken中 program(); if (currentToken.type == TokenType::END_OF_FILE) { cout << "success" << endl; } else { cout << "error" << endl; } return 0; }
这段代码中存在一个问题,就是头文件和using namespace std;之间没有加换行符,导致编译器无法识别头文件。
正确的代码应该是:
```cpp
#include <iostream>
#include <string>
using namespace std;
enum TokenType {
BEGIN, IF, THEN, WHILE, DO, END, ID, NUM, ASSIGN, PLUS, MINUS, MUL, DIV, LPAREN, RPAREN, SEMICOLON, LESS, GREATER, NEQ, LESS_EQUAL, GREATER_EQUAL, END_OF_FILE, COLON
};
struct Token {
TokenType type;
string lexeme;
};
Token currentToken;
void getNextToken() {
// 词法分析的代码,略去不写,将结果保存在currentToken中
}
void match(TokenType expectedType) {
if (currentToken.type == expectedType) {
getNextToken();
}
else {
cout << "error" << endl;
exit(1);
}
}
void program();
void stmts();
void stmt();
void exp();
void items();
void item();
void factors();
void factor();
void program() {
match(BEGIN);
stmts();
match(END);
}
void stmts() {
stmt();
while (currentToken.type == SEMICOLON) {
match(SEMICOLON);
stmt();
}
}
void stmt() {
if (currentToken.type == ID) {
match(ID);
match(ASSIGN);
exp();
}
else {
cout << "error" << endl;
exit(1);
}
}
void exp() {
item();
items();
}
void items() {
if (currentToken.type == PLUS || currentToken.type == MINUS) {
match(currentToken.type);
item();
items();
}
}
void item() {
factor();
factors();
}
void factors() {
if (currentToken.type == MUL || currentToken.type == DIV) {
match(currentToken.type);
factor();
factors();
}
}
void factor() {
if (currentToken.type == ID || currentToken.type == NUM) {
match(currentToken.type);
}
else if (currentToken.type == LPAREN) {
match(LPAREN);
exp();
match(RPAREN);
}
else {
cout << "error" << endl;
exit(1);
}
}
int main() {
// 词法分析部分的代码,略去不写,将结果保存在currentToken中
program();
if (currentToken.type == TokenType::END_OF_FILE) {
cout << "success" << endl;
}
else {
cout << "error" << endl;
}
return 0;
}
```
下面是简单C语言的词法: 1.关键字: else if int return void while 所有的关键字都是保留字,并且必须是小写。 2. 下面是专用符号: + - * / < <= > >= == != = ; , ( ) [ ] { } 3. 其他标记是ID 和NUM ,通过下列正则表达式定义: ID = letter letter* NUM = digit digit* letter = a|..|z|A|..|Z digit = 0|..|9 小写和大写字母是有区别的。 请利用flex生成上述语言的词法分析器。要求写出详细的步骤和相应的flex源程序。
步骤如下:
1. 安装flex
2. 创建文件 lexer.l
3. 在 lexer.l 中编写以下代码:
```flex
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
%}
%option noyywrap
%%
// 关键字
else { return ELSE; }
if { return IF; }
int { return INT; }
return { return RETURN; }
void { return VOID; }
while { return WHILE; }
// 专用符号
"+" { return PLUS; }
"-" { return MINUS; }
"*" { return TIMES; }
"/" { return OVER; }
"<" { return LT; }
"<=" { return LE; }
">" { return GT; }
">=" { return GE; }
"==" { return EQ; }
"!=" { return NE; }
"=" { return ASSIGN; }
";" { return SEMI; }
"," { return COMMA; }
"(" { return LPAREN; }
")" { return RPAREN; }
"[" { return LBRACK; }
"]" { return RBRACK; }
"{" { return LBRACE; }
"}" { return RBRACE; }
// ID
[a-zA-Z]+[a-zA-Z0-9]* { return ID; }
// NUM
[0-9]+ { return NUM; }
// 空格、制表符和换行符
[ \t\n] { /* do nothing */ }
// 注释
"/*" { /* do nothing */ }
"*/" { /* do nothing */ }
"//" { /* do nothing */ }
. { return ERROR; }
%%
int main(int argc, char **argv)
{
yyin = fopen(argv[1], "r");
yyout = fopen("output.txt", "w");
int token;
while ((token = yylex())) {
switch (token) {
case ID:
fprintf(yyout, "ID\n");
break;
case NUM:
fprintf(yyout, "NUM\n");
break;
case ELSE:
fprintf(yyout, "ELSE\n");
break;
case IF:
fprintf(yyout, "IF\n");
break;
case INT:
fprintf(yyout, "INT\n");
break;
case RETURN:
fprintf(yyout, "RETURN\n");
break;
case VOID:
fprintf(yyout, "VOID\n");
break;
case WHILE:
fprintf(yyout, "WHILE\n");
break;
case PLUS:
fprintf(yyout, "PLUS\n");
break;
case MINUS:
fprintf(yyout, "MINUS\n");
break;
case TIMES:
fprintf(yyout, "TIMES\n");
break;
case OVER:
fprintf(yyout, "OVER\n");
break;
case LT:
fprintf(yyout, "LT\n");
break;
case LE:
fprintf(yyout, "LE\n");
break;
case GT:
fprintf(yyout, "GT\n");
break;
case GE:
fprintf(yyout, "GE\n");
break;
case EQ:
fprintf(yyout, "EQ\n");
break;
case NE:
fprintf(yyout, "NE\n");
break;
case ASSIGN:
fprintf(yyout, "ASSIGN\n");
break;
case SEMI:
fprintf(yyout, "SEMI\n");
break;
case COMMA:
fprintf(yyout, "COMMA\n");
break;
case LPAREN:
fprintf(yyout, "LPAREN\n");
break;
case RPAREN:
fprintf(yyout, "RPAREN\n");
break;
case LBRACK:
fprintf(yyout, "LBRACK\n");
break;
case RBRACK:
fprintf(yyout, "RBRACK\n");
break;
case LBRACE:
fprintf(yyout, "LBRACE\n");
break;
case RBRACE:
fprintf(yyout, "RBRACE\n");
break;
case ERROR:
fprintf(yyout, "ERROR\n");
break;
default:
break;
}
}
fclose(yyin);
fclose(yyout);
return 0;
}
```
4. 在终端中输入以下命令编译并运行:
```bash
flex lexer.l
gcc lex.yy.c -o lexer
./lexer input.c
```
其中,input.c 是需要进行词法分析的 C 语言源文件。
5. 运行结果会输出到 output.txt 文件中。
阅读全文