Äàâàéòå ñîçäàäèì êîìïèëÿòîð!	
	ModernLib.Net / Ïðîãðàììèðîâàíèå / Êðåíøîó Äæåê / Äàâàéòå ñîçäàäèì êîìïèëÿòîð! - ×òåíèå
			(ñòð. 12)
			 
	
	
	
	
	| 
	Àâòîð:
	 | 
	
	Êðåíøîó Äæåê | 
	 
	
	| 
	Æàíð:
	 | 
	
	Ïðîãðàììèðîâàíèå | 
	 
		
	| 
   
  
	
			- 
					×èòàòü êíèãó ïîëíîñòüþ
					(666 Êá)
		
 
					- Ñêà÷àòü â ôîðìàòå fb2
			(192 Êá)
			
 
						- Ñêà÷àòü â ôîðìàòå doc
			(207 Êá)
			
 
						- Ñêà÷àòü â ôîðìàòå txt
			(181 Êá)
			
 
						- Ñêà÷àòü â ôîðìàòå html
			(198 Êá)
			
 
			- Ñòðàíèöû:
 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 	 
	 | 
	 
	
	 
	 | 
	 
	 
	 
			
		
	       Íàêîíåö, ìû äîëæíû âíåñòè èçìåíåíèÿ, ïîçâîëÿþùèå èñïîëüçîâàòü Token âìåñòî Look êàê ñèìâîëà äëÿ ïðîâåðêè è âûçûâàòü Scan â ïîäõîäÿùèõ ìåñòàõ. Ïî áîëüøåé ÷àñòè ýòî âêëþ÷àåò óäàëåíèå âûçîâîâ Match, ðåäêèå çàìåíû âûçîâîâ Match íà âûçîâû MatchString, è çàìåíó âûçîâîâ NewLine íà âûçîâû Scan. Âîò çàòðîíóòûå ïîäïðîãðàììû: 
      {–} 
      { Recognize and Translate an IF Construct } 
      procedure Block; Forward; 
      procedure DoIf; 
      var L1, L2: string; 
      begin 
      BoolExpression; 
      L1 := NewLabel; 
      L2 := L1; 
      BranchFalse(L1); 
      Block; 
      if Token = 'l' then begin 
      L2 := NewLabel; 
      Branch(L2); 
      PostLabel(L1); 
      Block; 
      end; 
      PostLabel(L2); 
      MatchString('ENDIF'); 
      end; 
      {–} 
      { Parse and Translate a WHILE Statement } 
      procedure DoWhile; 
      var L1, L2: string; 
      begin 
      L1 := NewLabel; 
      L2 := NewLabel; 
      PostLabel(L1); 
      BoolExpression; 
      BranchFalse(L2); 
      Block; 
      MatchString('ENDWHILE'); 
      Branch(L1); 
      PostLabel(L2); 
      end; 
      {–} 
      { Parse and Translate a Block of Statements } 
      procedure Block; 
      begin 
      Scan; 
      while not(Token in ['e', 'l']) do begin 
      case Token of 
      'i': DoIf; 
      'w': DoWhile; 
      else Assignment; 
      end; 
      Scan; 
      end; 
      end; 
      {–} 
      { Parse and Translate Global Declarations } 
      procedure TopDecls; 
      begin 
      Scan; 
      while Token <> 'b' do begin 
      case Token of 
      'v': Decl; 
      else Abort('Unrecognized Keyword ' + Value); 
      end; 
      Scan; 
      end; 
      end; 
      {–} 
      { Parse and Translate a Main Program } 
      procedure Main; 
      begin 
      MatchString('BEGIN'); 
      Prolog; 
      Block; 
      MatchString('END'); 
      Epilog; 
      end; 
      {–} 
      { Parse and Translate a Program } 
      procedure Prog; 
      begin 
      MatchString('PROGRAM'); 
      Header; 
      TopDecls; 
      Main; 
      Match('.'); 
      end; 
      {–} 
      { Initialize } 
      procedure Init; 
      var i: char; 
      begin 
      for i := 'A' to 'Z' do 
      ST[i] := ' '; 
      GetChar; 
      Scan; 
      end; 
      {–} 
 
       Ýòî äîëæíî ðàáîòàòü. Åñëè âñå èçìåíåíèÿ ñäåëàíû ïðàâèëüíî, âû äîëæíû òåïåðü àíàëèçèðîâàòü ïðîãðàììû, êîòîðûå âûãëÿäÿò êàê ïðîãðàììû. (Åñëè âû íå ñäåëàëè âñåõ èçìåíåíèé, íå îò÷àèâàéòåñü. Ïîëíûé ëèñòèíã êîíå÷íîé ôîðìû äàí íèæå.)       Ðàáîòàåò? Åñëè äà, òî ìû ïî÷òè äîìà. Ôàêòè÷åñêè, ñ íåñêîëüêèìè íåáîëüøèìè èñêëþ÷åíèÿìè, ìû óæå ïîëó÷èëè êîìïèëÿòîð, ïðèãîäíûé äëÿ èñïîëüçîâàíèÿ. Èìåþòñÿ åùå íåñêîëüêî îáëàñòåé, òðåáóþùèõ óñîâåðøåíñòâîâàíèÿ.
 
