Skip to content

Commit b22bde2

Browse files
author
baiwenlei
committed
init
0 parents  commit b22bde2

File tree

542 files changed

+96637
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

542 files changed

+96637
-0
lines changed

.gitignore

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
.DS_Store
2+
node_modules/
3+
*.output
4+
*.tab.c
5+
*.dot
6+
*.bak
7+
*.png
8+

calc/llparser/lexicalanalyzer.c

+118
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <ctype.h>
4+
#include "token.h"
5+
6+
static char *st_line;
7+
static int st_line_pos;
8+
9+
typedef enum {
10+
INITIAL_STATUS,
11+
IN_INT_PART_STATUS,
12+
DOT_STATUS,
13+
IN_FRAC_PART_STATUS
14+
} LexerStatus;
15+
16+
void
17+
get_token(Token *token)
18+
{
19+
int out_pos = 0;
20+
LexerStatus status = INITIAL_STATUS;
21+
char current_char;
22+
23+
token->kind = BAD_TOKEN;
24+
while (st_line[st_line_pos] != '\0') {
25+
current_char = st_line[st_line_pos];
26+
if ((status == IN_INT_PART_STATUS || status == IN_FRAC_PART_STATUS)
27+
&& !isdigit(current_char) && current_char != '.') {
28+
token->kind = NUMBER_TOKEN;
29+
sscanf(token->str, "%lf", &token->value);
30+
return;
31+
}
32+
if (isspace(current_char)) {
33+
if (current_char == '\n') {
34+
token->kind = END_OF_LINE_TOKEN;
35+
return;
36+
}
37+
st_line_pos++;
38+
continue;
39+
}
40+
41+
if (out_pos >= MAX_TOKEN_SIZE-1) {
42+
fprintf(stderr, "token too long.\n");
43+
exit(1);
44+
}
45+
token->str[out_pos] = st_line[st_line_pos];
46+
st_line_pos++;
47+
out_pos++;
48+
token->str[out_pos] = '\0';
49+
50+
if (current_char == '+') {
51+
token->kind = ADD_OPERATOR_TOKEN;
52+
return;
53+
} else if (current_char == '-') {
54+
token->kind = SUB_OPERATOR_TOKEN;
55+
return;
56+
} else if (current_char == '*') {
57+
token->kind = MUL_OPERATOR_TOKEN;
58+
return;
59+
} else if (current_char == '/') {
60+
token->kind = DIV_OPERATOR_TOKEN;
61+
return;
62+
} else if (isdigit(current_char)) {
63+
if (status == INITIAL_STATUS) {
64+
status = IN_INT_PART_STATUS;
65+
} else if (status == DOT_STATUS) {
66+
status = IN_FRAC_PART_STATUS;
67+
}
68+
} else if (current_char == '.') {
69+
if (status == IN_INT_PART_STATUS) {
70+
status = DOT_STATUS;
71+
} else {
72+
fprintf(stderr, "syntax error.\n");
73+
exit(1);
74+
}
75+
} else {
76+
fprintf(stderr, "bad character(%c)\n", current_char);
77+
exit(1);
78+
}
79+
}
80+
}
81+
82+
void
83+
set_line(char *line)
84+
{
85+
st_line = line;
86+
st_line_pos = 0;
87+
}
88+
89+
#if 0
90+
void
91+
parse_line(char *buf)
92+
{
93+
Token token;
94+
95+
set_line(buf);
96+
97+
for (;;) {
98+
get_token(&token);
99+
if (token.kind == END_OF_LINE_TOKEN) {
100+
break;
101+
} else {
102+
printf("kind..%d, str..%s\n", token.kind, token.str);
103+
}
104+
}
105+
}
106+
107+
int
108+
main(int argc, char **argv)
109+
{
110+
char buf[1024];
111+
112+
while (fgets(buf, 1024, stdin) != NULL) {
113+
parse_line(buf);
114+
}
115+
116+
return 0;
117+
}
118+
#endif

calc/llparser/make.bat

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
gcc -o mycalc -Wall -Wswitch-enum -ansi parser.c lexicalanalyzer.c

