Skip to content

Instantly share code, notes, and snippets.

@NilsHaldenwang
Created October 3, 2010 09:29
Show Gist options
  • Save NilsHaldenwang/608432 to your computer and use it in GitHub Desktop.
Save NilsHaldenwang/608432 to your computer and use it in GitHub Desktop.
grammar AddingMachine;
options {
language = Ruby;
}
expression returns[ value ]
: a=NUMBER '+' b=NUMBER { $value = $a.text.to_i + $b.text.to_i }
| a=NUMBER '-' b=NUMBER { $value = $a.text.to_i - $b.to_i }
;
NUMBER: ( '0' .. '9' )+;
SPACE: ' '+ { $channel = HIDDEN };
NUMBER=4
SPACE=5
T__7=7
T__6=6
'-'=7
'+'=6
#!/usr/bin/env ruby
#
# adding_machine.g
# --
# Generated using ANTLR version: 3.2.1-SNAPSHOT Jul 31, 2010 19:34:52
# Ruby runtime library version: 1.8.1
# Input grammar file: adding_machine.g
# Generated at: 2010-10-03 11:23:45
#
# ~~~> start load path setup
this_directory = File.expand_path( File.dirname( __FILE__ ) )
$LOAD_PATH.unshift( this_directory ) unless $LOAD_PATH.include?( this_directory )
antlr_load_failed = proc do
load_path = $LOAD_PATH.map { |dir| ' - ' << dir }.join( $/ )
raise LoadError, <<-END.strip!
Failed to load the ANTLR3 runtime library (version 1.8.1):
Ensure the library has been installed on your system and is available
on the load path. If rubygems is available on your system, this can
be done with the command:
gem install antlr3
Current load path:
#{ load_path }
END
end
defined?( ANTLR3 ) or begin
# 1: try to load the ruby antlr3 runtime library from the system path
require 'antlr3'
rescue LoadError
# 2: try to load rubygems if it isn't already loaded
defined?( Gem ) or begin
require 'rubygems'
rescue LoadError
antlr_load_failed.call
end
# 3: try to activate the antlr3 gem
begin
Gem.activate( 'antlr3', '~> 1.8.1' )
rescue Gem::LoadError
antlr_load_failed.call
end
require 'antlr3'
end
# <~~~ end load path setup
module AddingMachine
# TokenData defines all of the token type integer values
# as constants, which will be included in all
# ANTLR-generated recognizers.
const_defined?( :TokenData ) or TokenData = ANTLR3::TokenScheme.new
module TokenData
# define the token constants
define_tokens( :NUMBER => 4, :EOF => -1, :SPACE => 5, :T__7 => 7, :T__6 => 6 )
end
class Lexer < ANTLR3::Lexer
@grammar_home = AddingMachine
include TokenData
begin
generated_using( "adding_machine.g", "3.2.1-SNAPSHOT Jul 31, 2010 19:34:52", "1.8.1" )
rescue NoMethodError => error
# ignore
end
RULE_NAMES = [ "T__6", "T__7", "NUMBER", "SPACE" ].freeze
RULE_METHODS = [ :t__6!, :t__7!, :number!, :space! ].freeze
def initialize( input=nil, options = {} )
super( input, options )
end
# - - - - - - - - - - - lexer rules - - - - - - - - - - - -
# lexer rule t__6! (T__6)
# (in adding_machine.g)
def t__6!
# -> uncomment the next line to manually enable rule tracing
# trace_in( __method__, 1 )
type = T__6
channel = ANTLR3::DEFAULT_CHANNEL
# - - - - main rule block - - - -
# at line 7:8: '+'
match( 0x2b )
@state.type = type
@state.channel = channel
ensure
# -> uncomment the next line to manually enable rule tracing
# trace_out( __method__, 1 )
end
# lexer rule t__7! (T__7)
# (in adding_machine.g)
def t__7!
# -> uncomment the next line to manually enable rule tracing
# trace_in( __method__, 2 )
type = T__7
channel = ANTLR3::DEFAULT_CHANNEL
# - - - - main rule block - - - -
# at line 8:8: '-'
match( 0x2d )
@state.type = type
@state.channel = channel
ensure
# -> uncomment the next line to manually enable rule tracing
# trace_out( __method__, 2 )
end
# lexer rule number! (NUMBER)
# (in adding_machine.g)
def number!
# -> uncomment the next line to manually enable rule tracing
# trace_in( __method__, 3 )
type = NUMBER
channel = ANTLR3::DEFAULT_CHANNEL
# - - - - main rule block - - - -
# at line 12:9: ( '0' .. '9' )+
# at file 12:9: ( '0' .. '9' )+
match_count_1 = 0
while true
alt_1 = 2
look_1_0 = @input.peek( 1 )
if ( look_1_0.between?( 0x30, 0x39 ) )
alt_1 = 1
end
case alt_1
when 1
# at line 12:11: '0' .. '9'
match_range( 0x30, 0x39 )
else
match_count_1 > 0 and break
eee = EarlyExit(1)
raise eee
end
match_count_1 += 1
end
@state.type = type
@state.channel = channel
ensure
# -> uncomment the next line to manually enable rule tracing
# trace_out( __method__, 3 )
end
# lexer rule space! (SPACE)
# (in adding_machine.g)
def space!
# -> uncomment the next line to manually enable rule tracing
# trace_in( __method__, 4 )
type = SPACE
channel = ANTLR3::DEFAULT_CHANNEL
# - - - - main rule block - - - -
# at line 13:8: ( ' ' )+
# at file 13:8: ( ' ' )+
match_count_2 = 0
while true
alt_2 = 2
look_2_0 = @input.peek( 1 )
if ( look_2_0 == 0x20 )
alt_2 = 1
end
case alt_2
when 1
# at line 13:8: ' '
match( 0x20 )
else
match_count_2 > 0 and break
eee = EarlyExit(2)
raise eee
end
match_count_2 += 1
end
# --> action
channel = HIDDEN
# <-- action
@state.type = type
@state.channel = channel
ensure
# -> uncomment the next line to manually enable rule tracing
# trace_out( __method__, 4 )
end
# main rule used to study the input at the current position,
# and choose the proper lexer rule to call in order to
# fetch the next token
#
# usually, you don't make direct calls to this method,
# but instead use the next_token method, which will
# build and emit the actual next token
def token!
# at line 1:8: ( T__6 | T__7 | NUMBER | SPACE )
alt_3 = 4
case look_3 = @input.peek( 1 )
when 0x2b then alt_3 = 1
when 0x2d then alt_3 = 2
when 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39 then alt_3 = 3
when 0x20 then alt_3 = 4
else
raise NoViableAlternative( "", 3, 0 )
end
case alt_3
when 1
# at line 1:10: T__6
t__6!
when 2
# at line 1:15: T__7
t__7!
when 3
# at line 1:20: NUMBER
number!
when 4
# at line 1:27: SPACE
space!
end
end
end # class Lexer < ANTLR3::Lexer
at_exit { Lexer.main( ARGV ) } if __FILE__ == $0
end
#!/usr/bin/env ruby
#
# adding_machine.g
# --
# Generated using ANTLR version: 3.2.1-SNAPSHOT Jul 31, 2010 19:34:52
# Ruby runtime library version: 1.8.1
# Input grammar file: adding_machine.g
# Generated at: 2010-10-03 11:23:45
#
# ~~~> start load path setup
this_directory = File.expand_path( File.dirname( __FILE__ ) )
$LOAD_PATH.unshift( this_directory ) unless $LOAD_PATH.include?( this_directory )
antlr_load_failed = proc do
load_path = $LOAD_PATH.map { |dir| ' - ' << dir }.join( $/ )
raise LoadError, <<-END.strip!
Failed to load the ANTLR3 runtime library (version 1.8.1):
Ensure the library has been installed on your system and is available
on the load path. If rubygems is available on your system, this can
be done with the command:
gem install antlr3
Current load path:
#{ load_path }
END
end
defined?( ANTLR3 ) or begin
# 1: try to load the ruby antlr3 runtime library from the system path
require 'antlr3'
rescue LoadError
# 2: try to load rubygems if it isn't already loaded
defined?( Gem ) or begin
require 'rubygems'
rescue LoadError
antlr_load_failed.call
end
# 3: try to activate the antlr3 gem
begin
Gem.activate( 'antlr3', '~> 1.8.1' )
rescue Gem::LoadError
antlr_load_failed.call
end
require 'antlr3'
end
# <~~~ end load path setup
module AddingMachine
# TokenData defines all of the token type integer values
# as constants, which will be included in all
# ANTLR-generated recognizers.
const_defined?( :TokenData ) or TokenData = ANTLR3::TokenScheme.new
module TokenData
# define the token constants
define_tokens( :NUMBER => 4, :EOF => -1, :SPACE => 5, :T__7 => 7, :T__6 => 6 )
# register the proper human-readable name or literal value
# for each token type
#
# this is necessary because anonymous tokens, which are
# created from literal values in the grammar, do not
# have descriptive names
register_names( "NUMBER", "SPACE", "'+'", "'-'" )
end
class Parser < ANTLR3::Parser
@grammar_home = AddingMachine
RULE_METHODS = [ :expression ].freeze
include TokenData
begin
generated_using( "adding_machine.g", "3.2.1-SNAPSHOT Jul 31, 2010 19:34:52", "1.8.1" )
rescue NoMethodError => error
# ignore
end
def initialize( input, options = {} )
super( input, options )
end
# - - - - - - - - - - - - Rules - - - - - - - - - - - - -
#
# parser rule expression
#
# (in adding_machine.g)
# 7:1: expression returns [ value ] : (a= NUMBER '+' b= NUMBER | a= NUMBER '-' b= NUMBER );
#
def expression
# -> uncomment the next line to manually enable rule tracing
# trace_in( __method__, 1 )
value = nil
a = nil
b = nil
begin
# at line 8:3: (a= NUMBER '+' b= NUMBER | a= NUMBER '-' b= NUMBER )
alt_1 = 2
look_1_0 = @input.peek( 1 )
if ( look_1_0 == NUMBER )
look_1_1 = @input.peek( 2 )
if ( look_1_1 == T__6 )
alt_1 = 1
elsif ( look_1_1 == T__7 )
alt_1 = 2
else
raise NoViableAlternative( "", 1, 1 )
end
else
raise NoViableAlternative( "", 1, 0 )
end
case alt_1
when 1
# at line 8:5: a= NUMBER '+' b= NUMBER
a = match( NUMBER, TOKENS_FOLLOWING_NUMBER_IN_expression_31 )
match( T__6, TOKENS_FOLLOWING_T__6_IN_expression_33 )
b = match( NUMBER, TOKENS_FOLLOWING_NUMBER_IN_expression_37 )
# --> action
value = a.text.to_i + b.text.to_i
# <-- action
when 2
# at line 9:5: a= NUMBER '-' b= NUMBER
a = match( NUMBER, TOKENS_FOLLOWING_NUMBER_IN_expression_47 )
match( T__7, TOKENS_FOLLOWING_T__7_IN_expression_49 )
b = match( NUMBER, TOKENS_FOLLOWING_NUMBER_IN_expression_53 )
# --> action
value = a.text.to_i - b.to_i
# <-- action
end
rescue ANTLR3::Error::RecognitionError => re
report_error(re)
recover(re)
ensure
# -> uncomment the next line to manually enable rule tracing
# trace_out( __method__, 1 )
end
return value
end
TOKENS_FOLLOWING_NUMBER_IN_expression_31 = Set[ 6 ]
TOKENS_FOLLOWING_T__6_IN_expression_33 = Set[ 4 ]
TOKENS_FOLLOWING_NUMBER_IN_expression_37 = Set[ 1 ]
TOKENS_FOLLOWING_NUMBER_IN_expression_47 = Set[ 7 ]
TOKENS_FOLLOWING_T__7_IN_expression_49 = Set[ 4 ]
TOKENS_FOLLOWING_NUMBER_IN_expression_53 = Set[ 1 ]
end # class Parser < ANTLR3::Parser
at_exit { Parser.main( ARGV ) } if __FILE__ == $0
end
require "AddingMachineLexer"
require "AddingMachineParser"
lexer = AddingMachine::Lexer.new( "1 + 1" )
parser = AddingMachine::Parser.new( lexer )
puts parser.expression
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment