oryx 0.1.1 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -2,3 +2,6 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in oryx.gemspec
4
4
  gemspec
5
+
6
+ gem 'rltk', git: 'git://github.com/chriswailes/RLTK.git'
7
+
data/README.md CHANGED
@@ -12,17 +12,11 @@ C-Flat is a working subset of C designed for use in compilers courses. C-flat in
12
12
 
13
13
  ## Installation
14
14
 
15
- Add this line to your application's Gemfile:
16
-
17
- gem 'oryx'
18
-
19
- And then execute:
20
-
21
- $ bundle
15
+ $ gem install oryx
22
16
 
23
- Or install it yourself as:
17
+ ## Requirements
24
18
 
25
- $ gem install oryx
19
+ - Ruby >= 1.9.3
26
20
 
27
21
  ## Usage
28
22
 
@@ -35,6 +29,7 @@ For more details try
35
29
  ## See Also
36
30
  `bin/oryx.markdown`
37
31
 
32
+
38
33
  ## Contributing
39
34
  As this is a course project pull requests will be ignored.
40
35
 
data/Rakefile CHANGED
@@ -1,6 +1,5 @@
1
1
  require "bundler/gem_tasks"
2
2
  require 'rake/testtask'
3
- require 'binman/rakefile'
4
3
 
5
4
  Rake::TestTask.new do |t|
6
5
  t.libs << 'lib/oryx'
