Created
October 3, 2010 09:29
-
-
Save NilsHaldenwang/608432 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
NUMBER=4 | |
SPACE=5 | |
T__7=7 | |
T__6=6 | |
'-'=7 | |
'+'=6 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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