역시 SB 네요.

원 리 를 컴 파일 한 용 서 와 호 서 는 각각 두 장 씩 본 후에..................................................................
 
좋 습 니 다. 우리 라면 말단 부터 시작 해 야 합 니 다. 저 는 handwritten C 나 C 의 작은 부분 집합 인 one - pass 컴 파일 러 를 먼저 시도 해 보 겠 습 니 다. 깊 은 경험 을 한 다음 에 깊 은 형식 이론 을 연구 하 는 것 도 늦 지 않 습 니 다.그래서 저 는 며칠 동안 간단 한 품사 분석 을 했 고 힘 도 들 었 습 니 다. 급 한 아 이 큐 로 문법 트 리 같은 것 을 만들어 서 네 가지 연산 식 을 해석 할 수 있 습 니 다.책 에서 손 으로 쓴 컴 파일 러 는 재 귀 하강 법 이 가장 적합 하 다 고 말 했 는데, 나 는 한참 을 생각 했 지만 어떻게 재 귀 하강 해 야 할 지 몰 랐 다.방금 책 을 읽 은 간단 한 손 글씨 문법 분석 기 를 보 았 는데 모두 100 줄 밖 에 안 되 었 다. 나 는 책 을 보고 감탄 할 수 밖 에 없 었 다. 아, 바닥 이 전혀 딱딱 하지 않 아서 멀 었 다.
 
며칠 동안 hardcode 의 소감 을 썼 습 니 다.
마침내 왜 책 에서 우리 에 게 문법의 BNF 생 성식 을 모두 열거 하 라 고 했 는 지 알 게 되 었 다. 그리고 그 에 상응하는 모든 생 성식 을 위해 함 수 를 썼 다. 이것 은 사실 알고리즘 결합 을 풀 고 있 는 것 이다.예 를 들 어 우 리 는 아래 의 재 귀 하강 문법 기 는 unary operator 를 지원 하지 않 는 다 는 것 을 테스트 할 수 있다. 예 를 들 어 3 * - 2.이 연산 규칙 에 가입 하려 면 문법 에 규칙 을 새로 추가 한 다음 에 문법 을 수리 하고 마지막 으로 인 코딩: 순환 이 떨 어 지 는 단계 에 unary () 함 수 를 추가 하고 하층 은 factor () 이 며 상층 은 term () 이 며 완성 합 니 다.이렇게 하면 새로운 함 수 를 추가 하여 논리 연산 을 지원 하고 비교 연산 을 확장 할 수 있다.나 처럼 하 드 코드 라면...확장 할 때 비상 하 는 느낌 이 단번에 나 왔 다.
그리고 이와 같은 문법 적 특성 을 고려 하면:
a = b = c = 1;
재 귀 하강 법 을 이용 해도 완벽 하고 간결 하 게 해결 할 수 있 잖 아!
 
왜 원 리 를 컴 파일 해 야 합 니까?제 가 손 으로 쓴 것 은 점점 이탈리아 국수 가 되 었 기 때문에 하나의 feature 를 확대 할 때마다 온몸 을 움 직 였 습 니 다. 다른 곳 에 bug 를 도 입 했 는 지 전혀 확실 하지 않 습 니 다. 마지막 에 일반적인 C 코드 파일 을 컴 파일 할 수 있 을 지도 모 릅 니 다. 그런데 저 는 TM 가 왜 작 동 하 는 지 모 르 겠 습 니 다. 다른 플랫폼 에 이식 하거나 다른 언어의 컴 파일 러 를 다시 만 들 려 고 할 때어 리 석 을 수 밖 에 없다. 이것 이 바로 '인품 으로 프로 그래 밍' 이다. 이것 이 우리 의 상징적 인 특징 이다. 먼저 기능 을 끝내 고 bug 는 없 는 말 을 하지 못 한다. 야근 으로 보충 하 는 것 은 아니 지........................................................................................
 
 
코드 붙 이기:
 