data/lib/oryx/ast.rb ADDED
@@ -0,0 +1,74 @@
1
+ require 'rltk/ast'
2
+
3
+ module Oryx
4
+ class Expression < RLTK::ASTNode; end
5
+
6
+ class Number < Expression
7
+ value :value, Integer
8
+ end
9
+
10
+ class Variable < Expression
11
+ value :name, String
12
+ end
13
+
14
+ class Binary < Expression
15
+ child :left, Expression
16
+ child :right, Expression
17
+ end
18
+
19
+ class Assign < Expression
20
+ value :name, String
21
+ child :right, Expression
22
+ end
23
+
24
+ class Add < Binary; end
25
+ class Sub < Binary; end
26
+ class Mul < Binary; end
27
+ class Div < Binary; end
28
+
29
+ class GE < Binary; end
30
+ class GEQ < Binary; end
31
+ class LE < Binary; end
32
+ class LEQ < Binary; end
33
+ class EQ < Binary; end
34
+ class NEQ < Binary; end
35
+
36
+ class Return < Expression
37
+ child :right, Expression
38
+ end
39
+
40
+ class If < Expression
41
+ child :cond, Expression
42
+ child :then, Expression
43
+ child :else, Expression
44
+ end
45
+
46
+ class CodeBlock < Expression
47
+ child :statements, [Expression]
48
+ end
49
+
50
+ class ParamList < RLTK::ASTNode
51
+ child :params, [Expression]
52
+ end
53
+
54
+ class Function < RLTK::ASTNode
55
+ value :i, String
56
+ child :params, ParamList
57
+ child :body, CodeBlock
58
+ end
59
+
60
+ class While < Expression
61
+ child :condition, Expression
62
+ child :body, CodeBlock
63
+ end
64
+
65
+ class Type < Expression
66
+ value :t, String
67
+ end
68
+
69
+ class Boolean < Type; end
70
+ class Char < Type; end
71
+ class Int < Type; end
72
+ class Str < Type; end
73
+
74
+ end
@@ -0,0 +1,116 @@
1
+ require 'rltk'
2
+ require_relative "../oryx"
3
+
4
+ module Oryx
5
+ class Parser < RLTK::Parser
6
+
7
+ left :ASSIGN, :RETURN
8
+ left :EQ, :NEQ
9
+ left :GE, :GEQ, :LE, :LEQ
10
+ left :PLUS, :MINUS
11
+ left :TIMES, :DIV
12
+
13
+ production(:input) do
14
+ clause('') { || [] }
15
+ clause('ext_dec_list') { |edl| edl }
16
+ end
17
+
18
+ production(:external_declaration) do
19
+ clause('vdecl') { |v| v }
20
+ clause('vinit') { |v| v }
21
+ clause('fdecl') { |f| f }
22
+ end
23
+
24
+ production(:ext_dec_list) do
25
+ clause('ext_dec_list external_declaration') { |edl, ed| edl + Array(ed)}
26
+ clause('external_declaration') { |ed| [ed] }
27
+ end
28
+
29
+ production(:vdecl) do
30
+ clause('type_spec IDENT SEMI') { |t, i, _| Variable.new i}
31
+ end
32
+
33
+ production(:vinit) do
34
+ clause('type_spec IDENT ASSIGN constant SEMI') { |t, i, _, c, _| Assign.new i, c}
35
+ end
36
+
37
+ production(:fdecl) do
38
+ clause('type_spec IDENT LPAREN opt_param_list RPAREN code_block') { |t, i, _, opl, _, c| Function.new i, opl, c }
39
+ end
40
+
41
+ production(:opt_param_list) do
42
+ clause('') { || ParamList.new [] }
43
+ clause('param_list') { |pl| ParamList.new pl}
44
+ end
45
+
46
+ production(:param_list) do
47
+ clause('param') { |p| [p] }
48
+ clause('param COMMA param_list') { |p, _, pl| Array(p) + pl }
49
+ end
50
+
51
+ production(:param) do
52
+ clause('type_spec IDENT') { |t, i| Variable.new i }
53
+ end
54
+
55
+ production(:constant) do
56
+ clause('NUM') { |n| Number.new n.to_i }
57
+ clause('STRCON') { |s| Cstring.new s}
58
+ clause('CHARCON') { |c| Char.new c }
59
+ end
60
+
61
+ production(:type_spec) do
62
+ clause('BOOLEAN') { |_| Boolean.new 'bool'}
63
+ clause('CHAR') { |_| Char.new 'char'}
64
+ clause('INT') { |_| Int.new 'int'}
65
+ clause('STRING') { |_| Str.new 'str'}
66
+ clause('VOID') { |_| }
67
+ end
68
+
69
+ production(:code_block) do
70
+ clause('LCURLY statement_list RCURLY') { |_, sl, _| CodeBlock.new(sl) }
71
+ end
72
+
73
+ production(:statement_list) do
74
+ clause('') { || [] }
75
+ clause('statement_list statement') { |sl, s| sl + Array(s) }
76
+ clause('statement') { |s| [s] }
77
+ end
78
+
79
+ production(:statement) do
80
+ clause('e SEMI') { |e, _| e }
81
+ clause('if_statement') { |i| i}
82
+ clause('WHILE LPAREN e RPAREN code_block') {|_,_,e,_,c| While.new(e,c) }
83
+ end
84
+
85
+ production(:if_statement) do
86
+ clause('IF LPAREN e RPAREN statement') { |_, _, e, _, s| If.new(e, s, nil) }
87
+ clause('IF LPAREN e RPAREN statement ELSE statement') { |_,_,e,_,ts,_,fs| If.new(e, ts, fs) }
88
+ clause('IF LPAREN e RPAREN code_block ELSE code_block') {|_,_,e,_,tc,_,fc| If.new(e, tc, fc) }
89
+ end
90
+
91
+ production(:e) do
92
+ clause('LPAREN e RPAREN') { |_, e, _| e }
93
+
94
+ clause('IDENT') { |i| Variable.new i }
95
+ clause('constant') { |c| c }
96
+ clause('IDENT ASSIGN e') { |e0, _, e1| Assign.new e0, e1 }
97
+
98
+ clause('e PLUS e') { |e0, _, e1| Add.new(e0, e1) }
99
+ clause('e MINUS e') { |e0, _, e1| Sub.new(e0, e1) }
100
+ clause('e TIMES e') { |e0, _, e1| Mul.new(e0, e1) }
101
+ clause('e DIV e') { |e0, _, e1| Div.new(e0, e1) }
102
+ clause('e GE e') { |e0, _, e1| GE.new(e0, e1) }
103
+ clause('e GEQ e') { |e0, _, e1| GEQ.new(e0, e1) }
104
+ clause('e LE e') { |e0, _, e1| LE.new(e0, e1) }
105
+ clause('e LEQ e') { |e0, _, e1| LEQ.new(e0, e1) }
106
+ clause('e EQ e') { |e0, _, e1| EQ.new(e0, e1) }
107
+ clause('e NEQ e') { |e0, _, e1| NEQ.new(e0, e1) }
108
+
109
+
110
+ clause('RETURN e') { |_, e| Return.new e }
111
+
112
+ end
113
+
114
+ finalize explain: 'explain.out'
115
+ end
116
+ end
data/lib/oryx/runner.rb CHANGED
@@ -18,6 +18,9 @@ module Oryx
18
18
  l = Lexer.new