Ìíîãîñèìâîëüíûå èìåíà ïåðåìåííûõ 
      Îäíà èç íèõ – îãðàíè÷åíèå, òðåáóþùåå èñïîëüçîâàíèÿ îäíîñèìâîëüíûõ èìåí ïåðåìåííûõ. Òåïåðü, êîãäà ìû ìîæåì îáðàáàòûâàòü ìíîãîñèìâîëüíûå êëþ÷åâûå ñëîâà, ýòî îãðàíè÷åíèå íà÷èíàåò êàçàòüñÿ ïðîèçâîëüíûì è íåíóæíûì. È äåéñòâèòåëüíî ýòî òàê.  îñíîâíîì, åäèíñòâåííîå åãî äîñòîèíñòâî â òîì, ÷òî îí ïîçâîëÿåò ïîëó÷èòü òðèâèàëüíî ïðîñòóþ ðåàëèçàöèþ òàáëèöû èäåíòèôèêàòîðîâ. Íî ýòî ïðîñòî óäîáñòâî äëÿ ñîçäàòåëåé êîìïèëÿòîðîâ è îíî äîëæíî áûòü óíè÷òîæåíî.       Ìû óæå äåëàëè ýòîò øàã ïðåæäå. Íà ýòîò ðàç, êàê îáû÷íî, ÿ ñäåëàþ ýòî íåìíîãî ïî-äðóãîìó. ß äóìàþ ïîäõîä, ïðèìåíåííûé çäåñü, ñîõðàíèò ïðîñòîòó íàñòîëüêî, íàñêîëüêî ýòî âîçìîæíî.       Åñòåñòâåííûì ïóòåì ðåàëèçàöèè òàáëèöû èäåíòèôèêàòîðîâ íà Pascal ÿâëÿåòñÿ îáúÿâëåíèå ïåðåìåííîé òèïà çàïèñü è ñîçäàíèå òàáëèöû èäåíòèôèêàòîðîâ êàê ìàññèâà òàêèõ çàïèñåé. Çäåñü, îäíàêî, íàì â äåéñòâèòåëüíîñòè ïîêà íå íóæíî ïîëå òèïà (ñóùåñòâóåò ïîêà ÷òî òîëüêî îäèí ðàçðåøåííûé òèï), òàê ÷òî íàì íóæåí òîëüêî ìàññèâ ñèìâîëîâ. Ýòî èìååò ñâîå ïðåèìóùåñòâî, ïîòîìó ÷òî ìû ìîæåì èñïîëüçîâàòü ñóùåñòâóþùóþ ïðîöåäóðó Lookup äëÿ ïîèñêà â òàáëèöå èäåíòèôèêàòîðîâ òàêæå êàê è â ñïèñêå êëþ÷åâûõ ñëîâ. Îêàçûâàåòñÿ, äàæå êîãäà íàì íóæíû áîëüøå ïîëåé, ìû âñå ðàâíî ìîæåì èñïîëüçîâàòü òîò æå ñàìûé ïîäõîä, ïðîñòî ñîõðàíÿÿ äðóãèå ïîëÿ â îòäåëüíûõ ìàññèâàõ.       Âîò èçìåíåíèÿ, êîòîðûå íåîáõîäèìî ñäåëàòü. Ñïåðâà äîáàâüòå íîâóþ òèïèçèðîâàííóþ êîíñòàíòó:       NEntry: integer = 0;       Çàòåì èçìåíèòå îïðåäåëåíèå òàáëèöû èäåíòèôèêàòîðîâ êàê ïîêàçàíî íèæå:       const MaxEntry = 100;       var ST : array[1..MaxEntry] of Symbol;       (Îáðàòèòå âíèìàíèå, ÷òî ST íå îáúÿâëåí êàê SymTab. Ýòî îáúÿâëåíèå ëèïîâîå, ÷òîáû çàñòàâèòü Lookup ðàáîòàòü. SymTab çàíÿëÿ áû ñëèøêîì ìíîãî ïàìÿòè è ïîýòîìó ôàêòè÷åñêè íèêîãäà íå îáüÿâëÿåòñÿ).       Çàòåì ìû äîëæíû çàìåíèòü InTable. 
      {–} 
      { Look for Symbol in Table } 
      function InTable(n: Symbol): Boolean; 
      begin 
      InTable := Lookup(@ST, n, MaxEntry) <> 0; 
      end; 
      {–} 
 
       Íàì òàêæå íåîáõîäèìà íîâàÿ ïðîöåäóðà AddEntry, êîòîðàÿ äîáàâëÿåò íîâûé ýëåìåíò â òàáëèöó: 
      {–} 
      { Add a New Entry to Symbol Table } 
      procedure AddEntry(N: Symbol; T: char); 
      begin 
      if InTable(N) then Abort('Duplicate Identifier ' + N); 
      if NEntry = MaxEntry then Abort('Symbol Table Full'); 
      Inc(NEntry); 
      ST[NEntry] := N; 
      SType[NEntry] := T; 
      end; 
      {–} 
 
       Ýòà ïðîöåäóðà âûçûâàåòñÿ èç Alloc: 
      {–} 
      { Allocate Storage for a Variable } 
      procedure Alloc(N: Symbol); 
      begin 
      if InTable(N) then Abort('Duplicate Variable Name ' + N); 
      AddEntry(N, 'v'); 
      . 
      . 
      . 
      {–} 
 
       Íàêîíåö, ìû äîëæíû èçìåíèòü âñå ïîäïðîãðàììû, êîòîðûå â íàñòîÿùåå âðåìÿ îáðàáàòûâàþò èìåíà ïåðåìåííûõ êàê îäèíî÷íûé ñèìâîë. Îíè âêëþ÷àþò LoadVar è Store (ïðîñòî èçìåíèòå òèï ñ char íà string) è Factor, Assignment è Decl (ïðîñòî èçìåíèòå Value[1] íà Value).       Ïîñëåäíÿÿ âåùü: èçìåíèòå ïðîöåäóðó Init äëÿ î÷èñòêè ìàññèâà êàê ïîêàçàíî íèæå: 
      {–} 
      { Initialize } 
      procedure Init; 
      var i: integer; 
      begin 
      for i := 1 to MaxEntry do begin 
      ST[i] := ''; 
      SType[i] := ' '; 
      end; 
      GetChar; 
      Scan; 
      end; 
      {–} 
 
       Ýòî äîëæíî ðàáîòàòü. Èñïûòàéòå åå è ïðîâåðüòå, ÷òî âû äåéñòâèòåëüíî ìîæåòå èñïîëüçîâàòü ìíîãîñèìâîëüíûå èìåíà ïåðåìåííûõ.  
