1324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#!/usr/bin/ruby
2324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# encoding: utf-8
3324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
4324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverrequire 'antlr3/test/functional'
5324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
6324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass TestParser001 < ANTLR3::Test::Functional
7324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  inline_grammar( <<-'END' )
8324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    grammar Identifiers;
9324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    options { language = Ruby; }
10324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
11324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @parser::init {
12324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      @identifiers = []
13324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      @reported_errors = []
14324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
15324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
16324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @parser::members {
17324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      attr_reader :reported_errors, :identifiers
18324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      
19324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      def found_identifier(name)
20324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          @identifiers << name
21324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      end
22324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      
23324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      def emit_error_message(msg)
24324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        @reported_errors << msg
25324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      end
26324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
27324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
28324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    document:
29324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            t=IDENTIFIER {found_identifier($t.text)}
30324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ;
31324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
32324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    IDENTIFIER: ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*;
33324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  END
34324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
35324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  example "parsing 'blah_de_blah'" do
36324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # to build a parser, this is the standard chain of calls to prepare the input
37324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    input = ANTLR3::StringStream.new( 'blah_de_blah', :file => 'blah.txt' )
38324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    lexer  = Identifiers::Lexer.new( input )
39324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    tokens = ANTLR3::CommonTokenStream.new( lexer )
40324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    parser = Identifiers::Parser.new( tokens )
41324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
42324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    parser.document
43324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
44324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    parser.reported_errors.should be_empty
45324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    parser.identifiers.should == %w(blah_de_blah)
46324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
47324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
48324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  example "error from empty input" do
49324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # if you don't need to use a customized stream, lexers and parsers will
50324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # automatically wrap input in the standard stream classes
51324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    lexer = Identifiers::Lexer.new( '' )
52324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    parser = Identifiers::Parser.new( lexer )
53324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    parser.document
54324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
55324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    parser.reported_errors.should have( 1 ).thing
56324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
57324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
58324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  example 'automatic input wrapping' do
59324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # if the parser is able to figure out what lexer class
60324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # to use (typically when it comes from a combined grammar),
61324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # and you don't need to do any special token processing
62324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # before making a parser, this is an extra shortcut for
63324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # parser construction
64324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    parser = Identifiers::Parser.new( 'blah_de_blah', :file => 'blah.txt' )
65324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
66324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    parser.document
67324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
68324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    parser.reported_errors.should be_empty
69324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    parser.identifiers.should == %w(blah_de_blah)
70324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
71324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend
72324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
73324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass TestParser002 < ANTLR3::Test::Functional
74324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  inline_grammar( <<-'END' )
75324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    grammar SimpleLanguage;
76324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    options {
77324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      language = Ruby;
78324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
79324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
80324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @parser::init {
81324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      @events = []
82324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      @reported_errors = []
83324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
84324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
85324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @parser::members {
86324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      attr_reader :reported_errors, :events
87324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      
88324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      def emit_error_message(msg)
89324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        @reported_errors << msg
90324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      end
91324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
92324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
93324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    document:
94324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ( declaration
95324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            | call
96324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            )*
97324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            EOF
98324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ;
99324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
100324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    declaration:
101324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            'var' t=IDENTIFIER ';'
102324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            {@events << ['decl', $t.text]}
103324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ;
104324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
105324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    call:
106324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            t=IDENTIFIER '(' ')' ';'
107324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            {@events << ['call', $t.text]}
108324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ;
109324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
110324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    IDENTIFIER: ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*;
111324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    WS:  (' '|'\r'|'\t'|'\n') {$channel=HIDDEN;};
112324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  END
113324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
114324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
115324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  example "parsing decls and calls" do
116324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    lexer  = SimpleLanguage::Lexer.new( "var foobar; gnarz(); var blupp; flupp ( ) ;" )
117324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    parser = SimpleLanguage::Parser.new( lexer )
118324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
119324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    parser.document
120324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
121324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    parser.reported_errors.should be_empty
122324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    parser.events.should == [ 
123324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      %w(decl foobar),
124324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      %w(call gnarz),
125324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      %w(decl blupp),
126324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      %w(call flupp)
127324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    ]
128324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
129324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
130324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  example "bad declaration" do
131324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    lexer  = SimpleLanguage::Lexer.new( 'var; foo()' )
132324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    parser = SimpleLanguage::Parser.new( lexer )
133324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
134324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    parser.document
135324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
136324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    parser.reported_errors.should have( 1 ).thing
137324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    parser.events.should be_empty
138324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
139324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
140324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  example "error recovery via token insertion" do
141324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    lexer  = SimpleLanguage::Lexer.new( 'gnarz(; flupp();' )
142324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    parser = SimpleLanguage::Parser.new( lexer )
143324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
144324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    parser.document
145324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
146324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    parser.reported_errors.should have( 1 ).thing
147324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    parser.events.should == [ 
148324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      %w(call gnarz),
149324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      %w(call flupp)
150324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    ]
151324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
152324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
153324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend
154324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
155324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass TestParser003 < ANTLR3::Test::Functional
156324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  inline_grammar( <<-'END' )
157324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    grammar MoreComplicated;
158324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
159324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    options { language = Ruby; }
160324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
161324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @init {
162324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      @reported_errors = []
163324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
164324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
165324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @members {
166324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      attr_reader :reported_errors
167324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      
168324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      def emit_error_message(msg)
169324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        @reported_errors << msg
170324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      end
171324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
172324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
173324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    program
174324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        :   declaration+
175324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ;
176324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
177324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    declaration
178324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        :   variable
179324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        |   functionHeader ';'
180324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        |   functionHeader block
181324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ;
182324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
183324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    variable
184324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        :   type declarator ';'
185324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ;
186324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
187324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    declarator
188324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        :   ID 
189324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ;
190324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
191324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    functionHeader
192324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        :   type ID '(' ( formalParameter ( ',' formalParameter )* )? ')'
193324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ;
194324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
195324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    formalParameter
196324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        :   type declarator        
197324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ;
198324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
199324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    type
200324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        :   'int'   
201324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        |   'char'  
202324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        |   'void'
203324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        |   ID        
204324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ;
205324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
206324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    block
207324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        :   '{'
208324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                variable*
209324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                stat*
210324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            '}'
211324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ;
212324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
213324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    stat: forStat
214324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        | expr ';'      
215324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        | block
216324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        | assignStat ';'
217324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        | ';'
218324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ;
219324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
220324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    forStat
221324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        :   'for' '(' assignStat ';' expr ';' assignStat ')' block        
222324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ;
223324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
224324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    assignStat
225324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        :   ID '=' expr        
226324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ;
227324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
228324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    expr:   condExpr
229324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ;
230324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
231324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    condExpr
232324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        :   aexpr ( ('==' | '<') aexpr )?
233324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ;
234324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
235324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    aexpr
236324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        :   atom ( '+' atom )*
237324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ;
238324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
239324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    atom
240324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        : ID      
241324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        | INT      
242324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        | '(' expr ')'
243324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ; 
244324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
245324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    ID  :   ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
246324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ;
247324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
248324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    INT :	('0'..'9')+
249324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ;
250324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
251324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    WS  :   (   ' '
252324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            |   '\t'
253324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            |   '\r'
254324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            |   '\n'
255324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            )+
256324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            {$channel=HIDDEN}
257324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ;    
258324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  END
259324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
260324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  example "parsing 'int foo;'" do
261324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    lexer = MoreComplicated::Lexer.new "int foo;"
262324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    parser = MoreComplicated::Parser.new lexer
263324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    parser.program
264324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    parser.reported_errors.should be_empty
265324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
266324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
267324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
268324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  example "catching badly formed input" do
269324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    lexer = MoreComplicated::Lexer.new "int foo() { 1+2 }"
270324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    parser = MoreComplicated::Parser.new lexer
271324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    parser.program
272324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    parser.reported_errors.should have( 1 ).thing
273324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
274324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
275324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  example "two instances of badly formed input" do
276324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    lexer = MoreComplicated::Lexer.new "int foo() { 1+; 1+2 }"
277324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    parser = MoreComplicated::Parser.new lexer
278324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    parser.program
279324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    parser.reported_errors.should have( 2 ).things
280324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
281324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
282324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend
283