19
19
  output_filename.open('w:UTF-8') { |f| f.write(tabularize_output l.lex_file(input_filename.to_s)) }
20
20
  puts "complete".green
21
+
22
+ p = Parser.new
23
+ p.parse(l.lex_file(input_filename.to_s), parse_tree: 'tree.dot', verbose: 'parse.out')
21
24
  end
22
25
 
23
26
  private
data/lib/oryx/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Oryx
2
- VERSION = "0.1.1"
2
+ VERSION = "0.2.1"
3
3
  end
data/lib/oryx.rb CHANGED
@@ -1,8 +1,9 @@
1
1
  require "oryx/version"
2
- require "oryx/preprocessor"
3
2
  require "oryx/options"
4
3
  require "oryx/runner"
5
4
  require "oryx/lexer"
5
+ require "oryx/parser"
6
+ require "oryx/ast"
6
7
 
7
8
  module Oryx
8
9
  # Your code goes here...
data/oryx.gemspec CHANGED
@@ -6,7 +6,6 @@ require 'oryx/version'
6
6
  Gem::Specification.new do |gem|
7
7
  gem.name = "oryx"
8
8
  gem.version = Oryx::VERSION
9
- gem.date = Date.today.to_s
10
9
  gem.authors = ["Casey Robinson"]
11
10
  gem.email = ["kc@rampantmonkey.com"]
12
11
  gem.description = %q{C-Flat to x86 compiler}
@@ -14,15 +13,12 @@ Gem::Specification.new do |gem|
14
13
  gem.homepage = "http://github.com/rampantmonkey/oryx"
15
14
 
16
15
  gem.files = `git ls-files`.split($/)
17
- gem.files += Dir['man/man?/*.?']
18
16
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) unless !f and f["markdown"]}
19
17
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
20
18
  gem.require_paths = ["lib"]
21
19
 
22
20
  gem.add_development_dependency 'rake', '~>0.9.2.2'
23
21
  gem.add_development_dependency 'shoulda', '~>3.3.2'
24
- gem.add_development_dependency 'md2man', '~>1.4'
25
- gem.add_development_dependency 'binman', '~>3.2.0'
26
22
 
27
23
  gem.add_dependency 'rltk', '~>2.2.1'
28
24
  gem.add_dependency 'colorize', '~>0.5.8'
@@ -0,0 +1,8 @@
1
+ require_relative '../../test_helper'
2
+ require 'rltk'
3
+
4
+ module Oryx
5
+ class TestParser < Test::Unit::TestCase
6
+
7
+ end
8
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oryx
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-02-20 00:00:00.000000000 Z
12
+ date: 2013-04-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
@@ -43,38 +43,6 @@ dependencies:
43
43
  - - ~>
44
44
  - !ruby/object:Gem::Version
45
45
  version: 3.3.2