Ñíîâà îïåðàòîðû îòíîøåíèé 
      Ó íàñ îñòàëîñü ïîñëåäíåå îäíîñèìâîëüíîå îãðàíè÷åíèå – îãðàíè÷åíèå îïåðàòîðîâ îòíîøåíèé. Íåêîòîðûå èç îïåðàòîðîâ îòíîøåíèé äåéñòâèòåëüíî ñîñòîÿò èç îäèíî÷íûõ ñèìâîëîâ, íî äðóãèå òðåáóþò äâóõ. Ýòî '<=' è '>='. ß òàêæå ïðåäïî÷èòàþ Ïàñêàëåâñêîå '<>' äëÿ «íå ðàâíî» âìåñòî '#'.       Êàê âû ïîìíèòå, â ãëàâå 7 ÿ óêàçàë, ÷òî ñòàíäàðòíûé ñïîñîá ðàáîòû ñ îïåðàòîðàìè îòíîøåíèé – âêëþ÷èòü èõ â ñïèñîê êëþ÷åâûõ ñëîâ è ïîçâîëèòü ëåêñè÷åñêîìó àíàëèçàòîðó îòûñêèâàòü èõ. Íî, îïÿòü, ýòî òðåáóåò âûïîëíåíèå ïîëíîãî àíàëèçà âûðàæåíèÿ, òîãäà êàê äî ýòîãî ìû ó íàñ áûëà âîçìîæíîñòü îãðàíè÷èòü èñïîëüçîâàíèå ñêàíåðà íà÷àëîì óòâåðæäåíèÿ.       ß óïîìÿíóë òîãäà, ÷òî ìû âñå æå ìîæåì èçáåæàòü íåïðèÿòíîñòåé ñ ýòèì, òàê êàê ìíîãîñèìâîëüíûõ îïåðàòîðîâ îòíîøåíèé íåìíîãî è îíè îãðàíè÷åíû â ïðèìåíåíèè. Áûëî áû ëåãêî îáðàáàòûâàòü èõ ïðîñòî êàê ñïåöèàëüíûå ñëó÷àè è ïîääåðæèâàòü èõ ñïåöèàëüíûì ñïîñîáîì.       Òðåáóåìûå èçìåíåíèÿ âëèÿþò òîëüêî íà ïîäïðîãðàììû ãåíåðàöèè êîäà è ïðîöåäóðû Relation è åå äðóçåé. Ñïåðâà, íàì ïîíàäîáÿòñÿ åùå äâå ïîäïðîãðàììû ãåíåðàöèè êîäà: 
      {–} 
      { Set D0 If Compare was <= } 
      procedure SetLessOrEqual; 
      begin 
      EmitLn('SGE D0'); 
      EmitLn('EXT D0'); 
      end; 
      {–} 
      { Set D0 If Compare was >= } 
      procedure SetGreaterOrEqual; 
      begin 
      EmitLn('SLE D0'); 
      EmitLn('EXT D0'); 
      end; 
      {–} 
 
       Çàòåì èçìåíèòå ïîäïðîãðàììû àíàëèçà îòíîøåíèé êàê ïîêàçàíî íèæå: 
      {–} 
      { Recognize and Translate a Relational «Less Than or Equal» } 
      procedure LessOrEqual; 
      begin 
      Match('='); 
      Expression; 
      PopCompare; 
      SetLessOrEqual; 
      end; 
      {–} 
      { Recognize and Translate a Relational «Not Equals» } 
      procedure NotEqual; 
      begin 
      Match('>'); 
      Expression; 
      PopCompare; 
      SetNEqual; 
      end; 
      {–} 
      { Recognize and Translate a Relational «Less Than» } 
      procedure Less; 
      begin 
      Match('<'); 
      case Look of 
      '=': LessOrEqual; 
      '>': NotEqual; 
      else begin 
      Expression; 
      PopCompare; 
      SetLess; 
      end; 
      end; 
      end; 
      {–} 
      { Recognize and Translate a Relational «Greater Than» } 
      procedure Greater; 
      begin 
      Match('>'); 
      if Look = '=' then begin 
      Match('='); 
      Expression; 
      PopCompare; 
      SetGreaterOrEqual; 
      end 
      else begin 
      Expression; 
      PopCompare; 
      SetGreater; 
      end; 
      end; 
      {–} 
 
       Ýòî âñå, ÷òî òðåáóåòñÿ. Òåïåðü âû ìîæåòå îáðàáàòûâàòü âñå îïåðàòîðû îòíîøåíèé. Ïîïðîáóéòå.  
