#include <stdio.h>
#include "lily.h"
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
extern int get_token();
char test[100][100]
={ "begin",
"int", "char", "void" , "pint", "pchar",
"pvoid", "if", "else", "for", "while",
"return", "ID", "NUM", "14", "15",
"16", "17", "18", "19", "20",
"=", "+", "-", "*", "/",
"(", ")", "[", "]", "{",
"}", ",", ":", ";", "'",
"\"", "<=", "<", ">=", ">",
"==", "!=", "&", "|", "!",
"&&", "||" };
extern int save_line;
int current_line;
int main(int argc, char *argv[])
{
int a= -999;
freopen( "./lexTest/2.txt", "r", stdin );
// test
/* while( (a = get_token() ) != FINISH )
{
if( save_line == current_line )
printf( "%s\t", test[a] );
else
{
current_line = save_line;
printf( "\n%s\t", test[a] );
}
}*/
//printf( "\n\n" );
program();
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "lily.h"
#define MAX_WORD_LEN 20
#define MAX_INPUT_LEN 1000
#define RESEVER_WORD_NUM 11
char * resever_word[] =
{
"int", "char", "void", "pint", "pchar",
"pvoid", "if", "else", "for", "while",
"return"
};
char save_word[100];
int save_num;
int save_line;
static char input_line[105];
static int input_len;
static int pos;
static int is_resever_word()
{
int i;
for( i = 0; i < RESEVER_WORD_NUM; i++ )
{
if( !strcmp( resever_word[i], save_word ) )
return i+1;
}
return -1;
}
static int get_next_word()
{
if( pos >= input_len )
{
if( fgets( input_line, MAX_INPUT_LEN, stdin ) )
{
pos = 0;
save_line++;
input_len = strlen( input_line );
if( input_len > MAX_INPUT_LEN )
{
fprintf( stderr, "input_line out of max range\n" );
exit( 0 );
}
return input_line[pos++];
}
else
{
return FINISH;
}
}
else
return input_line[pos++];
}
int get_token()
{
int c, len, i, max_word_len, state, token, flag, pause_line, pause_block;
state = START;
pause_line = 0;
pause_block = 0;
while( state != OVER )
{
if( state == PAUSE )
{
if( pause_line )
{
pause_line = 0;
pos = input_len;
state = START;
}
if( pause_block )
{
while( (c = get_next_word()) != FINISH )
{
if( c == '*' && input_line[pos] == '/' )
{
input_line[pos++];
break;
}
}
if( c == FINISH )
return FINISH;
pause_block = 0;
state = START;
}
}
c = get_next_word();
if( c == FINISH )
return FINISH;
if( c == ' ' || c == '\t' || c == '\n' )
continue;
if( isalpha( c ) || c == '_' )
{
i = 0;
max_word_len = 0;
do
{
save_word[i++] = c;
c = input_line[pos++];
max_word_len++;
}while( isdigit( c ) || c == '_' || isalpha( c ) );
pos--;
if( max_word_len >= 20 )
{
fprintf( stderr, "word's max len is 20"); // 以后要写一个错误处理函数
exit( 0 );
}
save_word[i] = '\0';
token = TOK_ID;
state = OVER;
}
else if( isdigit( c ) )
{
i = 0;
if( flag == '-' )
save_word[i++] = '-';
while( isdigit( c ) )
{
save_word[i++] = c;
c = input_line[pos++];
}
pos--;
save_word[i] = '\0';
save_num = atoi( save_word );
token = TOK_NUM;
state = OVER;
flag = 0;
}
else
{
state = OVER;
switch( c )
{
case '+':
token = TOK_PLUS;
break;
case '-':
token = TOK_MINUS;
break;
case '*':
token = TOK_MUL;
break;
case '/':
if( input_line[pos] == '/' )
{
input_line[pos++];
state = PAUSE;
pause_line = 1;
}
else if( input_line[pos] == '*' )
{
input_line[pos++];
state = PAUSE;
pause_block = 1;
}
else
{
token = TOK_DIV;
}
break;
case '=':
if( input_line[pos] == '=' )
{
input_line[pos++];
token = TOK_EQ;
}
else
token = TOK_ASSIGN;
break;
case '>':
if( input_line[pos] == '=' )
{
input_line[pos++];
token = TOK_GE;
}
else
token = TOK_GT;
break;
case '<':
if( input_line[pos] == '=' )
{
input_line[pos++];
token = TOK_LE;
}
else
token = TOK_LT;
break;
case '!':
if( input_line[pos] == '=' )
{
input_line[pos++];
token = TOK_NE;
}
else
token = TOK_NOT;
break;
case '&':
if( input_line[pos] == '&' )
{
input_line[pos++];
token = TOK_ANDAND;
}
else
token = TOK_AND;
break;
case '|':
if( input_line[pos] == '|' )
{
input_line[pos++];
token = TOK_OROR;
}
else
token = TOK_OR;
break;
case ',':
token = TOK_COMMA;
break;
case ':'://no gonna use 'condition ? true : false'
token = TOK_COLON;
break;
case ';':
token = TOK_SEMI;
break;
case 39: // '
token = TOK_SQUTOA;
break;
case 34: // "
token = TOK_DQUTOA;
break;
case '(':
token = TOK_LPAREN;
break;
case ')':
token = TOK_RPAREN;
break;
case '[':
token = TOK_LSQUARE;
break;
case ']':
token = TOK_RSQUARE;
break;
case '{':
token = TOK_LBRACKET;
break;
case '}':
token = TOK_RBRACKET;
break;
}
}
}
if( token == TOK_ID )
{
int t;
if( (t = is_resever_word()) != -1 )
token = t;
}
return token;
}
#ifndef LILY_H
#define LILY_H
#define TOK_INT 1
#define TOK_CHAR 2
#define TOK_VOID 3
#define TOK_PINT 4
#define TOK_PCHAR 5
#define TOK_PVOID 6
#define TOK_IF 7
#define TOK_ELSE 8
#define TOK_FOR 9
#define TOK_WHILE 10
#define TOK_RETURN 11
#define TOK_ID 12
#define TOK_NUM 13
#define TOK_ASSIGN 21
#define TOK_PLUS 22
#define TOK_MINUS 23
#define TOK_MUL 24
#define TOK_DIV 25
#define TOK_LPAREN 26
#define TOK_RPAREN 27
#define TOK_LSQUARE 28
#define TOK_RSQUARE 29
#define TOK_LBRACKET 30
#define TOK_RBRACKET 31
#define TOK_COMMA 32
#define TOK_COLON 33
#define TOK_SEMI 34
#define TOK_SQUTOA 35
#define TOK_DQUTOA 36
#define TOK_LE 37
#define TOK_LT 38
#define TOK_GE 39
#define TOK_GT 40
#define TOK_EQ 41
#define TOK_NE 42
#define TOK_AND 43
#define TOK_OR 44
#define TOK_NOT 45
#define TOK_ANDAND 46
#define TOK_OROR 47
#define START -1
#define PAUSE -2
#define OVER -3
#define FINISH -4
#define true 1
#define false 0
#define TRUE 1
#define FALSE 0
#endif
#include <stdio.h>
#include <string.h>
#include "lily.h"
extern void program();
static void declaration(int type);
static void var_declaration(int type, char id[]);
static void fun_declaration(int type, char id[]);
static void params();
static void param_list();
static void param();
static void compound_stmt();
static void statement();
static void statement_list();
static void expression_stmt();
static void selection_stmt();
static void iteration_stmt();
static void return_stmt();
static void elseif_stmt();
static void expression();
static void var();
static void simple_expression();
static int relop();
static void additive_expression();
static int addop();
static void term();
static void factor();
static void call();
static void args();
static void arg_list();
int token;
extern char save_word[100];
extern int get_token();
extern int save_line;
extern char test[][100];
static void match(int type)
{
if(token == type)
{
token = get_token();
}
else
{
fprintf(stderr, "line %d: expected token %s\n", save_line, test[type]);
}
}
void program()
{
int entry_flag = 0;
token = get_token();
while(token == TOK_INT || token == TOK_VOID || token == TOK_CHAR)
{
entry_flag = 1;
declaration(token);
}
if(entry_flag)
printf("succeed!!\texit()");
else
fprintf(stderr, "line %d: %s does not name a type", save_line, save_word );
}
static void declaration(int type)
{
int temp;
char id[30];
type = token;
match(type);
match(TOK_ID);
strcpy( id, save_word );
if(token == TOK_LPAREN)
{
fun_declaration(type, id);
}
else if(token == TOK_SEMI || token == TOK_LSQUARE)
{
var_declaration(type, id);
}
else
{
fprintf(stderr, "line %d: unexpected token %s\n", save_line, save_word);
}
}
static void fun_declaration(int type, char * id)
{
/* match ( */
match(TOK_LPAREN);
params();
/*match ) */
match(TOK_RPAREN);
compound_stmt();
}
static void var_declaration(int type, char *id)
{
/* var */
if(token == TOK_SEMI)
{
match(TOK_SEMI);
}
/* array */
else if(token == TOK_LSQUARE)
{
/* match [ */
match(TOK_LSQUARE);
match(TOK_NUM);
match(TOK_RSQUARE);
match(TOK_SEMI);
}
else
fprintf(stderr, "line %d: param does not a type\n", save_line);
}
static void params()
{
if(token == TOK_VOID)
{
match(TOK_VOID);
}
else if(token == TOK_INT)
{
param_list();
}
else if(token == TOK_CHAR)
{
param_list();
}
else
{
if(token != TOK_RPAREN)
fprintf(stderr, "line %d: function params error\n", save_line);
//else is empty
}
}
static void param_list()
{
param();
while(token == TOK_COMMA)
{
match(TOK_COMMA);
param();
}
}
static void param( )
{
if(token == TOK_INT
||token == TOK_CHAR
||token == TOK_PINT
||token == TOK_PCHAR
||token == TOK_VOID
||token == TOK_PVOID)
{
match(token);
}
match(TOK_ID);
if(token==TOK_LSQUARE)
{
match(TOK_LSQUARE);
match(TOK_RSQUARE);
}
}
static void compound_stmt()
{
/* match { */
match( TOK_LBRACKET );
while(token == TOK_INT
|| token == TOK_CHAR
|| token == TOK_PINT
|| token == TOK_PCHAR)
{
match(token);
match(TOK_ID);
var_declaration(0,"");
}
statement_list();
/* match } */
match( TOK_RBRACKET );
}
static void statement_list()
{
while(token == TOK_IF
||token == TOK_LBRACKET
||token == TOK_ID // a
||token == TOK_MUL // *a
||token == TOK_AND // &a
||token == TOK_WHILE
||token == TOK_RETURN
||token == TOK_SEMI
||token == TOK_FOR )
{
statement();
}
}
static void statement( )
{
if(token == TOK_IF)
{
selection_stmt();
}
else if(token == TOK_LBRACKET)
{
compound_stmt();
}
else if(token == TOK_ID||token == TOK_MUL||token == TOK_AND)
{
expression_stmt();
}
else if(token == TOK_WHILE||token == TOK_FOR)
{
iteration_stmt();
}
else if(token == TOK_RETURN)
{
return_stmt();
}
else if(token == TOK_SEMI)
{
match(TOK_SEMI);
}
else
fprintf( stderr, "line %d: error statements", save_line );
}
static void expression_stmt()
{
expression();
match(TOK_SEMI);
}
static void selection_stmt()
{
match(TOK_IF);
match(TOK_LPAREN);
expression();
match(TOK_RPAREN);
statement();
if(token == TOK_ELSE)
{
match(TOK_ELSE);
statement();
}
}
static void iteration_stmt()
{
if(token == TOK_WHILE)
{
match(TOK_WHILE);
match(TOK_LPAREN); /* ( */
expression();
match(TOK_RPAREN); /* ) */
statement();
}
else
{
match(TOK_FOR);
match(TOK_LPAREN);/* ( */
expression();
match(TOK_SEMI);
expression();
match(TOK_SEMI);
expression();
match(TOK_RPAREN);/* ) */
}
}
static void return_stmt()
{
match(TOK_RETURN);
if(token == TOK_SEMI)
{
match(TOK_SEMI);
}
else
{
expression();
match(TOK_SEMI);
}
}
static void expression( )
{
simple_expression();
if(token == TOK_ASSIGN)
{
match(TOK_ASSIGN);
expression();
}
}
static void var()
{
if(token == TOK_MUL || token == TOK_AND)
{
/* if is * or & */
match(token);
}
match(TOK_ID);
if(token == TOK_LSQUARE)
{
match(TOK_LSQUARE);
expression();
match(TOK_RSQUARE);
}
}
static void simple_expression( )
{
additive_expression();
if(token == TOK_LE
||token == TOK_LT
||token == TOK_GT
||token == TOK_GE
||token == TOK_EQ
||token == TOK_NE )
{
relop();
additive_expression();
}
}
static int relop()
{
switch(token)
{
case TOK_LE:
match(TOK_LE);
break;
case TOK_LT:
match(TOK_LT);
break;
case TOK_GT:
match(TOK_GT);
break;
case TOK_GE:
match(TOK_GE);
break;
case TOK_EQ:
match(TOK_EQ);
break;
case TOK_NE:
match(TOK_NE);
break;
}
return token;
}
static void additive_expression()
{
term();
while(token == TOK_PLUS || token == TOK_MINUS)
{
/* match PLUS or MINUS */
match(token);
term();
}
}
static void term()
{
factor();
while(token == TOK_MUL || token == TOK_DIV)
{
/* match MUL or DIV */
match(token);
factor();
}
}
static void factor()
{
if(token == TOK_LPAREN)
{
match(TOK_LPAREN);
expression();
match(TOK_RPAREN);
}
else if(token == TOK_ID
||token == TOK_MUL
||token == TOK_AND)
{
var();
if(token == TOK_LPAREN)
{
call();
}
}
else if(token == TOK_NUM)
{
match(TOK_NUM);
}
else if(token == TOK_PLUS
||token == TOK_MINUS )
{
/* 0 + a -> +a
0 - a -> -a
*/
//first element is zero
}
else
fprintf(stderr, "line %d: unexpected factor\n", save_line, save_word);
}
static void call()
{
match(TOK_LPAREN);
args();
match(TOK_RPAREN);
}
void args()
{
if(token == TOK_ID)
{
expression();
while(token == TOK_COMMA)
{
match(TOK_COMMA);
expression();
}
}
}