46
- - !ruby/object:Gem::Dependency
47
- name: md2man
48
- requirement: !ruby/object:Gem::Requirement
49
- none: false
50
- requirements:
51
- - - ~>
52
- - !ruby/object:Gem::Version
53
- version: '1.4'
54
- type: :development
55
- prerelease: false
56
- version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
- requirements:
59
- - - ~>
60
- - !ruby/object:Gem::Version
61
- version: '1.4'
62
- - !ruby/object:Gem::Dependency
63
- name: binman
64
- requirement: !ruby/object:Gem::Requirement
65
- none: false
66
- requirements:
67
- - - ~>
68
- - !ruby/object:Gem::Version
69
- version: 3.2.0
70
- type: :development
71
- prerelease: false
72
- version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
- requirements:
75
- - - ~>
76
- - !ruby/object:Gem::Version
77
- version: 3.2.0
78
46
  - !ruby/object:Gem::Dependency
79
47
  name: rltk
80
48
  requirement: !ruby/object:Gem::Requirement
@@ -112,7 +80,6 @@ email:
112
80
  - kc@rampantmonkey.com
113
81
  executables:
114
82
  - oryx
115
- - oryx.markdown
116
83
  extensions: []
117
84
  extra_rdoc_files: []
118
85
  files:
@@ -123,19 +90,18 @@ files:
123
90
  - README.md
124
91
  - Rakefile
125
92
  - bin/oryx
126
- - bin/oryx.markdown
127
93
  - lib/oryx.rb
94
+ - lib/oryx/ast.rb
128
95
  - lib/oryx/lexer.rb
129
96
  - lib/oryx/options.rb
130
- - lib/oryx/preprocessor.rb
97
+ - lib/oryx/parser.rb
131
98
  - lib/oryx/runner.rb
132
99
  - lib/oryx/version.rb
133
100
  - oryx.gemspec
134
101
  - test/lib/oryx/lexer_test.rb
135
- - test/lib/oryx/preprocessor_test.rb
102
+ - test/lib/oryx/parser_test.rb
136
103
  - test/lib/oryx/version_test.rb
137
104
  - test/test_helper.rb
138
- - man/man1/oryx.1
139
105
  homepage: http://github.com/rampantmonkey/oryx
140
106
  licenses: []
141
107
  post_install_message:
@@ -150,7 +116,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
150
116
  version: '0'
151
117
  segments:
152
118
  - 0
153
- hash: 2601944800396312341
119
+ hash: 730399691837607602
154
120
  required_rubygems_version: !ruby/object:Gem::Requirement
155
121
  none: false
156
122
  requirements:
@@ -159,7 +125,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
159
125
  version: '0'
160
126
  segments:
161
127
  - 0
162
- hash: 2601944800396312341
128
+ hash: 730399691837607602
163
129
  requirements: []
164
130
  rubyforge_project:
165
131
  rubygems_version: 1.8.23
@@ -168,6 +134,6 @@ specification_version: 3
168
134
  summary: Take a program written in C-Flat and convert it to x86 assembly
169
135
  test_files:
170
136
  - test/lib/oryx/lexer_test.rb
171
- - test/lib/oryx/preprocessor_test.rb
137
+ - test/lib/oryx/parser_test.rb
172
138
  - test/lib/oryx/version_test.rb
173
139
  - test/test_helper.rb
