33,321
社区成员




偶在上面个帖子4楼的应该是符合要求地, 你把这个交上去, 然后跟老师一起探讨下编译原理/下推自动机/形式文法等等内容:
$ ( function x() { echo ------ $* ------- ; $* ; } ;\
x cat Xexpr.y ;x bison Xexpr.y -o Xexpr.c ; \
x gcc -o Xexpr Xexpr.c ; echo "(34+28+28)+[(7+8)-(9+10)]" | ./Xexpr ) | tee result
------ cat Xexpr.y -------
%{
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define YYPARSE_PARAM yyparam
#define YYLEX_PARAM yyparam
typedef struct yyparam_t yyparam_t;
struct yyparam_t
{
char* X_input;
int result;
};
int yylex( int *yylval_ , yyparam_t* param );
void yyerror( const char* msg )
{
fprintf( stderr , "[ERROR]%s\n" , msg );
}
%}
%pure_parser
%token XNUM
%right '+' '-'
%%
goal:
expr { ((yyparam_t*)YYPARSE_PARAM)->result = $$; }
;
expr:
XNUM
|
expr '+' expr { $$ = $1 + 2 * $3 ; }
|
expr '-' expr { $$ = $1 - 3 * $3 ; }
|
'(' expr ')' { $$ = $2 ; }
|
'[' expr ']' { $$ = $2 ; }
;
%%
int yylex( int *yylval_ , yyparam_t* param )
{
while( isspace( *param->X_input ) )
++param->X_input;
if( 0 == *param->X_input )
return 0;
if( !isdigit( *param->X_input ) )
return *param->X_input++;
*yylval_ = strtol( param->X_input , ¶m->X_input , 0 );
return XNUM;
}
int main()
{
yyparam_t param;
char line[1024+1] = "";
while( fgets( line , 1024 , stdin ) )
{
param.X_input = line;
if( 0 == yyparse( ¶m ) )
{
printf( "%d\n" , param.result );
}
}
return 0;
}
------ bison Xexpr.y -o Xexpr.c -------
------ gcc -o Xexpr Xexpr.c -------
74
#include <iostream>
#include <string>
#include <locale>
#include <sstream>
class RightExpressionEvaluator {
public:
explicit RightExpressionEvaluator(std::istream& input) : input(input) {
}
int evaluate() {
return evaluateLeftOperand() + evaluateRightOperand();
}
private:
int evaluateLeftOperand() {
return readNextToken() ? parseLeftOperand() : 0;
}
int parseLeftOperand() {
if (isOpenBracket(token)) {
return evaluate();
}
else if (isDigit(token)) {
return readNextInteger();
}
return 0;
}
int evaluateRightOperand() {
return readNextToken() ? parseRightOperand() : 0;
}
int parseRightOperand() {
switch (token) {
case '+': return 2 * evaluate();
case '-': return -3 * evaluate();
}
return 0;
}
int readNextInteger() {
int result = 0;
input.unget();
input >> result;
return result;
}
bool readNextToken() {
return input.get(token).good();
}
bool isOpenBracket(char token) {
return token == '(' || token == '[';
}
bool isDigit(char token) {
return std::isdigit(token, std::locale());
}
private:
std::istream& input;
char token;
};
void testEvaluator(const std::string& expression) {
std::istringstream input(expression);
std::cout << "expression: " << expression << std::endl;
std::cout << "value : " << RightExpressionEvaluator(input).evaluate() << std::endl;
std::cout << std::endl;
}
int main() {
testEvaluator("2");
testEvaluator("2+2");
testEvaluator("2-2");
testEvaluator("2-(2+2)");
testEvaluator("2-[2+2]");
testEvaluator("(2-2)+(2+2)");
testEvaluator("[2-2]-(2+2)");
testEvaluator("(34+28+28)+[(7+8)-(9+10)]");
}