Ââîä/Âûâîä 
      Òåïåðü ó íàñ åñòü ïîëíûé, ðàáîòàþùèé ÿçûê, çà èñêëþ÷åíèåì îäíîãî íåáîëüøîãî ñìóùàþùåãî ôàêòà: ó íàñ íåò íèêàêîãî ñïîñîáà ïîëó÷èòü èëè âûâåñòè äàííûå. Íàì íóæíû ïîäïðîãðàììû ââîäà/âûâîäà.       Ñîâðåìåííîå ñîãëàøåíèå, óñòàíîâëåííîå â C è ïðîäîëæåííîå â Ada è Modula-2, ñîñòîèò â òîì, ÷òîáû âûâåñòè I/O îïåðàòîðû èç ñàìîãî ÿçûêà è ïðîñòî âêëþ÷èòü èõ â áèáëèîòåêó ïîäïðîãðàìì. Ýòî áûëî áû ïðåêðàñíî, çà èñêëþ÷åíèåì òîãî, ÷òî ìû ïîêà íå èìååì íèêàêèõ ñðåäñòâ ïîääåðæêè ïîäïðîãðàìì.  ëþáîì ñëó÷àå, ñ ýòèì ïîäõîäîì âû ñòîëêíåòåñü ñ ïðîáëåìîé ïåðåìåííîé äëèíû ñïèñêà ïàðàìåòðîâ.  Ïàñêàëå I/O îïåðàòîðû âñòðîåíû â ÿçûê, ïîýòîìó ýòî åäèíñòâåííûå îïåðàòîðû, äëÿ êîòîðûõ ñïèñîê ïàðàìåòðîâ ìîæåò èìåòü ïåðåìåííîå ÷èñëî ýëåìåíòîâ.  C ìû ïðèìèðÿåìñÿ ñ êëóäæàìè òèïà scanf è printf è äîëæíû ïåðåäàâàòü êîëè÷åñòâî ïàðàìåòðîâ â âûçûâàåìóþ ïðîöåäóðó.  Ada è Modula-2 ìû äîëæíû èñïîëüçîâàòü íåóäîáíûé (è ìåäëåííûé!) ñïîñîá îòäåëüíîãî âûçîâà äëÿ êàæäîãî àðãóìåíòà.       Òàê ÷òî ÿ äóìàþ, ÷òî ïðåäïî÷èòàþ Ïàñêàëåâñêèé ïîäõîä âñòðàèâàíèÿ ïîäïðîãðàìì ââîäà/âûâîäà, äàæå åñëè ìû íå íóæäàåìñÿ â ýòîì.       Êàê îáû÷íî, äëÿ ýòîãî íàì íóæíû åùå íåñêîëüêî ïîäïðîãðàìì ãåíåðàöèè êîäà. Îíè, îêàçûâàåòñÿ, ñàìûå ïðîñòûå èç âñåõ, ïîòîìó ÷òî âñå, ÷òî ìû äåëàåì ýòî âûçûâàåì áèáëèîòå÷íûå ïðîöåäóðû äëÿ âûïîëíåíèÿ ðàáîòû. 
      {–} 
      { Read Variable to Primary Register } 
      procedure ReadVar; 
      begin 
      EmitLn('BSR READ'); 
      Store(Value); 
      end; 
      {–} 
      { Write Variable from Primary Register } 
      procedure WriteVar; 
      begin 
      EmitLn('BSR WRITE'); 
      end; 
      {–} 
 
       Èäåÿ ñîñòîèò â òîì, ÷òî READ çàãðóæàåò çíà÷åíèå èç âõîäíîãî ïîòîêà â D0, à WRITE âûâîäèò åãî îòòóäà.       Ýòè äâå ïðîöåäóðû ïðåäñòàâëÿþò ñîáîé íàøó ïåðâóþ âñòðå÷ó ñ ïîòðåáíîñòüþ â áèáëèîòå÷íûõ ïðîöåäóðàõ... êîìïîíåíòàõ Run Time Library (RTL). Êîíå÷íî êòî-òî (à èìåííî ìû) äîëæåí íàïèñàòü ýòè ïîäïðîãðàììû, íî îíè íå ÿâëÿþòñÿ íåïîñðåäñòâåííî ÷àñòüþ êîìïèëÿòîðà. ß äàæå íå áóäó áåñïîêîèòüñÿ î òîì, ÷òîáû ïîêàçàòü çäåñü ýòè ïîäïðîãðàììû, òàê êàê îíè î÷åâèäíî î÷åíü ÎÑ-çàâèñèìû. ß ïðîñòî ñêàæó, ÷òî äëÿ SK*DOS îíè îñîáåííî ïðîñòû... ïî÷òè òðèâèàëüíû. Îäíà èç ïðè÷èí, ïî êîòîðûì ÿ íå áóäó ïîêàçûâàòü èõ çäåñü â òîì, ÷òî âû ìîæåòå äîáàâëÿòü íîâûå âèäû âîçìîæíîñòåé, íàïðèìåð ïðèãëàøåíèå â READ èëè âîçìîæíîñòü ïîëüçîâàòåëþ ïîâòîðèòü îøèáî÷íûé ââîä.       Íî ýòî äåéñòâèòåëüíî îòäåëüíûé îò êîìïèëÿòîðà ïðîåêò, òàê ÷òî òåïåðü ÿ áóäó ïîäðàçóìåâàòü ÷òî áèáëèîòåêà, íàçûâàåìàÿ TINYLIB.LIB, ñóùåñòâóåò.       Òàê êàê íàì òåïåðü íóæíî çàãðóæàòü åå, ìû äîëæíû äîáàâèòü åå çàãðóçêó â ïðîöåäóðó Header: 
      {–} 
      { Write Header Info } 
      procedure Header; 
      begin 
      WriteLn('WARMST', TAB, 'EQU $A01E'); 
      EmitLn('LIB TINYLIB'); 
      end; 
      {–} 
 
       Îíà âîçüìåò íà ñåáÿ ýòó ÷àñòü ðàáîòû. Òåïåðü íàì òàêæå íåîáõîäèìî ðàñïîçíàâàòü êîìàíäû ââîäà è âûâîäà. Ìû ìîæåì ñäåëàòü ýòî äîáàâèâ åùå äâà êëþ÷åâûõ ñëîâà â íàø ñïèñîê: 
      {–} 
      { Definition of Keywords and Token Types } 
      const NKW = 11; 
      NKW1 = 12; 
      const KWlist: array[1..NKW] of Symbol = 
      ('IF', 'ELSE', 'ENDIF', 'WHILE', 'ENDWHILE', 
      'READ', 'WRITE', 'VAR', 'BEGIN', 'END', 
      'PROGRAM'); 
      const KWcode: string[NKW1] = 'xileweRWvbep'; 
      {–} 
 
       (Îáðàòèòå âíèìàíèå, ÷òî çäåñü ÿ èñïîëüçóþ êîäà â âåðõíåì ðåãèñòðå ÷òîáû èçáåæàòü êîíôëèêòà ñ 'w' èç WHILE.) Çàòåì íàì íóæíû ïðîöåäóðû äëÿ îáðàáîòêè îïåðàòîðà ââîäà/âûâîäà è åãî ñïèñêà ïàðàìåòðîâ: 
      {–} 
      { Process a Read Statement } 
      procedure DoRead; 
      begin 
      Match('('); 
      GetName; 
      ReadVar; 
      while Look = ',' do begin 
      Match(','); 
      GetName; 
      ReadVar; 
      end; 
      Match(')'); 
      end; 
      {–} 
      { Process a Write Statement } 
      procedure DoWrite; 
      begin 
      Match('('); 
      Expression; 
      WriteVar; 
      while Look = ',' do begin 
      Match(','); 
      Expression; 
      WriteVar; 
      end; 
      Match(')'); 
      end; 
      {–} 
 
       Íàêîíåö, ìû äîëæíû ðàñøèðèòü ïðîöåäóðó Block äëÿ ïîääåðæêè íîâûõ òèïîâ îïåðàòîðîâ: 
      {–} 
      { Parse and Translate a Block of Statements } 
      procedure Block; 
      begin 
      Scan; 
      while not(Token in ['e', 'l']) do begin 
      case Token of 
      'i': DoIf; 
      'w': DoWhile; 
      'R': DoRead; 
      'W': DoWrite; 
      else Assignment; 
      end; 
      Scan; 
      end; 
      end; 
      {–} 
 
       Íà ýòîì âñå. Òåïåðü ó íàñ åñòü ÿçûê!  