data/bin/oryx.markdown DELETED
@@ -1,29 +0,0 @@
1
- =begin===
2
- # ORYX 2013-2-20 0.1.0
3
-
4
- ## NAME
5
-
6
- oryx - cflat tokenizer
7
-
8
- ## SYNOPSIS
9
-
10
- `oryx` [-o output-file] input-file
11
-
12
- ## DESCRIPTION
13
-
14
- [oryx] produces a table of tokens representing the source code contained in `input-file`. If invalid characters/strings are found they are returned as error tokens and lexing continues. Oryx can even handle (in other words not throw an exception) when given random input, as shown by the test suite.
15
-
16
- ## OPTIONS
17
-
18
- `-h`, `--help`
19
- Show list of options and usage
20
-
21
- `-o`, `--output` [*FILE*]
22
- Specify the filename in which to write the token table
23
-
24
-
25
- ## SEE ALSO
26
-
27
- clang(1), gcc(1)
28
-
29
- =end===
@@ -1,21 +0,0 @@
1
- module Oryx
2
- class Preprocessor
3
- def initialize
4
- end
5
-
6
- def parse content
7
- content = remove_comment content
8
- remove_outer_whitespace content
9
- end
10
-
11
- def remove_comment content
12
- content.gsub /\/\*.*?\*\//, ''
13
- end
14
-
15
- def remove_outer_whitespace content
16
- content.lstrip.rstrip
17
- end
18
-
19
-
20
- end
21
- end
data/man/man1/oryx.1 DELETED
@@ -1,21 +0,0 @@
1
- .TH ORYX 2013\-2\-20 0.1.0
2
- .SH NAME
3
- .PP
4
- oryx \- cflat tokenizer
5
- .SH SYNOPSIS
6
- .PP
7
- \fB\fCoryx\fR [\-o output\-file] input\-file
8
- .SH DESCRIPTION
9
- .PP
10
- [oryx] produces a table of tokens representing the source code contained in \fB\fCinput-file\fR. If invalid characters/strings are found they are returned as error tokens and lexing continues. Oryx can even handle (in other words not throw an exception) when given random input, as shown by the test suite.
11
- .SH OPTIONS
12
- .PP
13
- \fB\fC-h\fR, \fB\fC--help\fR
14
- Show list of options and usage
15
- .PP
16
- \fB\fC-o\fR, \fB\fC--output\fR [\fIFILE\fP]
17
- Specify the filename in which to write the token table
18
- .SH SEE ALSO
19
- .PP
20
- .BR clang (1),
21
- .BR gcc (1)
@@ -1,65 +0,0 @@
1
- require_relative '../../test_helper'
2
-
3
- module Oryx
4
- class TestPreprocessor < Test::Unit::TestCase
5
- context "one line inputs" do
6
- setup do
7
- @preprocessor = Preprocessor.new
8
- end
9
-
10
- should "not modify empty input" do
11
- test_input = ""
12
- assert_equal test_input, @preprocessor.parse(test_input)
13
- end
14
-
15
- should "not modify simple assignment" do
16
- test_input = "int length=7;"
17
- assert_equal test_input, @preprocessor.parse(test_input)
18
- end
19
-
20
- should "remove block comment" do
21
- test_input = "/* this is a block comment in c */"
22
- assert_equal "", @preprocessor.parse(test_input)
23
- end
24
-
25
- should "remove trailing comment" do
26
- test_input = "int a = 5; /* a */"
27
- assert_equal "int a = 5;", @preprocessor.parse(test_input)
28
- end
29
-
30
- should "remove starting comment" do
31
- test_input = "/* a */ int a = 5;"
32
- assert_equal "int a = 5;", @preprocessor.parse(test_input)
33
- end
34
-
35
- should "remove both comments" do
36
- test_input = "/* a */ int a = 5; /* b */"
37
- assert_equal "int a = 5;", @preprocessor.parse(test_input)
38
- end
39
-
40
- should "remove tons of comments" do
41
- test_input = "/* a */"*700 + " int a = 5; " + "/* b */"*107
42
- assert_equal "int a = 5;", @preprocessor.parse(test_input)
43
- end
44
- end
45
-
46
- context "multi line test" do
47
- setup do
48
- @preprocessor = Preprocessor.new
49
- end
50
-
51
- should "remove extra newline" do
52
- test_input = "\n"
53
- assert_equal "", @preprocessor.parse(test_input)
54
- end
55
-
56
- should "do nothing" do
57
- test_input = "int a=5;\na++"
58
- assert_equal test_input, @preprocessor.parse(test_input)
59
- end
60
- end
61
-
62
-
63
- end
64
- end
65
-