You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

246 lines
6.8 KiB

#!/usr/bin/ruby
# encoding: utf-8
require 'antlr3'
require 'antlr3/test/functional'
ENV.delete( 'RUBYOPT' )
ENV[ 'RUBYLIB' ] = ANTLR3.library_path
class TestMainUtility < ANTLR3::Test::Functional
example 'overriding the built-in script action using the @main named-action' do
grammar = inline_grammar( <<-'END' )
lexer grammar MainOverride;
options { language = Ruby; }
@main {
raise( "the main block ran" )
}
ID: ('a'..'z' | '\u00c0'..'\u00ff')+;
WS: ' '+ { $channel = HIDDEN; };
END
# when this grammar is compiled and the resulting ruby files
# are loaded as a library, the custom @main block
# should not be executed
proc { compile_and_load( grammar ) }.should_not raise_error
# this assertion verifies that the main region is executed
# when the parser script is run directly
lexer_script = grammar.target_files.first
out = `ruby #{ lexer_script } 2>&1`.chomp
out.should =~ /the main block ran/
end
example 'using Lexer.main() to run the built-in lexer utility script on a source file' do
input_path = local_path( 'input.txt' )
open( input_path, 'w' ) { |f| f.write( "yada yada" ) }
compile_and_load inline_grammar( <<-'END' )
lexer grammar LexerMainWithSourceFile;
options { language = Ruby; }
ID: 'a'..'z'+;
WS: ' '+ { $channel = HIDDEN; };
END
begin
output = StringIO.new
input = File.open( input_path )
LexerMainWithSourceFile::Lexer.main( [], :input => input, :output => output )
out_lines = output.string.split( /\n/ )
out_lines.should have( 3 ).things
ensure
File.delete( input_path )
end
end
example 'using Lexer.main to run the built-in lexer utility script on input from $stdin' do
input = StringIO.new( "yada yada" ) # <- used to simulate $stdin
output = StringIO.new
compile_and_load inline_grammar( <<-'END' )
lexer grammar LexerMainFromStdIO;
options { language = Ruby; }
ID: 'a'..'z'+;
WS: ' '+ { $channel = HIDDEN; };
END
LexerMainFromStdIO::Lexer.main( [], :input => input, :output => output )
lines = output.string.split( /\n/ )
lines.should have( 3 ).things
end
example 'using Parser.main to run the built-in parser script utility with a combo grammar' do
compile_and_load inline_grammar( <<-'END' )
grammar MainForCombined;
options { language = Ruby; }
r returns [res]: (ID)+ EOF { $res = $text; };
ID: 'a'..'z'+;
WS: ' '+ { $channel = HIDDEN; };
END
output = StringIO.new
input = StringIO.new( 'yada yada' )
MainForCombined::Parser.main(
%w(--rule r --lexer-name MainForCombined::Lexer),
:input => input, :output => output )
lines = output.string.split( "\n" )
lines.should have( 4 ).things
end
example 'using built-in main to inspect AST constructed by an AST-building parser' do
compile_and_load inline_grammar( <<-'END' )
grammar ASTParserMain;
options {
language = Ruby;
output = AST;
}
r: ID OP^ ID EOF!;
ID: 'a'..'z'+;
OP: '+';
WS: ' '+ { $channel = HIDDEN; };
END
output = StringIO.new
input = StringIO.new 'yada + yada'
ASTParserMain::Parser.main(
%w(--rule r --lexer-name ASTParserMain::Lexer),
:input => input, :output => output )
output = output.string.strip
output.should == "(+ yada yada)"
end
example "using a tree parser's built-in main" do
compile_and_load inline_grammar( <<-'END' )
grammar TreeMain;
options {
language = Ruby;
output = AST;
}
r: ID OP^ ID EOF!;
ID: 'a'..'z'+;
OP: '+';
WS: ' '+ { $channel = HIDDEN; };
END
compile_and_load inline_grammar( <<-'END' )
tree grammar TreeMainWalker;
options {
language=Ruby;
ASTLabelType=CommonTree;
tokenVocab=TreeMain;
}
r returns [res]: ^(OP a=ID b=ID)
{ $res = "\%s \%s \%s" \% [$a.text, $OP.text, $b.text] }
;
END
output = StringIO.new
input = StringIO.new 'a+b'
TreeMainWalker::TreeParser.main(
%w(--rule r --parser-name TreeMain::Parser
--parser-rule r --lexer-name TreeMain::Lexer),
:input => input, :output => output )
output = output.string.strip
output.should == '"a + b"'
end
example "using a tree parser's built-in main to inspect AST rewrite output" do
compile_and_load inline_grammar( <<-'END' )
grammar TreeRewriteMain;
options {
language = Ruby;
output = AST;
}
r: ID OP^ ID EOF!;
ID: 'a'..'z'+;
OP: '+';
WS: ' '+ { $channel = HIDDEN; };
END
compile_and_load inline_grammar( <<-'END' )
tree grammar TreeRewriteMainWalker;
options {
language=Ruby;
ASTLabelType=CommonTree;
tokenVocab=TreeRewriteMain;
output=AST;
}
tokens { ARG; }
r: ^(OP a=ID b=ID) -> ^(OP ^(ARG ID) ^(ARG ID));
END
output = StringIO.new
input = StringIO.new 'a+b'
TreeRewriteMainWalker::TreeParser.main(
%w(--rule r --parser-name TreeRewriteMain::Parser
--parser-rule r --lexer-name TreeRewriteMain::Lexer),
:input => input, :output => output
)
output = output.string.strip
output.should == '(+ (ARG a) (ARG b))'
end
example 'using built-in main with a delegating grammar' do
inline_grammar( <<-'END' )
parser grammar MainSlave;
options { language=Ruby; }
a : B;
END
master = inline_grammar( <<-'END' )
grammar MainMaster;
options { language=Ruby; }
import MainSlave;
s returns [res]: a { $res = $a.text };
B : 'b' ; // defines B from inherited token space
WS : (' '|'\n') {skip} ;
END
master.compile
for file in master.target_files
require( file )
end
output = StringIO.new
input = StringIO.new 'b'
MainMaster::Parser.main(
%w(--rule s --lexer-name MainMaster::Lexer),
:input => input, :output => output )
output = output.string.strip
output.should == 'b'.inspect
end
#test :LexerEncoding do
# broken!("Non-ASCII encodings have not been implemented yet")
# grammar = inline_grammar(<<-'END')
# lexer grammar T3;
# options {
# language = Ruby;
# }
#
# ID: ('a'..'z' | '\u00c0'..'\u00ff')+;
# WS: ' '+ { $channel = HIDDEN; };
# END
# compile grammar
# input = StringIO.new("föö bär")
# output = StringIO.new('')
# lexer_class.main(%w(--encoding utf-8), :input => input, :output => output)
# puts output.string
# lines = output.string.split(/\n/)
# lines.should have(3).things
#end
end