skeem 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b820c8eb3683e1da04e9c28e41a4de2517894573
4
- data.tar.gz: 31dfc0fa971d27e165a73653abb824fdc39d00b6
3
+ metadata.gz: e25bd8499926a963c98886effec8d51eb78bb441
4
+ data.tar.gz: fd5e2e65ceffbe1ce202ab1d620645d74a2e03f7
5
5
  SHA512:
6
- metadata.gz: 333f74805437ad0199755a3bdb6bb8ffe8197c5d988979cf0bf8ec95dfd751fcdc423dcaa38c26adb892b982f62505a8bcb25ce62a0dade1c026ab05de0b3a5d
7
- data.tar.gz: cd5852bda6bb381855a2ef9a64e3d6875da172ede1c6f520d5b97c697e5a484096cc93cd9874a95311b866ff4b248841ed6d1fd0d802e30dc0e3be60e38d5d08
6
+ metadata.gz: 181ac16e0465292fc39a1ac157e313348afcb36d83243922b7539969a3e506dbbc0e2f97d78cf41f7bcb4a728dd43d1f78477ec8ca3a468841298f61ca51c2ca
7
+ data.tar.gz: 8c6a36fd38ebcc92a4f208bba5be6ac9f11423a1cfb405970f40bbf141f4c70dc1fa74279365d9d6277ef68b15bf6ff40bd2903eab6c865a246b25ab1e121dbc
data/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ ## [0.0.5] - 2018-08-30
2
+ Parser now generates correct parse trees for expressions consisting of a single literal.
3
+
4
+ ### Fixed
5
+ - Class`Tokenizer` The regexp for real numbers was too restricitive: it didn't recognize real numbers without fractional part.
6
+
7
+
1
8
  ## [0.0.4] - 2018-08-29
2
9
  ### Added
3
10
  - File `s_expr_nodes.rb` with initial implementation of `SExprTerminalNode` classes.
data/lib/skeem/grammar.rb CHANGED
@@ -24,7 +24,9 @@ module Skeem
24
24
  rule 'program' => 'cmd_or_def_plus'
25
25
  rule 'cmd_or_def_plus' => 'cmd_or_def_plus cmd_or_def'
26
26
  rule 'cmd_or_def_plus' => 'cmd_or_def'
27
+ rule 'cmd_or_def' => 'command'
27
28
  rule 'cmd_or_def' => 'definition'
29
+ rule 'command' => 'expression'
28
30
  rule 'definition' => 'LPAREN DEFINE IDENTIFIER expression RPAREN'
29
31
  rule 'expression' => 'IDENTIFIER'
30
32
  rule 'expression' => 'literal'
data/lib/skeem/parser.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require_relative 'tokenizer'
2
2
  require_relative 'grammar'
3
+ require_relative 's_expr_builder'
3
4
 
4
5
  module Skeem
5
6
  class Parser
@@ -7,7 +8,10 @@ module Skeem
7
8
 
8
9
  def initialize()
9
10
  # Create a Rley facade object
10
- @engine = Rley::Engine.new { |cfg| cfg.diagnose = true }
11
+ @engine = Rley::Engine.new do |cfg|
12
+ cfg.diagnose = true
13
+ cfg.repr_builder = SExprBuilder
14
+ end
11
15
 
12
16
  # Step 1. Load Skeem grammar
13
17
  @engine.use_grammar(Skeem::Grammar)
@@ -30,7 +34,7 @@ module Skeem
30
34
  raise StandardError, line1 + line2
31
35
  end
32
36
 
33
- return result
37
+ return engine.to_ptree(result)
34
38
  end
35
39
  end # class
36
40
  end # module
@@ -1,7 +1,7 @@
1
1
  require 'stringio'
2
- require_relative 'regex_repr'
2
+ require_relative 's_expr_nodes'
3
3
 
4
- module SrlRuby
4
+ module Skeem
5
5
  # The purpose of a ASTBuilder is to build piece by piece an AST
6
6
  # (Abstract Syntax Tree) from a sequence of input tokens and
7
7
  # visit events produced by walking over a GFGParsing object.
@@ -9,8 +9,14 @@ module SrlRuby
9
9
  # The Builder pattern creates a complex object
10
10
  # (say, a parse tree) from simpler objects (terminal and non-terminal
11
11
  # nodes) and using a step by step approach.