Çàêëþ÷åíèå 
      Ê ýòîìó ìîìåíòó ìû ïîëíîñòüþ îïðåäåëèëè TINY. Îí íå ñëèøêîì çíà÷èòåëåí... â äåéñòâèòåëüíîñòè èãðóøå÷íûé êîìèïëÿòîð. TINY èìååò òîëüêî îäèí òèï äàííûõ è íå èìååò ïîäïðîãðàìì... íî ýòî çàêîí÷åííûé, ïðèãîäíûé äëÿ èñïîëüçîâàíèÿ ÿçûê. Ïîêà ÷òî âû íå èìååòå âîçìîæíîñòè íàïèñàòü íà íåì äðóãîé êîìïèëÿòîð èëè ñäåëàòü ÷òî-íèáóäü åùå î÷åíü ñåðüåçíîå, íî âû ìîãëè áû ïèñàòü ïðîãðàììû äëÿ ÷òåíèÿ âõîäíûõ äàííûõ, âûïîëíåíèÿ âû÷èñëåíèé è âûâîäà ðåçóëüòàòîâ. Íå ñëèøêîì ïëîõî äëÿ èãðóøêè.       Áîëåå âàæíî, ÷òî ìû èìååì òâåðäóþ îñíîâó äëÿ äàëüíåéøåãî ðàçâèòèÿ. ß çíàþ, ÷òî âû áóäåòå ðàäû ñëûøàòü ýòî: â ïîñëåäíèé ðàç ÿ íà÷àë ñ ñîçäàíèÿ ñèíòàêñè÷åñêîãî àíàëèçàòîðà çàíîâî... ñ ýòîãî ìîìåíòà ÿ ïðåäïîëàãàþ ïðîñòî äîáàâëÿòü âîçìîæíîñòè â TINY ïîêà îí íå ïðåâðàòèòñÿ â KISS. Îõ, áóäåò âðåìÿ, êîãäà íàì ïîíàäîáèòñÿ ïîïðîáîâàòü íåêîòîðûå âåùè ñ íîâûìè êîïèÿìè Cradle, íî êàê òîëüêî ìû ðàçóçíàåì êàê îíè äåëàþòñÿ, îíè áóäóò âñòðîåíû â TINY.       Êàêèå ýòî áóäóò âîçìîæíîñòè? Õîðîøî, äëÿ íà÷àëà íàì ïîíàäîáÿòñÿ ïîäïðîãðàììû è ôóíêöèè. Çàòåì íàì íóæíà âîçìîæíîñòü îáðàáàòûâàòü ðàçëè÷íûå òèïû, âêëþ÷àÿ ìàññèâû, ñòðîêè è äðóãèå ñòðóêòóðû. Çàòåì íàì íóæíî ðàáîòàòü ñ èäååé óêàçàòåëåé. Âñå ýòî áóäåò â ñëåäóþùèõ ãëàâàõ.       Óâèäèìñÿ.       Â ñïðàâî÷íûõ öåëÿõ ïîëíûé ëèñòèíã TINY âåðñèè 1.0 ïîêàçàí íèæå: 
      {–} 
      program Tiny10; 
      {–} 
      { Constant Declarations } 
      const TAB = ^I; 
      CR = ^M; 
      LF = ^J; 
      LCount: integer = 0; 
      NEntry: integer = 0; 
      {–} 
      { Type Declarations } 
      type Symbol = string[8]; 
      SymTab = array[1..1000] of Symbol; 
      TabPtr = ^SymTab; 
      {–} 
      { Variable Declarations } 
      var Look : char; { Lookahead Character } 
      Token: char; { Encoded Token } 
      Value: string[16]; { Unencoded Token } 
      const MaxEntry = 100; 
      var ST : array[1..MaxEntry] of Symbol; 
      SType: array[1..MaxEntry] of char; 
      {–} 
      { Definition of Keywords and Token Types } 
      const NKW = 11; 
      NKW1 = 12; 
      const KWlist: array[1..NKW] of Symbol = 
      ('IF', 'ELSE', 'ENDIF', 'WHILE', 'ENDWHILE', 
      'READ', 'WRITE', 'VAR', 'BEGIN', 'END', 
      'PROGRAM'); 
      const KWcode: string[NKW1] = 'xileweRWvbep'; 
      {–} 
      { Read New Character From Input Stream } 
      procedure GetChar; 
      begin 
      Read(Look); 
      end; 
      {–} 
      { Report an Error } 
      procedure Error(s: string); 
      begin 
      WriteLn; 
      WriteLn(^G, 'Error: ', s, '.'); 
      end; 
      {–} 
      { Report Error and Halt } 
      procedure Abort(s: string); 
      begin 
      Error(s); 
      Halt; 
      end; 
      {–} 
      { Report What Was Expected } 
      procedure Expected(s: string); 
      begin 
      Abort(s + ' Expected'); 
      end; 
      {–} 
      { Report an Undefined Identifier } 
      procedure Undefined(n: string); 
      begin 
      Abort('Undefined Identifier ' + n); 
      end; 
      {–} 
      { Recognize an Alpha Character } 
      function IsAlpha(c: char): boolean; 
      begin 
      IsAlpha := UpCase(c) in ['A'..'Z']; 
      end; 
      {–} 
      { Recognize a Decimal Digit } 
      function IsDigit(c: char): boolean; 
      begin 
      IsDigit := c in ['0'..'9']; 
      end; 
      {–} 
      { Recognize an AlphaNumeric Character } 
      function IsAlNum(c: char): boolean; 
      begin 
      IsAlNum := IsAlpha(c) or IsDigit(c); 
      end; 
      {–} 
      { Recognize an Addop } 
      function IsAddop(c: char): boolean; 
      begin 
      IsAddop := c in ['+', '-']; 
      end; 
      {–} 
      { Recognize a Mulop } 
      function IsMulop(c: char): boolean; 
      begin 
      IsMulop := c in ['*', '/']; 
      end; 
      {–} 
      { Recognize a Boolean Orop } 
      function IsOrop(c: char): boolean; 
      begin 
      IsOrop := c in ['|', '~']; 
      end; 
      {–} 
      { Recognize a Relop } 
      function IsRelop(c: char): boolean; 
      begin 
      IsRelop := c in ['=', '#', '<', '>']; 
      end; 
      {–} 
      { Recognize White Space } 
      function IsWhite(c: char): boolean; 
      begin 
      IsWhite := c in [' ', TAB]; 
      end; 
      {–} 
      { Skip Over Leading White Space } 
      procedure SkipWhite; 
      begin 
      while IsWhite(Look) do 
      GetChar; 
      end; 
      {–} 
      { Skip Over an End-of-Line } 
      procedure NewLine; 
      begin 
      while Look = CR do begin 
      GetChar; 
      if Look = LF then GetChar; 
      SkipWhite; 
      end; 
      end; 
      {–} 
      { Match a Specific Input Character } 
      procedure Match(x: char); 
      begin 
      NewLine; 
      if Look = x then GetChar 
      else Expected('''' + x + ''''); 
      SkipWhite; 
      end; 
      {–} 
      { Table Lookup } 
      function Lookup(T: TabPtr; s: string; n: integer): integer; 
      var i: integer; 
      found: Boolean; 
      begin 
      found := false; 
      i := n; 
      while (i > 0) and not found do 
      if s = T^[i] then 
      found := true 
      else 
      dec(i); 
      Lookup := i; 
      end; 
      {–} 
      { Locate a Symbol in Table } 
      { Returns the index of the entry. Zero if not present. } 
      function Locate(N: Symbol): integer; 
      begin 
      Locate := Lookup(@ST, n, MaxEntry); 
      end; 
      {–} 
      { Look for Symbol in Table } 
      function InTable(n: Symbol): Boolean; 
      begin 
      InTable := Lookup(@ST, n, MaxEntry) <> 0; 
      end; 
      {–} 
      { Add a New Entry to Symbol Table } 
      procedure AddEntry(N: Symbol; T: char); 
      begin 
      if InTable(N) then Abort('Duplicate Identifier ' + N); 
      if NEntry = MaxEntry then Abort('Symbol Table Full'); 
      Inc(NEntry); 
      ST[NEntry] := N; 
      SType[NEntry] := T; 
      end; 
      {–} 
      { Get an Identifier } 
      procedure GetName; 
      begin 
      NewLine; 
      if not IsAlpha(Look) then Expected('Name'); 
      Value := ''; 
      while IsAlNum(Look) do begin 
      Value := Value + UpCase(Look); 
      GetChar; 
      end; 
      SkipWhite; 
      end; 
      {–} 
      { Get a Number } 
      function GetNum: integer; 
      var Val: integer; 
      begin 
      NewLine; 
      if not IsDigit(Look) then Expected('Integer'); 
      Val := 0; 
      while IsDigit(Look) do begin 
      Val := 10 * Val + Ord(Look) – Ord('0'); 
      GetChar; 
      end; 
      GetNum := Val; 
      SkipWhite; 
      end; 
      {–} 
      { Get an Identifier and Scan it for Keywords } 
      procedure Scan; 
      begin 
      GetName; 
      Token := KWcode[Lookup(Addr(KWlist), Value, NKW) + 1]; 
      end; 
      {–} 
      { Match a Specific Input String } 
      procedure MatchString(x: string); 
      begin 
      if Value <> x then Expected('''' + x + ''''); 
      end; 
      {–} 
      { Output a String with Tab } 
      procedure Emit(s: string); 
      begin 
      Write(TAB, s); 
      end; 
      {–} 
      { Output a String with Tab and CRLF } 
      procedure EmitLn(s: string); 
      begin 
      Emit(s); 
      WriteLn; 
      end; 
      {–} 
      { Generate a Unique Label } 
      function NewLabel: string; 
      var S: string; 
      begin 
      Str(LCount, S); 
      NewLabel := 'L' + S; 
      Inc(LCount); 
      end; 
      {–} 
      { Post a Label To Output } 
      procedure PostLabel(L: string); 
      begin 
      WriteLn(L, ':'); 
      end; 
      {–} 
      { Clear the Primary Register } 
      procedure Clear; 
      begin 
      EmitLn('CLR D0'); 
      end; 
      {–} 
      { Negate the Primary Register } 
      procedure Negate; 
      begin 
      EmitLn('NEG D0'); 
      end; 
      {–} 
      { Complement the Primary Register } 
      procedure NotIt; 
      begin 
      EmitLn('NOT D0'); 
      end; 
      {–} 
      { Load a Constant Value to Primary Register } 
      procedure LoadConst(n: integer); 
      begin 
      Emit('MOVE #'); 
      WriteLn(n, ',D0'); 
      end; 
      {–} 
      { Load a Variable to Primary Register } 
      procedure LoadVar(Name: string); 
      begin 
      if not InTable(Name) then Undefined(Name); 
      EmitLn('MOVE ' + Name + '(PC),D0'); 
      end; 
      {–} 
      { Push Primary onto Stack } 
      procedure Push; 
      begin 
      EmitLn('MOVE D0,-(SP)'); 
      end; 
      {–} 
      { Add Top of Stack to Primary } 
      procedure PopAdd; 
      begin 
      EmitLn('ADD (SP)+,D0'); 
      end; 
      {–} 
      { Subtract Primary from Top of Stack } 
      procedure PopSub; 
      begin 
      EmitLn('SUB (SP)+,D0'); 
      EmitLn('NEG D0'); 
      end; 
      {–} 
      { Multiply Top of Stack by Primary } 
      procedure PopMul; 
      begin 
      EmitLn('MULS (SP)+,D0'); 
      end; 
      {–} 
      { Divide Top of Stack by Primary } 
      procedure PopDiv; 
      begin 
      EmitLn('MOVE (SP)+,D7'); 
      EmitLn('EXT.L D7'); 
      EmitLn('DIVS D0,D7'); 
      EmitLn('MOVE D7,D0'); 
      end; 
      {–} 
      { AND Top of Stack with Primary } 
      procedure PopAnd; 
      begin 
      EmitLn('AND (SP)+,D0'); 
      end; 
      {–} 
      { OR Top of Stack with Primary } 
      procedure PopOr; 
      begin 
      EmitLn('OR (SP)+,D0'); 
      end; 
      {–} 
      { XOR Top of Stack with Primary } 
      procedure PopXor; 
      begin 
      EmitLn('EOR (SP)+,D0'); 
      end; 
      {–} 
      { Compare Top of Stack with Primary } 
      procedure PopCompare; 
      begin 
      EmitLn('CMP (SP)+,D0'); 
      end; 
      {–} 
      { Set D0 If Compare was = } 
      procedure SetEqual; 
      begin 
      EmitLn('SEQ D0'); 
      EmitLn('EXT D0'); 
      end; 
      {–} 
      { Set D0 If Compare was != } 
      procedure SetNEqual; 
      begin 
      EmitLn('SNE D0'); 
      EmitLn('EXT D0'); 
      end; 
      {–} 
      { Set D0 If Compare was > } 
      procedure SetGreater; 
      begin 
      EmitLn('SLT D0'); 
      EmitLn('EXT D0'); 
      end; 
      {–} 
      { Set D0 If Compare was < } 
      procedure SetLess; 
      begin 
      EmitLn('SGT D0'); 
      EmitLn('EXT D0'); 
      end; 
      {–} 
      { Set D0 If Compare was <= } 
      procedure SetLessOrEqual; 
      begin 
      EmitLn('SGE D0'); 
      EmitLn('EXT D0'); 
      end; 
      {–} 
      { Set D0 If Compare was >= } 
      procedure SetGreaterOrEqual; 
      begin 
      EmitLn('SLE D0'); 
      EmitLn('EXT D0'); 
      end; 
      {–} 
      { Store Primary to Variable } 
      procedure Store(Name: string); 
      begin 
      if not InTable(Name) then Undefined(Name); 
      EmitLn('LEA ' + Name + '(PC),A0'); 
      EmitLn('MOVE D0,(A0)') 
      end; 
      {–} 
      { Branch Unconditional } 
      procedure Branch(L: string); 
      begin 
      EmitLn('BRA ' + L); 
      end; 
      {–} 
      { Branch False } 
      procedure BranchFalse(L: string); 
      begin 
      EmitLn('TST D0'); 
      EmitLn('BEQ ' + L); 
      end; 
      {–} 
      { Read Variable to Primary Register } 
      procedure ReadVar; 
      begin 
      EmitLn('BSR READ'); 
      Store(Value[1]); 
      end; 
      { Write Variable from Primary Register } 
      procedure WriteVar; 
      begin 
      EmitLn('BSR WRITE'); 
      end; 
      {–} 
      { Write Header Info } 
      procedure Header; 
      begin 
      WriteLn('WARMST', TAB, 'EQU $A01E'); 
      end; 
      {–} 
      { Write the Prolog } 
      procedure Prolog; 
      begin 
      PostLabel('MAIN'); 
      end; 
      {–} 
      { Write the Epilog } 
      procedure Epilog; 
      begin 
      EmitLn('DC WARMST'); 
      EmitLn('END MAIN'); 
      end; 
      {–} 
      { Parse and Translate a Math Factor } 
      procedure BoolExpression; Forward; 
      procedure Factor; 
      begin 
      if Look = '(' then begin 
      Match('('); 
      BoolExpression; 
      Match(')'); 
      end 
      else if IsAlpha(Look) then begin 
      GetName; 
      LoadVar(Value); 
      end 
      else 
      LoadConst(GetNum); 
      end; 
      {–} 
      { Parse and Translate a Negative Factor } 
      procedure NegFactor; 
      begin 
      Match('-'); 
      if IsDigit(Look) then 
      LoadConst(-GetNum) 
      else begin 
      Factor; 
      Negate; 
      end; 
      end; 
      {–} 
      { Parse and Translate a Leading Factor } 
      procedure FirstFactor; 
      begin 
      case Look of 
      '+': begin 
      Match('+'); 
      Factor; 
      end; 
      '-': NegFactor; 
      else Factor; 
      end; 
      end; 
      {–} 
      { Recognize and Translate a Multiply } 
      procedure Multiply; 
      begin 
      Match('*'); 
      Factor; 
      PopMul; 
      end; 
      {–} 
      { Recognize and Translate a Divide } 
      procedure Divide; 
      begin 
      Match('/'); 
      Factor; 
      PopDiv; 
      end; 
      {–} 
      { Common Code Used by Term and FirstTerm } 
      procedure Term1; 
      begin 
      while IsMulop(Look) do begin 
      Push; 
      case Look of 
      '*': Multiply; 
      '/': Divide; 
      end; 
      end; 
      end; 
      {–} 
      { Parse and Translate a Math Term } 
      procedure Term; 
      begin 
      Factor; 
      Term1; 
      end; 
      {–} 
      { Parse and Translate a Leading Term } 
      procedure FirstTerm; 
      begin 
      FirstFactor; 
      Term1; 
      end; 
      {–} 
      { Recognize and Translate an Add } 
      procedure Add; 
      begin 
      Match('+'); 
      Term; 
      PopAdd; 
      end; 
      {–} 
      { Recognize and Translate a Subtract } 
      procedure Subtract; 
      begin 
      Match('-'); 
      Term; 
      PopSub; 
      end; 
      {–} 
      { Parse and Translate an Expression } 
      procedure Expression; 
      begin 
      FirstTerm; 
      while IsAddop(Look) do begin 
      Push;
  
  		 
		 
		Ñòðàíèöû: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23
  | 
 
 
 |