《编译原理》实验二:句法分析器 LL(1)
考虑下面的C语言子集的文法,其中<>括起来的为非终结符,粗体为终结符。
<program> --> <statement_list>
<statement_list> --> <statement>
| <statement> <statement_list>
<statement> --> <expression_statement>
| <selection_statement>
| <iteration_statement>
<expression_statement> --> ;
| <expression> ;
<expression> --> <assignment_expression>
| <assignment_expression> , <expression>
<assignment_expression> --> <equality_expression>
| ID = <assignment_expression>
<equality_expression> --> <relational_expression>
| <relational_expression> == <equality_expression>
| <relational_expression> != <equality_expression>
<relational_expression> --> <additive_expression>
| <additive_expression> < <relational_expression>
| <additive_expression> > <relational_expression>
| <additive_expression> <= <relational_expression>
| <additive_expression> >= <relational_expression>
<additive_expression> --> <multiplicative_expression>
| <multiplicative_expression> + <additive_expression>
| <multiplicative_expression> - <additive_expression>
<multiplicative_expression> --> <primary_expression>
| <primary_expression> * <multiplicative_expression>
| <primary_expression> / <multiplicative_expression>
<primary_expression> --> ID | NUM | STRING | ( <expression> )
<selection_statement> --> IF ( <expression> ) <statement>
<iteration_statement> --> WHILE ( <expression> ) <statement>
| DO <statement> WHILE ( <expression> ) ;
要求:对给定的C语言程序进行句法分析,输出得到的分析树。
例如,下面的源程序代码:
sum = 0.0;
x = 1.0;
while (x <= 100) sum = sum + x;
句法分析结果为:
<program>
|-- <statement_list>
|-- <statement>
| |-- <expression_statement>
| |-- <expression>
| | |-- <assignment_expression>
| | |-- ID
| | |-- =
| | |-- <assignment_expression>
| | |-- <equality_expression>
| | |-- <relational_expression>
| | |-- <additive_expression>
| | |-- <multiplicative_expression>
| | |-- <primary_expression>
| | |-- NUM
| |-- ;
|-- <statement_list>
|-- <statement>
| |-- <expression_statement>
| |-- <expression>
| | |-- <assignment_expression>
| | |-- ID
| | |-- =
| | |-- <assignment_expression>
| | |-- <equality_expression>
| | |-- <relational_expression>
| | |-- <additive_expression>
| | |-- <multiplicative_expression>
| | |-- <primary_expression>
| | |-- NUM
| |-- ;
|-- <statement_list>
|-- <statement>
|-- <iteration_statement>
|-- WHILE
|-- (
|-- <expression>
| |-- <assignment_expression>
| |-- <equality_expression>
| |-- <relational_expression>
| |-- <additive_expression>
| | |-- <multiplicative_expression>
| | |-- <primary_expression>
| | |-- ID
| |-- <=
| |-- <relational_expression>
| |-- <additive_expression>
| |-- <multiplicative_expression>
| |-- <primary_expression>
| |-- NUM
|-- )
|-- <statement>
|-- <expression_statement>
|-- <expression>
| |-- <assignment_expression>
| |-- ID
| |-- =
| |-- <assignment_expression>
| |-- <equality_expression>
| |-- <relational_expression>
| |-- <additive_expression>
| |-- <multiplicative_expression>
| | |-- <primary_expression>
| | |-- ID
| |-- +
| |-- <additive_expression>
| |-- <multiplicative_expression>
| |-- <primary_expression>
| |-- ID
|-- ;
递归下降分析法
文法的每个非终结符对应一个递归过程。分析过程就是从文法开始符出发执行一组递归过程,这样向下推导直到推出句子;或者说从根结点出发,自顶向下为输入串寻找一个最左匹配序列,建立一棵分析树。
在不含左递归和每个非终结符的所有候选式推导出的终结符号串的首字符集都两两不相交的条件下,就可能构造一个不带回溯的自顶向下的分析程序。这样的一个分析程序称为递归下降分析器。
void match (token t) {
if (lookahead == t)
lookahead = nexttoken;
else
error();
}
E -> TE'
void E() {
T();
E'();
}
E' -> +TE'∣ε
void E'() {
if (lookahead == '+'){
match ('+');
T();
E'();
}
}
T -> FT'
void T() {
F();
T'();
}
T' -> *FT'∣ε
void T'() {
if (lookahead =='*') {
match ('*');
F();
T'();
}
}
F -> (E)∣i
void F()
{
if (lookahead == 'i')
match ('i');
else if (lookahead =='(')
{
match ('(');
E();
if (lookahead ==')')
match (')');
else
error ();
}
else
error();
}
首先得提取左公因子、消除左递归后的文法
<program> --> <statement_list>
<statement_list> --> <statement> <statement_list’>
<statement_list’> --> ε | <statement_list>
<statement> --> <expression_statement> | <selection_statement> | <iteration_statement>
<expression_statement> --> ; | <expression> ;
<expression> --> <assignment_expression> <expression’>
<expression’> --> ε | , <expression>
<assignment_expression> -->
ID <assignment_expression’>
| NUM <multiplicative_expression’> <additive_expression’> <relational_expression’> <equality_expression’>
| STRING <multiplicative_expression’> <additive_expression’> <relational_expression’> <equality_expression’>
| (<expression>) <multiplicative_expression’> <additive_expression’> <relational_expression’> <equality_expression’>
<assignment_expression’> -->
<multiplicative_expression’><additive_expression’><relational_expression’> <equality_expression’>
| = <assignment_expression>
<equality_expression> --> <relational_expression> <equality_expression’>
<equality_expression’> --> ε | == <equality_expression> | != <equality_expression>
<relational_expression> --> <additive_expression> <relational_expression’>
<relational_expression’> --> ε | < <relational_expression> | > <relational_expression>
| <= <relational_expression> | >= <relational_expression>
<additive_expression> --> <multiplicative_expression> <additive_expression’>
<additive_expression’> --> ε | + <additive_expression> | - <additive_expression>
<multiplicative_expression> --> <primary_expression> <multiplicative_expression’>
<multiplicative_expression’> --> ε | * <multiplicative_expression>
| / <multiplicative_expression>
<primary_expression> --> ID | NUM | STRING | ( <expression> )
<selection_statement> --> IF ( <expression> ) <statement>
<iteration_statement> -->
WHILE ( <expression> ) <statement>
| DO <statement> WHILE ( <expression> ) ;
求得FIRST集:
First(<iteration_statement>) = { WHILE, DO }
First(<selection_statement>) = { IF }
First(<primary_expression>) = { ID, NUM, STRING, ( }
First(<multiplicative_expression’>) = { ε, *, / }
First(<multiplicative_expression>) = { ID, NUM, STRING, ( }
First(<additive_expression’>) = { ε , +, - }
First(<additive_expression>) = { ID, NUM, STRING, ( }
First(<relational_expression’>) = { ε , <, >, <=, >= }
First(<relational_expression>) = { ID, NUM, STRING, ( }
First(<equality_expression’>) = { ε , ==, != }
First(<equality_expression>) = { ID, NUM, STRING, ( }
First(<assignment_expression’>) = { ε , *, /, +, -, <, >, <=, >=, ==, != , = }
First(<assignment_expression>) = { ID, NUM, STRING, ( }
First(<expression’>) = { ε , , }
First(<expression>) = { ID, NUM, STRING, ( }
First(<expression_statement>) = { ;, ID, NUM, STRING, ( }
First(<statement>) = { ;, ID, NUM, STRING, (, IF, WHILE, DO }
First(<statement_list>) = { ;, ID, NUM, STRING, (, IF, WHILE, DO }
First(<statement_list’>) = { ε , ;, ID, NUM, STRING, (, IF, WHILE, DO }
First(<program>) = { ;, ID, NUM, STRING, (, IF, WHILE, DO }
求得FOLLOW集:
Follow(<program>) = { $ }
Follow(<statement_list>) = { $ }
Follow(<statement_list’>) = { $ }
Follow(<statement>) = { $, ;, ID, NUM, STRING, (, IF, WHILE, DO }
Follow(<expression_statement>) = { $, ;, ID, NUM, STRING, (, IF, WHILE, DO }
Follow(<expression>) = { ;, ) }
Follow(<expression’>) = { ;, ) }
Follow(<assignment_expression>) = { ;, ), , }
Follow(<assignment_expression’>) = { ;, ), , }
Follow(<equality_expression>) = { ;, ), , }
Follow(<equality_expression’>) = { ;, ), , }
Follow(<relational_expression’>) = { ==, !=, ;, ), , }
Follow(<relational_expression>) = { ==, !=, ;, ), , }
Follow(<additive_expression’>) = { <, >, <=, >=, ==, !=, ;, ), , }
Follow(<additive_expression>) = { <, >, <=, >=, ==, !=, ;, ), , }
Follow(<multiplicative_expression’>) = { +, -, <, >, <=, >=, ==, !=, ;, ), , }
Follow(<multiplicative_expression>) = { +, -, <, >, <=, >=, ==, !=, ;, ), , }
Follow(<primary_expression>) = { *, /, +, -, <, >, <=, >=, ==, !=, ;, ), , }
Follow(<selection_statement>) = { $, ;, ID, NUM, STRING, (, IF, WHILE, DO }
Follow(<iteration_statement>) = { $, ;, ID, NUM, STRING, (, IF, WHILE, DO }
然后进行代码的编写:虽然代码量比较大,但是原理比较简单,细心一点按原理进行编写问题应该不大。
//句法分析器.cpp
#pragma warning(disable :4996)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "global.h"
char src_buf[10240];
int src_size;
extern int lookahead;
void drawTree(struct node* rootPtr, const char* prefix)
{
int i;
int len;
char childprefix[1024];
if (rootPtr == NULL)
return;
printf("%s", prefix);
if (strcmp(prefix, "") == 0)
printf("%s\n", rootPtr->label);
else {
len = strlen(prefix);
if (prefix[len - 1] == '|')
printf("-- %s\n", rootPtr->label);
else
printf("|-- %s\n", rootPtr->label);
}
for (i = 0; i < rootPtr->num_children; i++) {
if (i == rootPtr->num_children - 1)
sprintf(childprefix, "%s ", prefix);
else
sprintf(childprefix, "%s |", prefix);
drawTree(rootPtr->children[i], childprefix);
}
}
int main()
{
FILE* src;
struct node* root;
src = fopen("test.c", "r");
if (src == NULL) {
printf("can not open the source file.\n");
return 1;
}
fread(src_buf, 10240, 1, src);
src_size = strlen(src_buf) + 1;
lookahead = gettoken();
root = program();
drawTree(root, "");
}
// Parser.cpp
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include"global.h"
int lookahead;
struct node* program();
struct node* statement_list();
struct node* statement_list1();
struct node* statement();
struct node* expression_statement();
struct node* expression();
struct node* expression1();
struct node* assignment_expression();
struct node* assignment_expression1();
struct node* equality_expression();
struct node* equality_expression1();
struct node* relational_expression();
struct node* relational_expression1();
struct node* additive_expression();
struct node* additive_expression1();
struct node* multiplicative_expression();
struct node* multiplicative_expression1();
struct node* primary_expression();
struct node* selection_statement();
struct node* iteration_statement();
struct node* createNode(const char* label, int num_children) {
struct node* ptr = NULL;
ptr = (struct node*)malloc(sizeof(struct node));
if (ptr == NULL) {
printf("out of memory.\n");
return NULL;
}
sprintf(ptr->label, "%s", label);
ptr->num_children = num_children;
return ptr;
}
void match(int code)
{
lookahead = gettoken();
}
/
struct node* program()
{
struct node* ptr = NULL;
ptr = createNode("<program>", 1);
ptr->children[0] = statement_list();
return ptr;
}
struct node* statement_list()
{
struct node* ptr = NULL;
ptr = createNode("<statement_list>", 2);
ptr->children[0] = statement();
ptr->children[1] = statement_list1();
return ptr;
}
struct node* statement_list1()
{
struct node* ptr = NULL;
if (lookahead == SEMI || lookahead == ID || lookahead == NUM || lookahead == STRING || lookahead == IF || lookahead == WHILE || lookahead == DO || lookahead == LR)
{
ptr = createNode("<statement_list1>", 1);
ptr->children[0] = statement_list();
}
else {
ptr = createNode("<statement_list1>", 1);
ptr->children[0] = createNode("ε", 0);
}
return ptr;
}
struct node* statement()
{
struct node* ptr = NULL;
if (lookahead == SEMI || lookahead == ID || lookahead == NUM || lookahead == STRING || lookahead == LR)
{
ptr = createNode("<statement>", 1);
ptr->children[0] = expression_statement();
}
else if (lookahead == IF)
{
ptr = createNode("<statement>", 1);
ptr->children[0] = selection_statement();
}
else if (lookahead == WHILE || lookahead == DO)
{
ptr = createNode("<statement>", 1);
ptr->children[0] = iteration_statement();
}
return ptr;
}
struct node* expression_statement()
{
struct node* ptr = NULL;
if (lookahead == SEMI) {
ptr = createNode("<expression_statement>", 1);
match(SEMI);
ptr->children[0] = createNode("SEMI", 0);
}
else {
ptr = createNode("<expression_statement>", 2);
ptr->children[0] = expression();
if (lookahead == SEMI) {
match(SEMI);
ptr->children[1] = createNode("SEMI", 0);
}
else {
printf("Syntax error: expression_statement.\n");
}
}
return ptr;
}
struct node* expression()
{
struct node* ptr = NULL;
ptr = createNode("<expression>", 2);
ptr->children[0] = assignment_expression();
ptr->children[1] = expression1();
return ptr;
}
struct node* expression1()
{
struct node* ptr = NULL;
if (lookahead == COMMA) {
ptr = createNode("<expression1>", 2);
match(COMMA);
ptr->children[0] = createNode("COMMA", 0);
ptr->children[1] = expression();
}
else {
ptr = createNode("<expression1>", 1);
ptr->children[0] = createNode("ε", 0);
}
return ptr;
}
struct node* assignment_expression()
{
struct node* ptr = NULL;
if (lookahead == ID) {
ptr = createNode("<assignment_expression>", 2);
match(ID);
ptr->children[0] = createNode("ID", 0);
ptr->children[1] = assignment_expression1();
}
else if (lookahead == NUM) {
ptr = createNode("<assignment_expression>", 5);
match(NUM);
ptr->children[0] = createNode("NUM", 0);
ptr->children[1] = multiplicative_expression1();
ptr->children[2] = additive_expression1();
ptr->children[3] = relational_expression1();
ptr->children[4] = equality_expression1();
}
else if (lookahead == STRING) {
ptr = createNode("<assignment_expression>", 5);
match(STRING);
ptr->children[0] = createNode("STRING", 0);
ptr->children[1] = multiplicative_expression1();
ptr->children[2] = additive_expression1();
ptr->children[3] = relational_expression1();
ptr->children[4] = equality_expression1();
}
else if (lookahead == LR) {
ptr = createNode("<assignment_expression>", 7);
match(LR);
ptr->children[0] = createNode("LR", 0);
ptr->children[1] = expression();
if (lookahead == RR) {
match(RR);
ptr->children[2] = createNode("RR", 0);
ptr->children[3] = multiplicative_expression1();
ptr->children[4] = additive_expression1();
ptr->children[5] = relational_expression1();
ptr->children[6] = equality_expression1();
}
}
else {
printf("Syntax error: assignment_expression.\n");
}
return ptr;
}
struct node* assignment_expression1()
{
struct node* ptr = NULL;
if (lookahead == ASSIGN) {
ptr = createNode("<assignment_expression1>", 2);
match(ASSIGN);
ptr->children[0] = createNode("ASSIGN", 0);
ptr->children[1] = assignment_expression();
}
else {
ptr = createNode("<assignment_expression1>", 4);
ptr->children[0] = multiplicative_expression1();
ptr->children[1] = additive_expression1();
ptr->children[2] = relational_expression1();
ptr->children[3] = equality_expression1();
}
return ptr;
}
struct node* equality_expression()
{
struct node* ptr = NULL;
ptr = createNode("<equality_expression>", 2);
ptr->children[0] = relational_expression();
ptr->children[1] = equality_expression1();
return ptr;
}
struct node* equality_expression1()
{
struct node* ptr = NULL;
if (lookahead == EQ) {
ptr = createNode("<equality_expression1>", 2);
match(EQ);
ptr->children[0] = createNode("EQ", 0);
ptr->children[1] = equality_expression();
}
else if (lookahead == NE) {
ptr = createNode("<equality_expression1>", 2);
match(NE);
ptr->children[0] = createNode("NE", 0);
ptr->children[1] = equality_expression();
}
else {
ptr = createNode("<equality_expression1>", 1);
ptr->children[0] = createNode("ε", 0);
}
return ptr;
}
struct node* relational_expression()
{
struct node* ptr = NULL;
ptr = createNode("<relational_expression1>", 2);
ptr->children[0] = additive_expression();
ptr->children[1] = relational_expression1();
return ptr;
}
struct node* relational_expression1()
{
struct node* ptr = NULL;
if (lookahead == LT) {
ptr = createNode("<relational_expression1>", 2);
match(LT);
ptr->children[0] = createNode("LT", 0);
ptr->children[1] = relational_expression();
}
else if (lookahead == GT) {
ptr = createNode("<relational_expression1>", 2);
match(GT);
ptr->children[0] = createNode("GT", 0);
ptr->children[1] = relational_expression();
}
else if (lookahead == LE) {
ptr = createNode("<relational_expression1>", 2);
match(LE);
ptr->children[0] = createNode("LE", 0);
ptr->children[1] = relational_expression();
}
else if (lookahead == GE) {
ptr = createNode("<relational_expression1>", 2);
match(GE);
ptr->children[0] = createNode("GE", 0);
ptr->children[1] = relational_expression();
}
else {
ptr = createNode("<relational_expression1>", 1);
ptr->children[0] = createNode("ε", 0);
}
return ptr;
}
struct node* additive_expression()
{
struct node* ptr = NULL;
ptr = createNode("<additive_expression>", 2);
ptr->children[0] = multiplicative_expression();
ptr->children[1] = additive_expression1();
return ptr;
}
struct node* additive_expression1()
{
struct node* ptr = NULL;
if (lookahead == ADD) {
ptr = createNode("<additive_expression1>", 2);
match(ADD);
ptr->children[0] = createNode("ADD", 0);
ptr->children[1] = additive_expression();
}
else if (lookahead == SUB) {
ptr = createNode("<additive_expression1>", 2);
match(SUB);
ptr->children[0] = createNode("SUB", 0);
ptr->children[1] = additive_expression();
}
else {
ptr = createNode("<relational_expression1>", 1);
ptr->children[0] = createNode("ε", 0);
}
return ptr;
}
struct node* multiplicative_expression()
{
struct node* ptr = NULL;
ptr = createNode("<multiplicative_expression>", 2);
ptr->children[0] = primary_expression();
ptr->children[1] = multiplicative_expression1();
return ptr;
}
struct node* multiplicative_expression1()
{
struct node* ptr = NULL;
if (lookahead == MUL) {
ptr = createNode("<multiplicative_expression1>", 2);
match(MUL);
ptr->children[0] = createNode("MUL", 0);
ptr->children[1] = multiplicative_expression();
}
else if (lookahead == DIV) {
ptr = createNode("<multiplicative_expression1>", 2);
match(DIV);
ptr->children[0] = createNode("DIV", 0);
ptr->children[1] = multiplicative_expression();
}
else {
ptr = createNode("<multiplicative_expression1>", 1);
ptr->children[0] = createNode("ε", 0);
}
return ptr;
}
struct node* primary_expression()
{
struct node* ptr = NULL;
if (lookahead == ID) {
ptr = createNode("primary_expression", 1);
match(ID);
ptr->children[0] = createNode("ID", 0);
}
else if (lookahead == NUM) {
ptr = createNode("primary_expression", 1);
match(NUM);
ptr->children[0] = createNode("NUM", 0);
}
else if (lookahead == STRING) {
ptr = createNode("primary_expression", 1);
match(STRING);
ptr->children[0] = createNode("STRING", 0);
}
else if (lookahead == LR) {
ptr = createNode("primary_expression", 3);
match(LR);
ptr->children[0] = createNode("LR", 0);
ptr->children[1] = expression();
if (lookahead == RR) {
match(RR);
ptr->children[2] = createNode("RR", 0);
}
else {
printf("Syntax error: mismatched left brace.\n");
}
}
else {
printf("Syntax error: primary_expression.\n");
}
return ptr;
}
struct node* selection_statement()
{
struct node* ptr = NULL;
if (lookahead == IF) {
ptr = createNode("<selection_statement>", 5);
match(IF);
ptr->children[0] = createNode("IF", 0);
if (lookahead == LR) {
match(LR);
ptr->children[1] = createNode("LR", 0);
ptr->children[2] = expression();
if (lookahead == RR) {
match(RR);
ptr->children[3] = createNode("RR", 0);
ptr->children[4] = statement();
}
else {
printf("Syntax error: mismatched left brace.\n");
}
}
}
return ptr;
}
struct node* iteration_statement()
{
struct node* ptr = NULL;
if (lookahead == WHILE) {
ptr = createNode("iteration_statement", 5);
match(WHILE);
ptr->children[0] = createNode("WHILE", 0);
if (lookahead == LR) {
match(LR);
ptr->children[1] = createNode("LR", 0);
ptr->children[2] = expression();
if (lookahead == RR) {
match(RR);
ptr->children[3] = createNode("RR", 0);
ptr->children[4] = statement();
}
else {
printf("Syntax error: mismatched RIGHT brace.\n");
}
}
}
else if (lookahead == DO) {
ptr = createNode("iteration_statement", 7);
match(DO);
ptr->children[0] = createNode("DO", 0);
ptr->children[1] = statement();
if (lookahead == WHILE) {
match(WHILE);
ptr->children[2] = createNode("WHILE", 0);
if (lookahead == LR) {
match(LR);
ptr->children[3] = createNode("LR", 0);
ptr->children[4] = expression();
if (lookahead == RR) {
match(RR);
ptr->children[5] = createNode("RR", 0);
if (lookahead == SEMI) {
match(SEMI);
ptr->children[6] = createNode("SEMI", 0);
}
else {
printf("Syntax error: iteration_statement.\n");
}
}
else {
printf("Syntax error: iteration_statement.\n");
}
}
else {
printf("Syntax error: iteration_statement.\n");
}
}
}
return ptr;
}
// Scanner.cpp
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"global.h"
extern char src_buf[10240];
extern int src_size;
int index = 0;
char token[256];
char c;
int len = 0;
char getc()
{
if (index >= src_size) {
printf("out of source file.\n");
return '\0';
}
char c = src_buf[index];
index++;
return c;
}
void getbe()
{
//if (c == EOF)return;
while (c == ' ' || c == '\t' || c == '\n') {
c = getc();
}
}
int letter()
{
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
return 1;
return 0;
}
int digit()
{
if (c >= '0' && c <= '9')
return 1;
return 0;
}
void concatenation()
{
token[len] = c;
token[len + 1] = '\0';
len++;
}
void retract()
{
index--;
}
int reserve()
{
char keywords[128][64] = { "", "break", "char", "do", "double", "else", "if", "int", "return", "void", "while" };
int i;
for (i = 0; i <= 10; i++) {
if (strcmp(token, keywords[i]) == 0) {
return i;
}
}
return 0;
}
int gettoken()
{
int code;
len = 0;
token[0] = '\0'; /*对token数组初始化*/
c = getc();
getbe(); /*滤除空格*/
switch (c)
{
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
case 'g':
case 'h':
case 'i':
case 'j':
case 'k':
case 'l':
case 'm':
case 'n':
case 'o':
case 'p':
case 'q':
case 'r':
case 's':
case 't':
case 'u':
case 'v':
case 'w':
case 'x':
case 'y':
case 'z':
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
case 'G':
case 'H':
case 'I':
case 'J':
case 'K':
case 'L':
case 'M':
case 'N':
case 'O':
case 'P':
case 'Q':
case 'R':
case 'S':
case 'T':
case 'U':
case 'V':
case 'W':
case 'X':
case 'Y':
case 'Z':
while (letter() || digit())
{
concatenation(); /*将当前读入的字符送入token数组*/
c = getc();
}
retract(); /*扫描指针回退一个字符*/
code = reserve();
if (code == 0)
{
return ID;
}
else
return code;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
while (digit() && index < src_size)
{
concatenation();
c = getc();
}
retract();
return NUM;
case '+':
return ADD;
case '-':
return SUB;
case '*':
return MUL;
case '/':
return DIV;
case '<':
c = getc();
if (c == '=')
return LE;
else
{
retract();
return LT;
}
case '>':
c = getc();
if (c == '=')
return GE;
else
{
retract();
return GT;
}
case '=':
c = getc();
if (c == '=')
return EQ;
else
{
retract();
return ASSIGN;
}
case '!':
c = getc();
if (c == '=')
return NE;
else
{
retract();
return ASSIGN;
}
case '{':
return LB;
case '}':
return RB;
case '(':
return LR;
case ')':
return RR;
case ',':
return COMMA;
case ';':
return SEMI;
/*case EOF:
printf("hhhhh.\n");*/
default:
printf("Lexical error.\n");
}
}
// global.h
enum code { BREAK = 1, CHAR, DO, DOUBLE, ELSE, IF, INT, RETURN, VOID, WHILE, ID, NUM, STRING, ADD, SUB, MUL, DIV, GT, GE, LT, LE, EQ, NE, ASSIGN, LB, RB, LR, RR, COMMA, SEMI };
#define MAX_LEN 64
#define MAX_NUM_CHILDREN 8
struct node {
char label[MAX_LEN];
int num_children;
struct node* children[MAX_NUM_CHILDREN];
};
int gettoken();
struct node* program();
struct node* createNode(const char* label, int num_children);
// 输入文件 test.c
count = 10;
while (count > 1)
count = count - 1;
n = count * (count - 100);
if (n > 10)
m = 1;
i = 100;
if (maxvalue > 100)
while (i < 10) i = i + 2;
while (a + b >= 100)
if (c != d)
result = 100;
if (a > b)
max = a;
else
max = b;
sum = 0;
for (i = 0; i < 10; i++)
sum += i;
结果
<program>
|-- <statement_list>
|-- <statement>
| |-- <expression_statement>
| |-- <expression>
| | |-- <assignment_expression>
| | | |-- ID
| | | |-- <assignment_expression1>
| | | |-- ASSIGN
| | | |-- <assignment_expression>
| | | |-- NUM
| | | |-- <multiplicative_expression1>
| | | | |-- ε
| | | |-- <relational_expression1>
| | | | |-- ε
| | | |-- <relational_expression1>
| | | | |-- ε
| | | |-- <equality_expression1>
| | | |-- ε
| | |-- <expression1>
| | |-- ε
| |-- SEMI
|-- <statement_list1>
|-- <statement_list>
|-- <statement>
| |-- iteration_statement
| |-- WHILE
| |-- LR
| |-- <expression>
| | |-- <assignment_expression>
| | | |-- ID
| | | |-- <assignment_expression1>
| | | |-- <multiplicative_expression1>
| | | | |-- ε
| | | |-- <relational_expression1>
| | | | |-- ε
| | | |-- <relational_expression1>
| | | | |-- GT
| | | | |-- <relational_expression1>
| | | | |-- <additive_expression>
| | | | | |-- <multiplicative_expression>
| | | | | | |-- primary_expression
| | | | | | | |-- NUM
| | | | | | |-- <multiplicative_expression1>
| | | | | | |-- ε
| | | | | |-- <relational_expression1>
| | | | | |-- ε
| | | | |-- <relational_expression1>
| | | | |-- ε
| | | |-- <equality_expression1>
| | | |-- ε
| | |-- <expression1>
| | |-- ε
| |-- RR
| |-- <statement>
| |-- <expression_statement>
| |-- <expression>
| | |-- <assignment_expression>
| | | |-- ID
| | | |-- <assignment_expression1>
| | | |-- ASSIGN
| | | |-- <assignment_expression>
| | | |-- ID
| | | |-- <assignment_expression1>
| | | |-- <multiplicative_expression1>
| | | | |-- ε
| | | |-- <additive_expression1>
| | | | |-- SUB
| | | | |-- <additive_expression>
| | | | |-- <multiplicative_expression>
| | | | | |-- primary_expression
| | | | | | |-- NUM
| | | | | |-- <multiplicative_expression1>
| | | | | |-- ε
| | | | |-- <relational_expression1>
| | | | |-- ε
| | | |-- <relational_expression1>
| | | | |-- ε
| | | |-- <equality_expression1>
| | | |-- ε
| | |-- <expression1>
| | |-- ε
| |-- SEMI
|-- <statement_list1>
|-- <statement_list>
|-- <statement>
| |-- <expression_statement>
| |-- <expression>
| | |-- <assignment_expression>
| | | |-- ID
| | | |-- <assignment_expression1>
| | | |-- ASSIGN
| | | |-- <assignment_expression>
| | | |-- ID
| | | |-- <assignment_expression1>
| | | |-- <multiplicative_expression1>
| | | | |-- MUL
| | | | |-- <multiplicative_expression>
| | | | |-- primary_expression
| | | | | |-- LR
| | | | | |-- <expression>
| | | | | | |-- <assignment_expression>
| | | | | | | |-- ID
| | | | | | | |-- <assignment_expression1>
| | | | | | | |-- <multiplicative_expression1>
| | | | | | | | |-- ε
| | | | | | | |-- <additive_expression1>
| | | | | | | | |-- SUB
| | | | | | | | |-- <additive_expression>
| | | | | | | | |-- <multiplicative_expression>
| | | | | | | | | |-- primary_expression
| | | | | | | | | | |-- NUM
| | | | | | | | | |-- <multiplicative_expression1>
| | | | | | | | | |-- ε
| | | | | | | | |-- <relational_expression1>
| | | | | | | | |-- ε
| | | | | | | |-- <relational_expression1>
| | | | | | | | |-- ε
| | | | | | | |-- <equality_expression1>
| | | | | | | |-- ε
| | | | | | |-- <expression1>
| | | | | | |-- ε
| | | | | |-- RR
| | | | |-- <multiplicative_expression1>
| | | | |-- ε
| | | |-- <relational_expression1>
| | | | |-- ε
| | | |-- <relational_expression1>
| | | | |-- ε
| | | |-- <equality_expression1>
| | | |-- ε
| | |-- <expression1>
| | |-- ε
| |-- SEMI
|-- <statement_list1>
|-- <statement_list>
|-- <statement>
| |-- <selection_statement>
| |-- IF
| |-- LR
| |-- <expression>
| | |-- <assignment_expression>
| | | |-- ID
| | | |-- <assignment_expression1>
| | | |-- <multiplicative_expression1>
| | | | |-- ε
| | | |-- <relational_expression1>
| | | | |-- ε
| | | |-- <relational_expression1>
| | | | |-- GT
| | | | |-- <relational_expression1>
| | | | |-- <additive_expression>
| | | | | |-- <multiplicative_expression>
| | | | | | |-- primary_expression
| | | | | | | |-- NUM
| | | | | | |-- <multiplicative_expression1>
| | | | | | |-- ε
| | | | | |-- <relational_expression1>
| | | | | |-- ε
| | | | |-- <relational_expression1>
| | | | |-- ε
| | | |-- <equality_expression1>
| | | |-- ε
| | |-- <expression1>
| | |-- ε
| |-- RR
| |-- <statement>
| |-- <expression_statement>
| |-- <expression>
| | |-- <assignment_expression>
| | | |-- ID
| | | |-- <assignment_expression1>
| | | |-- ASSIGN
| | | |-- <assignment_expression>
| | | |-- NUM
| | | |-- <multiplicative_expression1>
| | | | |-- ε
| | | |-- <relational_expression1>
| | | | |-- ε
| | | |-- <relational_expression1>
| | | | |-- ε
| | | |-- <equality_expression1>
| | | |-- ε
| | |-- <expression1>
| | |-- ε
| |-- SEMI
|-- <statement_list1>
|-- <statement_list>
|-- <statement>
| |-- <expression_statement>
| |-- <expression>
| | |-- <assignment_expression>
| | | |-- ID
| | | |-- <assignment_expression1>
| | | |-- ASSIGN
| | | |-- <assignment_expression>
| | | |-- NUM
| | | |-- <multiplicative_expression1>
| | | | |-- ε
| | | |-- <relational_expression1>
| | | | |-- ε
| | | |-- <relational_expression1>
| | | | |-- ε
| | | |-- <equality_expression1>
| | | |-- ε
| | |-- <expression1>
| | |-- ε
| |-- SEMI
|-- <statement_list1>
|-- <statement_list>
|-- <statement>
| |-- <selection_statement>
| |-- IF
| |-- LR
| |-- <expression>
| | |-- <assignment_expression>
| | | |-- ID
| | | |-- <assignment_expression1>
| | | |-- <multiplicative_expression1>
| | | | |-- ε
| | | |-- <relational_expression1>
| | | | |-- ε
| | | |-- <relational_expression1>
| | | | |-- GT
| | | | |-- <relational_expression1>
| | | | |-- <additive_expression>
| | | | | |-- <multiplicative_expression>
| | | | | | |-- primary_expression
| | | | | | | |-- NUM
| | | | | | |-- <multiplicative_expression1>
| | | | | | |-- ε
| | | | | |-- <relational_expression1>
| | | | | |-- ε
| | | | |-- <relational_expression1>
| | | | |-- ε
| | | |-- <equality_expression1>
| | | |-- ε
| | |-- <expression1>
| | |-- ε
| |-- RR
| |-- <statement>
| |-- iteration_statement
| |-- WHILE
| |-- LR
| |-- <expression>
| | |-- <assignment_expression>
| | | |-- ID
| | | |-- <assignment_expression1>
| | | |-- <multiplicative_expression1>
| | | | |-- ε
| | | |-- <relational_expression1>
| | | | |-- ε
| | | |-- <relational_expression1>
| | | | |-- LT
| | | | |-- <relational_expression1>
| | | | |-- <additive_expression>
| | | | | |-- <multiplicative_expression>
| | | | | | |-- primary_expression
| | | | | | | |-- NUM
| | | | | | |-- <multiplicative_expression1>
| | | | | | |-- ε
| | | | | |-- <relational_expression1>
| | | | | |-- ε
| | | | |-- <relational_expression1>
| | | | |-- ε
| | | |-- <equality_expression1>
| | | |-- ε
| | |-- <expression1>
| | |-- ε
| |-- RR
| |-- <statement>
| |-- <expression_statement>
| |-- <expression>
| | |-- <assignment_expression>
| | | |-- ID
| | | |-- <assignment_expression1>
| | | |-- ASSIGN
| | | |-- <assignment_expression>
| | | |-- ID
| | | |-- <assignment_expression1>
| | | |-- <multiplicative_expression1>
| | | | |-- ε
| | | |-- <additive_expression1>
| | | | |-- ADD
| | | | |-- <additive_expression>
| | | | |-- <multiplicative_expression>
| | | | | |-- primary_expression
| | | | | | |-- NUM
| | | | | |-- <multiplicative_expression1>
| | | | | |-- ε
| | | | |-- <relational_expression1>
| | | | |-- ε
| | | |-- <relational_expression1>
| | | | |-- ε
| | | |-- <equality_expression1>
| | | |-- ε
| | |-- <expression1>
| | |-- ε
| |-- SEMI
|-- <statement_list1>
|-- <statement_list>
|-- <statement>
| |-- iteration_statement
| |-- WHILE
| |-- LR
| |-- <expression>
| | |-- <assignment_expression>
| | | |-- ID
| | | |-- <assignment_expression1>
| | | |-- <multiplicative_expression1>
| | | | |-- ε
| | | |-- <additive_expression1>
| | | | |-- ADD
| | | | |-- <additive_expression>
| | | | |-- <multiplicative_expression>
| | | | | |-- primary_expression
| | | | | | |-- ID
| | | | | |-- <multiplicative_expression1>
| | | | | |-- ε
| | | | |-- <relational_expression1>
| | | | |-- ε
| | | |-- <relational_expression1>
| | | | |-- GE
| | | | |-- <relational_expression1>
| | | | |-- <additive_expression>
| | | | | |-- <multiplicative_expression>
| | | | | | |-- primary_expression
| | | | | | | |-- NUM
| | | | | | |-- <multiplicative_expression1>
| | | | | | |-- ε
| | | | | |-- <relational_expression1>
| | | | | |-- ε
| | | | |-- <relational_expression1>
| | | | |-- ε
| | | |-- <equality_expression1>
| | | |-- ε
| | |-- <expression1>
| | |-- ε
| |-- RR
| |-- <statement>
| |-- <selection_statement>
| |-- IF
| |-- LR
| |-- <expression>
| | |-- <assignment_expression>
| | | |-- ID
| | | |-- <assignment_expression1>
| | | |-- <multiplicative_expression1>
| | | | |-- ε
| | | |-- <relational_expression1>
| | | | |-- ε
| | | |-- <relational_expression1>
| | | | |-- ε
| | | |-- <equality_expression1>
| | | |-- NE
| | | |-- <equality_expression>
| | | |-- <relational_expression1>
| | | | |-- <additive_expression>
| | | | | |-- <multiplicative_expression>
| | | | | | |-- primary_expression
| | | | | | | |-- ID
| | | | | | |-- <multiplicative_expression1>
| | | | | | |-- ε
| | | | | |-- <relational_expression1>
| | | | | |-- ε
| | | | |-- <relational_expression1>
| | | | |-- ε
| | | |-- <equality_expression1>
| | | |-- ε
| | |-- <expression1>
| | |-- ε
| |-- RR
| |-- <statement>
| |-- <expression_statement>
| |-- <expression>
| | |-- <assignment_expression>
| | | |-- ID
| | | |-- <assignment_expression1>
| | | |-- ASSIGN
| | | |-- <assignment_expression>
| | | |-- NUM
| | | |-- <multiplicative_expression1>
| | | | |-- ε
| | | |-- <relational_expression1>
| | | | |-- ε
| | | |-- <relational_expression1>
| | | | |-- ε
| | | |-- <equality_expression1>
| | | |-- ε
| | |-- <expression1>
| | |-- ε
| |-- SEMI
|-- <statement_list1>
|-- <statement_list>
|-- <statement>
| |-- <selection_statement>
| |-- IF
| |-- LR
| |-- <expression>
| | |-- <assignment_expression>
| | | |-- ID
| | | |-- <assignment_expression1>
| | | |-- <multiplicative_expression1>
| | | | |-- ε
| | | |-- <relational_expression1>
| | | | |-- ε
| | | |-- <relational_expression1>
| | | | |-- GT
| | | | |-- <relational_expression1>
| | | | |-- <additive_expression>
| | | | | |-- <multiplicative_expression>
| | | | | | |-- primary_expression
| | | | | | | |-- ID
| | | | | | |-- <multiplicative_expression1>
| | | | | | |-- ε
| | | | | |-- <relational_expression1>
| | | | | |-- ε
| | | | |-- <relational_expression1>
| | | | |-- ε
| | | |-- <equality_expression1>
| | | |-- ε
| | |-- <expression1>
| | |-- ε
| |-- RR
| |-- <statement>
| |-- <expression_statement>
| |-- <expression>
| | |-- <assignment_expression>
| | | |-- ID
| | | |-- <assignment_expression1>
| | | |-- ASSIGN
| | | |-- <assignment_expression>
| | | |-- ID
| | | |-- <assignment_expression1>
| | | |-- <multiplicative_expression1>
| | | | |-- ε
| | | |-- <relational_expression1>
| | | | |-- ε
| | | |-- <relational_expression1>
| | | | |-- ε
| | | |-- <equality_expression1>
| | | |-- ε
| | |-- <expression1>
| | |-- ε
| |-- SEMI
|-- <statement_list1>
|-- ε