12
- class ASTBuilder < Rley::ParseRep::ASTBaseBuilder
13
- Terminal2NodeClass = {}.freeze
12
+ class SExprBuilder < Rley::ParseRep::ASTBaseBuilder
13
+ Terminal2NodeClass = {
14
+ 'BOOLEAN' => SExprBooleanNode,
15
+ 'IDENTIFIER' => SExprIdentifierNode,
16
+ 'INTEGER' => SExprIntegerNode,
17
+ 'REAL' => SExprRealNode,
18
+ 'STRING_LIT' => SExprStringNode
19
+ }.freeze
14
20
 
15
21
  # Create a new AST builder instance.
16
22
  # @param theTokens [Array<Token>] The sequence of input tokens.
@@ -28,20 +34,6 @@ module SrlRuby
28
34
  def terminal2node
29
35
  Terminal2NodeClass
30
36
  end
31
-
32
-
33
- # Overriding method.
34
- # Factory method for creating a node object for the given
35
- # input token.
36
- # @param _production [Rley::Syntax::Production]
37
- # @param _terminal [Rley::Syntax::Terminal] Terminal symbol associated with the token
38
- # @param aTokenPosition [Integer] Position of token in the input stream
39
- # @param aToken [Rley::Lexical::Token] The input token
40
- def new_leaf_node(_production, _terminal, aTokenPosition, aToken)
41
- node = Rley::PTree::TerminalNode.new(aToken, aTokenPosition)
42
-
43
- return node
44
- end
45
37
  end # class
46
38
  end # module
47
39
  # End of file
@@ -13,7 +13,7 @@ module Skeem
13
13
 
14
14
  # This method can be overriden
15
15
  def init_value(aValue)
16
- self.value = aValue.dup
16
+ self.value = aValue
17
17
  end
18
18
 
19
19
  def symbol()
@@ -39,6 +39,7 @@ module Skeem
39
39
  end # class
40
40
 
41
41
  class SExprNumberNode < SExprTerminalNode
42
+ end # class
42
43
 
43
44
  class SExprRealNode < SExprNumberNode
44
45
  end # class
@@ -47,6 +48,17 @@ module Skeem
47
48
  end # class
48
49
 
49
50
  class SExprStringNode < SExprTerminalNode
51
+ # Override
52
+ def init_value(aValue)
53
+ self.value = aValue.dup
54
+ end
55
+ end # class
56
+
57
+ class SExprIdentifierNode < SExprTerminalNode
58
+ # Override
59
+ def init_value(aValue)
60
+ self.value = aValue.dup
61
+ end
50
62
  end # class
51
63
 
52
64
  =begin
@@ -77,7 +77,8 @@ module Skeem
77
77
  token = build_token('BOOLEAN', lexeme)