calc/llparser/make.sh

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
cc -o mycalc lexicalanalyzer.c parser.c

calc/llparser/parser.c

+120
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include "token.h"
4+
5+
#define LINE_BUF_SIZE (1024)
6+
7+
static Token st_look_ahead_token;
8+
static int st_look_ahead_token_exists;
9+
10+
static void
11+
my_get_token(Token *token)
12+
{
13+
if (st_look_ahead_token_exists) {
14+
*token = st_look_ahead_token;
15+
st_look_ahead_token_exists = 0;
16+
} else {
17+
get_token(token);
18+
}
19+
}
20+
21+
static void
22+
unget_token(Token *token)
23+
{
24+
st_look_ahead_token = *token;
25+
st_look_ahead_token_exists = 1;
26+
}
27+
28+
double parse_expression(void);
29+
30+
static double
31+
parse_primary_expression()
32+
{
33+
Token token;
34+
35+
my_get_token(&token);
36+
if (token.kind == NUMBER_TOKEN) {
37+
return token.value;
38+
}
39+
fprintf(stderr, "syntax error.\n");
40+
exit(1);
41+
return 0.0; /* make compiler happy */
42+
}
43+
44+
static double
45+
parse_term()
46+
{
47+
double v1;
48+
double v2;
49+
Token token;
50+
51+
v1 = parse_primary_expression();
52+
for (;;) {
53+
my_get_token(&token);
54+
if (token.kind != MUL_OPERATOR_TOKEN
55+
&& token.kind != DIV_OPERATOR_TOKEN) {
56+
unget_token(&token);
57+
break;
58+
}
59+
v2 = parse_primary_expression();
60+
if (token.kind == MUL_OPERATOR_TOKEN) {
61+
v1 *= v2;
62+
} else if (token.kind == DIV_OPERATOR_TOKEN) {
63+
v1 /= v2;
64+
}
65+
}
66+
return v1;
67+
}
68+
69+
double
70+
parse_expression()
71+
{
72+
double v1;
73+
double v2;
74+
Token token;
75+
76+
v1 = parse_term();
77+
for (;;) {
78+
my_get_token(&token);
79+
if (token.kind != ADD_OPERATOR_TOKEN
80+
&& token.kind != SUB_OPERATOR_TOKEN) {
81+
unget_token(&token);
82+
break;
83+
}
84+
v2 = parse_term();
85+
if (token.kind == ADD_OPERATOR_TOKEN) {
86+
v1 += v2;
87+
} else if (token.kind == SUB_OPERATOR_TOKEN) {
88+
v1 -= v2;
89+
} else {
90+
unget_token(&token);
91+
}
92+
}
93+
return v1;
94+
}
95+
96+
double
97+
parse_line(void)
98+
{
99+
double value;
100+
101+
st_look_ahead_token_exists = 0;
102+
value = parse_expression();
103+
104+
return value;
105+
}
106+
107+
int
108+
main(int argc, char **argv)
109+
{
110+
char line[LINE_BUF_SIZE];
111+
double value;
112+
113+
while (fgets(line, LINE_BUF_SIZE, stdin) != NULL) {
114+
set_line(line);
115+
value = parse_line();
116+
printf(">>%f\n", value);
117+
}
118+
119+
return 0;
120+
}

calc/llparser/token.h

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#ifndef TOKEN_H_INCLUDED
2+
#define TOKEN_H_INCLUDED
3+
4+
typedef enum {
5+
BAD_TOKEN,
6+
NUMBER_TOKEN,
7+
ADD_OPERATOR_TOKEN,
8+
SUB_OPERATOR_TOKEN,
9+
MUL_OPERATOR_TOKEN,
10+
DIV_OPERATOR_TOKEN,
11+
END_OF_LINE_TOKEN
12+
} TokenKind;
13+
14+
#define MAX_TOKEN_SIZE (100)
15+
16+
typedef struct {
17+
TokenKind kind;
18+
double value;
19+
char str[MAX_TOKEN_SIZE];
20+
} Token;
21+
22+
void set_line(char *line);
23+
void get_token(Token *token);
24+
25+
#endif /* TOKEN_H_INCLUDED */

