11using System ;
22using System . Collections . Generic ;
3+ using System . IO ;
34using Xtaieer . Lex ;
45
56namespace Xtaieer . Grammar
@@ -20,6 +21,7 @@ private enum TokenType
2021 MINAL ,
2122 SINGLE_CHAR_MINAL
2223 }
24+
2325 private class Token
2426 {
2527 public static readonly Token EMPTY = new Token ( "" , TokenType . EMPTY ) ;
@@ -94,18 +96,61 @@ public void AddTerminal(string terminal)
9496 terminals . Add ( terminal , new Terminal ( terminal ) ) ;
9597 }
9698
99+ public void AddProduction ( string production )
100+ {
101+ lex . SetInput ( new StringReader ( production ) ) ;
102+ current = lex . NextToken ( ) ;
103+ Nonterminal nonterminal = Nonterminal ( ) ;
104+ Match ( TokenType . SYMBOL ) ;
105+ List < Minal [ ] > productions = RightT ( null ) ;
106+ foreach ( Minal [ ] pro in productions )
107+ {
108+ nonterminal . AddProduction ( pro ) ;
109+ }
110+ }
97111
112+ public Nonterminal [ ] GetResult ( )
113+ {
114+ List < Nonterminal > result = new List < Nonterminal > ( nonterminals . Count ) ;
115+ foreach ( Nonterminal nonterminal in nonterminals . Values )
116+ {
117+ result . Add ( nonterminal ) ;
118+ }
119+ return result . ToArray ( ) ;
120+ }
98121
99- private void RightT ( )
122+ private List < Minal [ ] > RightT ( List < Minal [ ] > productions )
100123 {
101- Right ( ) ;
124+ List < Minal [ ] > result = productions ;
125+ if ( result == null )
126+ {
127+ result = new List < Minal [ ] > ( ) ;
128+ }
129+ LinkedList < Minal > minalLinkedList = new LinkedList < Minal > ( ) ;
130+ minalLinkedList = Right ( minalLinkedList ) ;
131+ Minal [ ] minals = new Minal [ minalLinkedList . Count ] ;
132+ LinkedListNode < Minal > head = minalLinkedList . First ;
133+ int index = 0 ;
134+ while ( head != null )
135+ {
136+ minals [ index ] = head . Value ;
137+ index ++ ;
138+ head = head . Next ;
139+ }
140+ result . Add ( minals ) ;
141+ if ( current != null && current . Type == TokenType . SYMBOL && current . Name == ";" )
142+ {
143+ Match ( TokenType . SYMBOL ) ;
144+ return RightT ( result ) ;
145+ }
146+ return result ;
102147 }
103148
104149 private LinkedList < Minal > Right ( LinkedList < Minal > left )
105150 {
106151 Minal minal = Minal ( ) ;
107- left . AddBefore ( left . First , minal ) ;
108- if ( current . Type == TokenType . MINAL || current . Type == TokenType . SINGLE_CHAR_MINAL )
152+ left . AddFirst ( minal ) ;
153+ if ( current != null && ( current . Type == TokenType . MINAL || current . Type == TokenType . SINGLE_CHAR_MINAL ) )
109154 {
110155 return Right ( left ) ;
111156 }
@@ -114,41 +159,58 @@ private LinkedList<Minal> Right(LinkedList<Minal> left)
114159
115160 private Minal Minal ( )
116161 {
117- Token token = current ;
118- Match ( TokenType . MINAL ) ;
119- if ( terminals . ContainsKey ( token . Name ) )
162+ if ( terminals . ContainsKey ( current . Name ) || current . Type == TokenType . SINGLE_CHAR_MINAL )
120163 {
121- Minal minal = terminals [ token . Name ] ;
122- return minal ;
164+ return Terminal ( ) ;
123165 }
124166 else
125167 {
126- if ( nonterminals . ContainsKey ( token . Name ) )
127- {
128- return nonterminals [ token . Name ] ;
129- }
130- else
131- {
132- Nonterminal nonterminal = new Nonterminal ( token . Name ) ;
133- nonterminals . Add ( token . Name , nonterminal ) ;
134- return nonterminal ;
135- }
168+ return Nonterminal ( ) ;
136169 }
137170 }
138171
139- private void Terminal ( )
172+ private Terminal Terminal ( )
140173 {
141-
174+ Token token = current ;
175+ if ( current . Type == TokenType . SINGLE_CHAR_MINAL )
176+ {
177+ Match ( TokenType . SINGLE_CHAR_MINAL ) ;
178+ if ( ! terminals . ContainsKey ( token . Name ) )
179+ {
180+ Terminal minal = new Terminal ( token . Name ) ;
181+ terminals . Add ( token . Name , minal ) ;
182+ }
183+ }
184+ else
185+ {
186+ Match ( TokenType . MINAL ) ;
187+ }
188+ return terminals [ token . Name ] ;
142189 }
143190
144- private void Nonterminal ( )
191+ private Nonterminal Nonterminal ( )
145192 {
146-
193+ Token token = current ;
194+ Match ( TokenType . MINAL ) ;
195+ if ( nonterminals . ContainsKey ( token . Name ) )
196+ {
197+ return nonterminals [ token . Name ] ;
198+ }
199+ else
200+ {
201+ Nonterminal nonterminal = new Nonterminal ( token . Name ) ;
202+ nonterminals . Add ( token . Name , nonterminal ) ;
203+ return nonterminal ;
204+ }
147205 }
148206
149207 private void Match ( TokenType type )
150208 {
151209 current = lex . NextToken ( ) ;
210+ while ( current != null && current . Type == TokenType . EMPTY )
211+ {
212+ current = lex . NextToken ( ) ;
213+ }
152214 }
153215 }
154216}
0 commit comments