78
78
  elsif (lexeme = scanner.scan(/[+-]?[0-9]+(?=\s|[|()";]|$)/))
79
79
  token = build_token('INTEGER', lexeme) # Decimal radix
80
- elsif (lexeme = scanner.scan(/[+-]?[0-9]+\.[0-9]+(?:(?:e|E)[+-]?[0-9]+)?/))
80
+ elsif (lexeme = scanner.scan(/[+-]?[0-9]+(?:\.[0-9]+)?(?:(?:e|E)[+-]?[0-9]+)?/))
81
+ # Order dependency: must be tested after INTEGER case
81
82
  token = build_token('REAL', lexeme)
82
83
  elsif (lexeme = scanner.scan(/"(?:\\"|[^"])*"/)) # Double quotes literal?
83
84
  token = build_token('STRING_LIT', lexeme)
@@ -130,8 +131,8 @@ module Skeem
130
131
  value = to_real(aLexeme, aFormat)
131
132
  when 'STRING_LIT'
132
133
  value = to_string(aLexeme, aFormat)
133
- when 'SYMBOL'
134
- value = to_string(aLexeme, aFormat)
134
+ when 'IDENTIFIER'
135
+ value = to_identifier(aLexeme, aFormat)
135
136
  else
136
137
  value = aLexeme
137
138
  end
@@ -170,7 +171,7 @@ module Skeem
170
171
  return value
171
172
  end
172
173
 
173
- def to_symbol(aLexeme, aFormat)
174
+ def to_identifier(aLexeme, aFormat)
174
175
  case aFormat
175
176
  when :default
176
177
  value = aLexeme
data/lib/skeem/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Skeem
2
- VERSION = '0.0.4'.freeze
2
+ VERSION = '0.0.5'.freeze
3
3
  end
@@ -14,11 +14,79 @@ module Skeem
14
14
  end
15
15
  end # context
16
16
 
17
- context 'Parsing:' do
18
- it 'should parse definitions' do
19
- source = "(define r 10)"
20
- expect { subject.parse(source) }.not_to raise_error
17
+ context 'Parsing literals:' do
18
+ it 'should parse isolated booleans' do
19
+ samples = [
20
+ ['#f', false],
21
+ ['#false', false],
22
+ ['#t', true],
23
+ ['#true', true]
24
+ ]
25
+ samples.each do |source, predicted|
26
+ ptree = subject.parse(source)
27
+ expect(ptree.root).to be_kind_of(SExprBooleanNode)
28
+ expect(ptree.root.value).to eq(predicted)
29
+ end
21
30
  end
31
+
32
+ it 'should parse isolated integers' do
33
+ samples = [
34
+ ['0', 0],
35
+ ['3', 3],
36
+ ['-3', -3],
37
+ ['+12345', 12345],
38
+ ['-12345', -12345]
39
+ ]
40
+ samples.each do |source, predicted|
41
+ ptree = subject.parse(source)
42
+ expect(ptree.root).to be_kind_of(SExprIntegerNode)
43
+ expect(ptree.root.value).to eq(predicted)
44
+ end
45
+ end
46
+
47
+ it 'should parse isolated real numbers' do
48
+ samples = [
49
+ ['0.0', 0.0],
50
+ ['3.14', 3.14],
51
+ ['-3.14', -3.14],
52
+ ['+123e+45', 123e+45],
53
+ ['-123e-45', -123e-45]
54
+ ]
55
+ samples.each do |source, predicted|
56
+ ptree = subject.parse(source)
57
+ expect(ptree.root).to be_kind_of(SExprRealNode)
58
+ expect(ptree.root.value).to eq(predicted)
59
+ end
60
+ end
61
+
62
+ it 'should parse isolated strings' do
63
+ samples = [
64
+ ['"Hello world!"', 'Hello world!']
65
+ ]
66
+ samples.each do |source, predicted|
67
+ ptree = subject.parse(source)
68
+ expect(ptree.root).to be_kind_of(SExprStringNode)
69
+ expect(ptree.root.value).to eq(predicted)
70
+ end
71
+ end
72
+
73
+ it 'should parse isolated identifiers' do
74
+ samples = [
75
+ ['the-word-recursion-has-many-meanings', 'the-word-recursion-has-many-meanings']
76
+ ]
77
+ samples.each do |source, predicted|
78
+ ptree = subject.parse(source)
79
+ expect(ptree.root).to be_kind_of(SExprIdentifierNode)
80
+ expect(ptree.root.value).to eq(predicted)
81
+ end
82
+ end
83
+ end # context
84
+
85
+ context 'Parsing forms:' do
86
+ # it 'should parse definitions' do
87
+ # source = '(define r 10)'
88
+ # expect { subject.parse(source) }.not_to raise_error
89
+ # end
22
90
  end # context
23
91
  end # describe
24
92
  end # module
@@ -84,7 +84,8 @@ module Skeem
84
84
  # couple [raw input, expected]
85
85
  ["\t\t3.45e+6", 3.45e+6],
86
86
  ['+3.45e+6', +3.45e+6],
87
- ['-3.45e+6', -3.45e+6]
87
+ ['-3.45e+6', -3.45e+6],
88
+ ['123e+45', 1.23e+47]
88
89
  ]
89
90
 
90
91
  tests.each do |(input, prediction)|
@@ -96,7 +97,6 @@ module Skeem
96
97
  end
97
98
  end # context
98
99
 
99
- # TODO
100
100
  context 'String recognition:' do
101
101
  it 'should tokenize strings' do
102
102
  examples = [
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: skeem
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dimitri Geshef
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-08-29 00:00:00.000000000 Z
11
+ date: 2018-08-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rley
@@ -86,8 +86,8 @@ files:
86
86
  - appveyor.yml
87
87
  - lib/skeem.rb
88
88
  - lib/skeem/grammar.rb
89
- - lib/skeem/node_builder.rb
90
89
  - lib/skeem/parser.rb
90
+ - lib/skeem/s_expr_builder.rb
91
91
  - lib/skeem/s_expr_nodes.rb
92
92
  - lib/skeem/stoken.rb
93
93
  - lib/skeem/tokenizer.rb