calc/llparser_ex/lexicalanalyzer.c

+118
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <ctype.h>
4+
#include "token.h"
5+
6+
static char *st_line;
7+
static int st_line_pos;
8+
9+
typedef enum {
10+
INITIAL_STATUS,
11+
IN_INT_PART_STATUS,
12+
DOT_STATUS,
13+
IN_FRAC_PART_STATUS
14+
} LexerStatus;
15+
16+
void
17+
get_token(Token *token)
18+
{
19+
int out_pos = 0;
20+
LexerStatus status = INITIAL_STATUS;
21+
char current_char;
22+
23+
token->kind = BAD_TOKEN;
24+
while (st_line[st_line_pos] != '\0') {
25+
current_char = st_line[st_line_pos];
26+
if ((status == IN_INT_PART_STATUS || status == IN_FRAC_PART_STATUS)
27+
&& !isdigit(current_char) && current_char != '.') {
28+
token->kind = NUMBER_TOKEN;
29+
sscanf(token->str, "%lf", &token->value);
30+
return;
31+
}
32+
if (isspace(current_char)) {
33+
if (current_char == '\n') {
34+
token->kind = END_OF_LINE_TOKEN;
35+
return;
36+
}
37+
st_line_pos++;
38+
continue;
39+
}
40+
41+
if (out_pos >= MAX_TOKEN_SIZE-1) {
42+
fprintf(stderr, "token too long.\n");
43+
exit(1);
44+
}
45+
token->str[out_pos] = st_line[st_line_pos];
46+
st_line_pos++;
47+
out_pos++;
48+
token->str[out_pos] = '\0';
49+
50+
if (current_char == '+') {
51+
token->kind = ADD_OPERATOR_TOKEN;
52+
return;
53+
} else if (current_char == '-') {
54+
token->kind = SUB_OPERATOR_TOKEN;
55+
return;
56+
} else if (current_char == '*') {
57+
token->kind = MUL_OPERATOR_TOKEN;
58+
return;
59+
} else if (current_char == '/') {
60+
token->kind = DIV_OPERATOR_TOKEN;
61+
return;
62+
} else if (current_char == '(') {
63+
token->kind = LEFT_PAREN_TOKEN;
64+
return;
65+
} else if (current_char == ')') {
66+
token->kind = RIGHT_PAREN_TOKEN;
67+
return;
68+
} else if (isdigit(current_char)) {
69+
if (status == INITIAL_STATUS) {
70+
status = IN_INT_PART_STATUS;
71+
} else if (status == DOT_STATUS) {
72+
status = IN_FRAC_PART_STATUS;
73+
}
74+
} else if (current_char == '.') {
75+
if (status == IN_INT_PART_STATUS) {
76+
status = DOT_STATUS;
77+
} else {
78+
fprintf(stderr, "syntax error.\n");
79+
exit(1);
80+
}
81+
}
82+
}
83+
}
84+
85+
void
86+
set_line(char *line)
87+
{
88+
st_line = line;
89+
st_line_pos = 0;
90+
}
91+
92+
#if 0
93+
void
94+
parse_line(void)
95+
{
96+
Token token;
97+
st_line_pos = 0;
98+
99+
for (;;) {
100+
get_token(&token);
101+
if (token.kind == END_OF_LINE_TOKEN) {
102+
break;
103+
} else {
104+
printf("kind..%d, str..%s\n", token.kind, token.str);
105+
}
106+
}
107+
}
108+
109+
int
110+
main(int argc, char **argv)
111+
{
112+
while (fgets(st_line, LINE_BUF_SIZE, stdin) != NULL) {
113+
parse_line();
114+
}
115+
116+
return 0;
117+
}
118+
#endif

calc/llparser_ex/make.bat

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
gcc -o mycalc -Wall -Wswitch-enum -ansi parser.c lexicalanalyzer.c

0 commit comments

Comments
 (0)