표준 재 귀 하강 문법 기:
  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 
  4 char token; /*      */
  5 
  6 /*         */
  7 int exp( void );
  8 int term( void );
  9 int factor( void );
 10 
 11 void error( void ) /*         */
 12 {
 13     fprintf( stderr, "  
"); 14 exit( 1 ); 15 } 16 17 void match( char expectedToken ) /* */ 18 { 19 if( token == expectedToken ) token = getchar(); /**/ 20 else error(); /**/ 21 } 22 void Message(void) 23 { 24 printf("================================================================
"); 25 printf("* *
"); 26 printf("****************************************************************
"); 27 printf(" : , . 45*(12-2)[ ]
"); 28 printf("*****************************************************************

"); 29 } 30 main() 31 { 32 int result; /* */ 33 Message(); 34 printf(" >> : "); 35 token = getchar(); /* */ 36 37 result = exp(); /* */ 38 if( token == '
' ) /* */ 39 printf( " >> : %d
", result ); 40 else error(); /* */ 41 puts("

...
"); 42 getch(); 43 return 0; 44 } 45 46 int exp( void ) 47 { 48 int temp = term(); /* */ 49 while(( token == '+' ) || ( token == '-' )) 50 switch( token ) { 51 case '+': match('+'); /* */ 52 temp += term(); 53 break; 54 case '-': match('-'); 55 temp -= term(); /* */ 56 break; 57 } 58 return temp; 59 } 60 61 int term( void ) 62 { 63 int div; /* */ 64 int temp = factor(); /* */ 65 while(( token == '*' ) || ( token == '/' )) 66 switch( token ) { 67 case '*': match('*'); /* */ 68 temp *= factor(); 69 break; 70 case '/': match('/'); /* */ 71 div = factor(); 72 if( div == 0 ) /* 0*/ 73 { 74 fprintf( stderr, " 0.
" ); 75 exit(1); 76 } 77 temp /= div; 78 break; 79 } 80 return temp; 81 } 82 83 int factor( void ) 84 { 85 int temp; 86 if( token == '(' ) /* */ 87 { 88 match( '(' ); 89 temp = exp(); 90 match(')'); 91 } 92 else if ( isdigit( token )) /* */ 93 { 94 ungetc( token, stdin ); /* */ 95 scanf( "%d", &temp ); /* */ 96 token = getchar(); /* */ 97 } 98 else error(); /* */ 99 return temp; 100 }

 
 
나의 비상 코드:
 
  1 #include "StdAfx.h"
  2 #include "SyntaxTree.h"
  3 #include "Compiler.h"
  4 
  5 eTokenType SyntaxTree::lastTokenType = eTokenType_Invalid;
  6 
  7 int SyntaxTreeOpNode::Evaluate()
  8 {
  9     if (!strcmp(op, "+"))
 10     {
 11         return lchild->Evaluate() + rchild->Evaluate();
 12     }
 13     else if (!strcmp(op, "-"))
 14     {
 15         return lchild->Evaluate() - rchild->Evaluate();
 16     }
 17     else if (!strcmp(op, "*"))
 18     {
 19         return lchild->Evaluate() * rchild->Evaluate();
 20     }
 21     else if (!strcmp(op, "/"))
 22     {
 23         return lchild->Evaluate() / rchild->Evaluate();
 24     }
 25     else
 26     {
 27         //TODO: refactoring for no ugly if-else
 28         assert(0);
 29         return 0;
 30     }
 31 }
 32 
 33 bool SyntaxTreeOpNode::IsThisOpPriorityHigher( const char* s )
 34 {
 35     return cl.opPriorityMap[op] >= cl.opPriorityMap[s];
 36 }
 37 
 38 int SyntaxTreeLeafNode::Evaluate()
 39 {
 40     return value;
 41 }
 42 
 43 int SyntaxTreeRootNode::Evaluate()
 44 {
 45     assert(rchild && "WTF!? This is not my tree!");
 46     return rchild->Evaluate();
 47 }
 48 
 49 SyntaxTree::SyntaxTree()
 50 :root(nullptr)
 51 {
 52 }
 53 
 54 SyntaxTree::~SyntaxTree()
 55 {
 56     ResetTree();
 57 }
 58 
 59 bool SyntaxTree::ConstructTree(int len)
 60 {
 61     const char* expstart = cl.sentence + cl.sentence_curpos;
 62     assert(expstart[0] != 0);
 63     char op[MAX_IDENT_LEN];
 64     eTokenType type;
 65     SyntaxTreeNode* curNode = root;
 66     std::vector<int> vecNums;
 67     std::vector<SyntaxTreeOpNode*> vecFlatNodes;
 68 
 69     //1.           
 70     while (cl.sentence_curpos < len)
 71     {
 72         type = cl.ScanWord(op);
 73         if (type == eTokenType_Operator)
 74         {
 75             auto iter = cl.opPriorityMap.find(op);
 76             assert(iter != cl.opPriorityMap.end() && "Invalid op!");
 77             SyntaxTreeOpNode* node = new SyntaxTreeOpNode;
 78             strcpy_s(node->op, ARRAYSIZE(node->op), op);
 79 
 80             //unary op process
 81             bool bUnary = op[1]==0 && (op[0]=='+' || op[0]=='-');
 82             if (lastTokenType==eTokenType_Operator || lastTokenType==eTokenType_LBracket && bUnary)
 83             {
 84                 vecNums.push_back(0);
 85                 curNode->rchild = node;
 86                 node->parent = curNode;
 87             }
 88             else if (curNode->IsThisOpPriorityHigher(op))
 89             {
 90                 assert(node->parent == nullptr);
 91                 curNode->parent = node;
 92                 node->lchild = curNode;
 93                 //  root  
 94                 root->rchild = node;
 95                 node->parent = root;
 96             } 
 97             else
 98             {
 99                 curNode->rchild = node;
100                 node->parent = curNode;
101             }
102             curNode = node;
103             vecFlatNodes.push_back(node);
104         }
105         else if (type == eTokenType_ConstantNumber)
106         {
107             vecNums.push_back(atoi(op));
108         }
109         else if (type == eTokenType_LBracket)
110         {
111             int substr_len = len - 1;
112             //must find a matching r-bracket!
113             bool bFind = false;
114             while (substr_len >= cl.sentence_curpos)
115             {
116                 if(cl.sentence[substr_len] == ')')
117                 {
118                     bFind = true;
119                     break;
120                 }
121                 --substr_len;
122             }
123             if (bFind)
124             {
125                 //    ,         ...
126                 SyntaxTree tmpTree;
127                 tmpTree.ResetTree();
128                 if(tmpTree.ConstructTree(substr_len))
129                     vecNums.push_back(tmpTree.Evaluate());
130                 else
131                     return false;
132 
133                 assert(cl.sentence[cl.sentence_curpos] == ')' && "Can't be true!...");
134                 ++cl.sentence_curpos;
135             } 
136             else
137             {
138                 LOG_ERR(eErr_NotMatchBracket);
139                 return false;
140             }
141             type = eTokenType_ConstantNumber;
142         }
143         else
144         {
145             LOG_ERR(eErr_InvalidExpression);
146             return false;
147         }
148         lastTokenType = type;
149     }
150 
151     //2.             
152     if (root->rchild == nullptr)
153     {
154         LOG_ERR(eErr_InvalidExpression);
155         return false;
156     }
157 
158     size_t leaf = 0, totalLeaf = vecNums.size();
159     for (size_t i=0; i<vecFlatNodes.size(); ++i)
160     {
161         SyntaxTreeOpNode* node = vecFlatNodes[i];
162         if (!node->lchild)
163         {
164             if (leaf < totalLeaf)
165             {
166                 SyntaxTreeLeafNode* leafNode = new SyntaxTreeLeafNode;
167                 leafNode->value = vecNums[leaf];
168                 node->lchild = leafNode;
169                 leafNode->parent = node;
170                 ++leaf;
171             }
172             else
173             {
174                 LOG_ERR(eErr_InvalidExpression);
175                 return false;
176             }
177         }
178         if (!node->rchild)
179         {
180             if (leaf < totalLeaf)
181             {
182                 SyntaxTreeLeafNode* leafNode = new SyntaxTreeLeafNode;
183                 leafNode->value = vecNums[leaf];
184                 node->rchild = leafNode;
185                 leafNode->parent = node;
186                 ++leaf;
187             }
188             else
189             {
190                 LOG_ERR(eErr_InvalidExpression);
191                 return false;
192             }
193         }
194     }
195 
196     return true;
197 }
198 
199 void SyntaxTree::ResetTree()
200 {
201     SAFE_DELETE(root);
202     root = new SyntaxTreeRootNode;
203 }
204 
205 int SyntaxTree::Evaluate()
206 {
207     return root->Evaluate();
208 }

 
 
마지막 으로 본의 아니 게 이 친구 가 만 지 작 거 리 는 걸 봤 어 요. 나 보다 못 한 것 같 아 요..................................................와 하하 하, 슬 픈 우리 야
http://blog.csdn.net/zhouzxi/article/details/7897301

좋은 웹페이지 즐겨찾기