编程实现英文数字到中文大写数字的转换 分类: 编译原理 2014-06-02 15:15 541人阅读 评论(0) 收藏

本程序实现英文数字到中文大写数字的转换。
主要思想是利用该语法自底向上地构造出1——>999999999999;
然后将数字转换成中文大写。
利用flex进行词法分析,bison进行句法分析。


语法如下:
e1-->one|two|three|four|five|six|seven|eight|nine
e2-->ten|eleven|twelve|thirteen|fourteen|fifteen|sixteen|seventeen|eighteen|nineteen
e3-->twenty|thirty|forty|fifty|sixty|seventy|eighty|ninety
 
e4-->e3-e1
    |e3
    |e2
    |e1
 
e51-->e1 hundred and e4
     |e1 hundred
e52-->e51
     |e4
 
e61-->e52 thousand e51
     |e52 thousand and e4
     |e52 thousand  
e62-->e61
     |e52
 
e71-->e52 million e61
     |e52 million e51
     |e52 million and e4
     |e52 million
e72-->e71
     |e62
 
e81-->e52 billion e71
     |e52 billion e61
     |e52 billion e51
     |e52 billion and e4
     |e52 billion
e82-->e81
     |e72
     |zero


lex.l文件如下:

%%
zero     {yylval=0;return ZERO;}
one      {yylval=1;return NUM1;}
two      {yylval=2;return NUM1;}
three    {yylval=3;return NUM1;}
four     {yylval=4;return NUM1;}
five     {yylval=5;return NUM1;}
six      {yylval=6;return NUM1;}
seven    {yylval=7;return NUM1;}
eight    {yylval=8;return NUM1;}
nine     {yylval=9;return NUM1;}
ten    	 {yylval=10;return NUM2;}
eleven 	 {yylval=11;return NUM2;}
twelve 	 {yylval=12;return NUM2;}
thirteen {yylval=13;return NUM2;}
fourteen {yylval=14;return NUM2;}
fifteen	 {yylval=15;return NUM2;}
sixteen	 {yylval=16;return NUM2;}
seventeen {yylval=17;return NUM2;}
eighteen {yylval=18;return NUM2;}
nineteen {yylval=19;return NUM2;}
twenty   {yylval=20;return NUM3;}
thirty   {yylval=30;return NUM3;}
forty    {yylval=40;return NUM3;}
fifty    {yylval=50;return NUM3;}
sixty    {yylval=60;return NUM3;}
seventy  {yylval=70;return NUM3;}
eighty   {yylval=80;return NUM3;}
ninety   {yylval=90;return NUM3;}
hundred  {return HUNDRED;}
thousand {return THOUSAND;}
million  {return MILLION;}
billion  {return BILLION;}
and      {return AND;}
[ \t]+   /* skip blanks */
.|\n     { return yytext[0];}




parser.y文件如下:

%{
#include<cmath>
#include <string>
#include <iostream>
using namespace std;
void yyerror(string msg);
string trans(int term);
void dtos(long term,string &result);
int yylex();
#define YYSTYPE long
%}
%token NUM1
%token NUM2
%token NUM3
%token ZERO
%token HUNDRED
%token THOUSAND
%token MILLION
%token BILLION
%token AND
%%
lines : lines e82 '\n' {string result;dtos($2,result);cout<<result<<endl;}
      | lines '\n'
      | /*empty*/
      |error '\n' {yyerrok;}
      ;

e82:e81  {$$=$1;}
   |e72  {$$=$1;}
   |ZERO {$$=0;}
   ;
e81:e52 BILLION e71    {$$=$1*pow(10,9)+$3;}
   |e52 BILLION e61    {$$=$1*pow(10,9)+$3;}
   |e52 BILLION e51    {$$=$1*pow(10,9)+$3;}
   |e52 BILLION AND e4 {$$=$1*pow(10,9)+$4;}
   |e52 BILLION        {$$=$1*pow(10,9);}
   ;

e72:e71 {$$=$1;}
   |e62 {$$=$1;}
   ;
e71:e52 MILLION e61    {$$=$1*pow(10,6)+$3;}
   |e52 MILLION e51    {$$=$1*pow(10,6)+$3;}
   |e52 MILLION AND e4 {$$=$1*pow(10,6)+$4;}
   |e52 MILLION        {$$=$1*pow(10,6);}
   ;

e62:e61 {$$=$1;}
   |e52 {$$=$1;}
   ;
e61:e52 THOUSAND e51 {$$=$1*pow(10,3)+$3;}
   |e52 THOUSAND AND e4 {$$=$1*pow(10,3)+$4;}
   |e52 THOUSAND {$$=$1*pow(10,3);}
   ;

e52:e51 {$$=$1;}
   |e4 {$$=$1;}
   ;
e51:e1 HUNDRED AND e4 {$$=$1*pow(10,2)+$4;}
   |e1 HUNDRED {$$=$1*pow(10,2);}
   ;

e4:e3'-'e1{$$=$1+$3;}
  |e3 {$$=$1;}
  |e2 {$$=$1;}
  |e1 {$$=$1;}
  ;
e3:NUM3 {$$=$1;}
  ;
e2:NUM2 {$$=$1;}
  ;
e1:NUM1 {$$=$1;}
  ;
%%
#include "lex.yy.c"
int main() 
{
    return yyparse();
}

void yyerror(string msg) {
    cout<<msg<<endl;
}
string trans(int term)
{
 if(term==1)
 return "壹";
 if(term==2)
 return "贰";
 if(term==3)
 return "叁";
 if(term==4)
 return "肆";
 if(term==5)
 return "伍";
 if(term==6)
 return "陆";
 if(term==7)
 return "柒";
 if(term==8)
 return "捌";
 if(term==9)
 return "玖";
}
void dtos(long term,string &result)
{
 bool flag1=false,flag2=false,flag3=false,flag4=false;
 long temp1=term/100000000;
 if(temp1!=0)
 {
  flag1=true;
  dtos(temp1,result);
  result+="亿";
 }
 term%=100000000;
 long temp2=term/10000;
 if(temp2!=0)
 {
  if(temp2<1000)
  {
   if(flag1)
    result+="零";
  }
  flag2=true;
  dtos(temp2,result);
  result+="万";
 } 
 else if(flag1)
 { result+="零";}

 term%=10000;
 long temp3=term/1000;
 if(temp3!=0)
 {
  flag3=true;
  result+=trans(temp3);
  result+="仟";
 }
 else if(flag2)
 {result+="零";}
 term%=1000;
 long temp4=term/100;
 if(temp4!=0)
 {
  flag4=true;
  result+=trans(temp4);
  result+="佰";
 } 
 else if(flag3)
 {result+="零";}
 term%=100;
 long temp5=term/10; 
 if(temp5!=0)
 {
  result+=trans(temp5);
  result+="拾";
 }
 else if(flag4)
 {result+="零";}
 term%=10;
 long temp6=term;
 if(temp6!=0)
 result+=trans(temp6);
 if(result=="")
 result+="零";
 string temp=result.substr(result.length()-3,result.length());
 if((result!="零")&&(temp=="零"))
 {
   result=result.substr(0,result.length()-3);
 }
}


程序的运行:
flex lex.l
bison parser.y
g++ parser.tab.c -ly -ll
./a.out
输入英文数字回车得到对应的中文大写。

版权声明:本文为博主原创文章,未经博主允许不得转载。

posted @ 2014-06-02 15:15  xiaoluo91  阅读(223)  评论(0编辑  收藏  举报