rley 0.3.11 → 0.3.12
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +3 -0
- data/examples/data_formats/JSON/{demo_json.rb → JSON_demo.rb} +0 -0
- data/examples/data_formats/JSON/JSON_parser.rb +0 -1
- data/examples/general/calc/calc_demo.rb +31 -0
- data/examples/general/calc/calc_grammar.rb +28 -0
- data/examples/general/calc/calc_lexer.rb +93 -0
- data/examples/general/calc/calc_parser.rb +24 -0
- data/lib/rley/constants.rb +1 -1
- data/lib/rley/syntax/grammar.rb +6 -7
- data/lib/rley/syntax/grammar_builder.rb +6 -8
- data/spec/rley/parser/gfg_earley_parser_spec.rb +25 -22
- data/spec/rley/parser/groucho_spec.rb +11 -10
- data/spec/rley/parser/parse_forest_builder_spec.rb +10 -9
- data/spec/rley/parser/parse_forest_factory_spec.rb +10 -9
- data/spec/rley/support/ambiguous_grammar_helper.rb +6 -5
- data/spec/rley/support/grammar_abc_helper.rb +6 -5
- data/spec/rley/support/grammar_ambig01_helper.rb +8 -7
- data/spec/rley/support/grammar_b_expr_helper.rb +9 -8
- data/spec/rley/support/grammar_l0_helper.rb +15 -14
- data/spec/rley/support/grammar_sppf_helper.rb +10 -9
- metadata +7 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3cb8a4bdff7b8a62407ea9b05f6efc807a62bcbf
|
4
|
+
data.tar.gz: 498be3de6c49c8b6800d5f64eb2e1237f845b405
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e8ca57661728076d51e311c936698bfe603962de9041c02a686bb7cce360ad21f992437e7f3f460b7792b78c1fe30106cd955b3dbe5ecebdd8973112dc2375df
|
7
|
+
data.tar.gz: 984d7e2dc9f42831657f3a30d58c5e4145cc9383df894f3234dabd09c34138bdfa3bde3aa956f1b14dc8cce97dc90eaa11c85074fca21befd9a038cac95e3218
|
data/CHANGELOG.md
CHANGED
File without changes
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require_relative 'calc_parser'
|
2
|
+
|
3
|
+
# Create a calculator parser object
|
4
|
+
parser = CalcParser.new
|
5
|
+
|
6
|
+
# Parse the input expression in command-line
|
7
|
+
if ARGV.empty?
|
8
|
+
msg = <<-END_MSG
|
9
|
+
Command-line symtax:
|
10
|
+
ruby #{__FILE__} "arithmetic expression"
|
11
|
+
where:
|
12
|
+
the arithmetic expression is enclosed between double quotes (")
|
13
|
+
|
14
|
+
Example:
|
15
|
+
ruby #{__FILE__} "2 * 3 + (4 - 1)"
|
16
|
+
END_MSG
|
17
|
+
puts msg
|
18
|
+
exit(1)
|
19
|
+
end
|
20
|
+
puts ARGV[0]
|
21
|
+
result = parser.parse_expression(ARGV[0])
|
22
|
+
|
23
|
+
unless result.success?
|
24
|
+
# Stop if the parse failed...
|
25
|
+
puts "Parsing of '#{file_name}' failed"
|
26
|
+
exit(1)
|
27
|
+
end
|
28
|
+
|
29
|
+
# Generate a parse forest from the parse result
|
30
|
+
pforest = result.parse_forest
|
31
|
+
# End of file
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# Grammar for simple arithmetical expressions
|
2
|
+
require 'rley' # Load the gem
|
3
|
+
|
4
|
+
########################################
|
5
|
+
# Define a grammar for basic arithmetical expressions
|
6
|
+
builder = Rley::Syntax::GrammarBuilder.new do
|
7
|
+
add_terminals('NUMBER')
|
8
|
+
add_terminals('LPAREN', 'RPAREN') # For '(', ')' delimiters
|
9
|
+
add_terminals('PLUS', 'MINUS') # For '+', '-' operators or sign
|
10
|
+
add_terminals('STAR', 'DIVIDE') # For '*', '/' operators
|
11
|
+
rule 'expression' => %w(sign simple_expression)
|
12
|
+
rule 'simple_expression' => 'term'
|
13
|
+
rule 'simple_expression' => %w(simple_expression add_operator term)
|
14
|
+
rule 'term' => 'factor'
|
15
|
+
rule 'term' => %w(term mul_operator factor)
|
16
|
+
rule 'factor' => 'NUMBER'
|
17
|
+
rule 'factor' => %w(LPAREN expression RPAREN)
|
18
|
+
rule 'sign' => 'PLUS'
|
19
|
+
rule 'sign' => 'MINUS'
|
20
|
+
rule 'sign' => []
|
21
|
+
rule 'add_operator' => 'PLUS'
|
22
|
+
rule 'add_operator' => 'MINUS'
|
23
|
+
rule 'mul_operator' => 'STAR'
|
24
|
+
rule 'mul_operator' => 'DIVIDE'
|
25
|
+
end
|
26
|
+
|
27
|
+
# And now build the grammar...
|
28
|
+
CalcGrammar = builder.grammar
|
@@ -0,0 +1,93 @@
|
|
1
|
+
# File: calc_lexer.rb
|
2
|
+
# Lexer for a basic arithmetical expression parser
|
3
|
+
require 'strscan'
|
4
|
+
require 'rley' # Load the gem
|
5
|
+
|
6
|
+
|
7
|
+
class CalcLexer
|
8
|
+
attr_reader(:scanner)
|
9
|
+
attr_reader(:lineno)
|
10
|
+
attr_reader(:line_start)
|
11
|
+
attr_reader(:name2symbol)
|
12
|
+
|
13
|
+
@@lexeme2name = {
|
14
|
+
'(' => 'LPAREN',
|
15
|
+
')' => 'RPAREN',
|
16
|
+
'+' => 'PLUS',
|
17
|
+
'-' => 'MINUS',
|
18
|
+
'*' => 'STAR',
|
19
|
+
'/' => 'DIVIDE',
|
20
|
+
}
|
21
|
+
|
22
|
+
class ScanError < StandardError ; end
|
23
|
+
|
24
|
+
public
|
25
|
+
def initialize(source, aGrammar)
|
26
|
+
@scanner = StringScanner.new(source)
|
27
|
+
@name2symbol = aGrammar.name2symbol
|
28
|
+
@lineno = 1
|
29
|
+
end
|
30
|
+
|
31
|
+
def tokens()
|
32
|
+
tok_sequence = []
|
33
|
+
until @scanner.eos? do
|
34
|
+
token = _next_token
|
35
|
+
tok_sequence << token unless token.nil?
|
36
|
+
end
|
37
|
+
|
38
|
+
return tok_sequence
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
def _next_token()
|
43
|
+
token = nil
|
44
|
+
skip_whitespaces
|
45
|
+
curr_ch = scanner.getch # curr_ch is at start of token or eof reached...
|
46
|
+
|
47
|
+
begin
|
48
|
+
break if curr_ch.nil?
|
49
|
+
|
50
|
+
case curr_ch
|
51
|
+
when '(', ')', '+', '-', '*', '/'
|
52
|
+
type_name = @@lexeme2name[curr_ch]
|
53
|
+
token_type = name2symbol[type_name]
|
54
|
+
token = Rley::Parser::Token.new(curr_ch, token_type)
|
55
|
+
|
56
|
+
# LITERALS
|
57
|
+
when /[-0-9]/ # Start character of number literal found
|
58
|
+
@scanner.pos = scanner.pos - 1 # Simulate putback
|
59
|
+
value = scanner.scan(/-?[0-9]+(\.[0-9]+)?([eE][-+]?[0-9])?/)
|
60
|
+
token_type = name2symbol['NUMBER']
|
61
|
+
token = Rley::Parser::Token.new(value, token_type)
|
62
|
+
|
63
|
+
|
64
|
+
else # Unknown token
|
65
|
+
erroneous = curr_ch.nil? ? '' : curr_ch
|
66
|
+
sequel = scanner.scan(/.{1,20}/)
|
67
|
+
erroneous += sequel unless sequel.nil?
|
68
|
+
raise ScanError.new("Unknown token #{erroneous}")
|
69
|
+
end #case
|
70
|
+
|
71
|
+
|
72
|
+
end while (token.nil? && curr_ch = scanner.getch())
|
73
|
+
|
74
|
+
return token
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
def skip_whitespaces()
|
79
|
+
matched = scanner.scan(/[ \t\f\n\r]+/)
|
80
|
+
return if matched.nil?
|
81
|
+
|
82
|
+
newline_count = 0
|
83
|
+
matched.scan(/\n\r?|\r/) { |_| newline_count += 1 }
|
84
|
+
newline_detected(newline_count)
|
85
|
+
end
|
86
|
+
|
87
|
+
|
88
|
+
def newline_detected(count)
|
89
|
+
@lineno += count
|
90
|
+
@line_start = scanner.pos()
|
91
|
+
end
|
92
|
+
|
93
|
+
end # class
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# Purpose: to demonstrate how to build and render a parse tree for JSON
|
2
|
+
# language
|
3
|
+
require_relative 'calc_lexer'
|
4
|
+
require_relative 'calc_grammar'
|
5
|
+
|
6
|
+
# A parser for arithmetic expressions
|
7
|
+
class CalcParser < Rley::Parser::GFGEarleyParser
|
8
|
+
attr_reader(:source_file)
|
9
|
+
|
10
|
+
# Constructor
|
11
|
+
def initialize()
|
12
|
+
# Builder the Earley parser with the calculator grammar
|
13
|
+
super(CalcGrammar)
|
14
|
+
end
|
15
|
+
|
16
|
+
def parse_expression(aText)
|
17
|
+
lexer = CalcLexer.new(aText, self.grammar)
|
18
|
+
result = parse(lexer.tokens)
|
19
|
+
|
20
|
+
return result
|
21
|
+
end
|
22
|
+
end # class
|
23
|
+
|
24
|
+
# End of file
|
data/lib/rley/constants.rb
CHANGED
data/lib/rley/syntax/grammar.rb
CHANGED
@@ -3,11 +3,11 @@ require 'set'
|
|
3
3
|
module Rley # This module is used as a namespace
|
4
4
|
module Syntax # This module is used as a namespace
|
5
5
|
# A grammar specifies the syntax of a language.
|
6
|
-
# Formally, a grammar has:
|
7
|
-
# One start symbol,
|
8
|
-
# One or more other production rules,
|
9
|
-
# Each production has a rhs that is a sequence of grammar symbols.
|
10
|
-
# Grammar symbols are categorized into
|
6
|
+
# Formally, a grammar has:
|
7
|
+
# * One start symbol,
|
8
|
+
# * One or more other production rules,
|
9
|
+
# * Each production has a rhs that is a sequence of grammar symbols.
|
10
|
+
# * Grammar symbols are categorized into
|
11
11
|
# -terminal symbols
|
12
12
|
# -non-terminal symbols
|
13
13
|
class Grammar
|
@@ -24,8 +24,7 @@ module Rley # This module is used as a namespace
|
|
24
24
|
# A Hash with pairs of the kind: symbol name => grammar symbol
|
25
25
|
attr_reader(:name2symbol)
|
26
26
|
|
27
|
-
# @param theProductions [Array
|
28
|
-
# of the grammar.
|
27
|
+
# @param theProductions [Array<Production>] productions of the grammar.
|
29
28
|
def initialize(theProductions)
|
30
29
|
@rules = []
|
31
30
|
@symbols = []
|
@@ -34,25 +34,23 @@ module Rley # This module is used as a namespace
|
|
34
34
|
return symbols[aSymbolName]
|
35
35
|
end
|
36
36
|
|
37
|
-
# Add the terminal symbols of the language
|
38
|
-
# @param terminalSymbols [String or Terminal]
|
39
|
-
# terminal symbols to add to the grammar.
|
37
|
+
# Add the given terminal symbols to the grammar of the language
|
38
|
+
# @param terminalSymbols [String or Terminal] 1..* terminal symbols.
|
40
39
|
def add_terminals(*terminalSymbols)
|
41
40
|
new_symbs = build_symbols(Terminal, terminalSymbols)
|
42
41
|
symbols.merge!(new_symbs)
|
43
42
|
end
|
44
43
|
|
45
44
|
|
46
|
-
# Add a production rule in the grammar
|
47
|
-
#
|
48
|
-
# production. It consists of a key-value pair of the form:
|
49
|
-
# String => Array.
|
45
|
+
# Add a production rule in the grammar given one
|
46
|
+
# key-value pair of the form: String => Array.
|
50
47
|
# Where the key is the name of the non-terminal appearing in the
|
51
48
|
# left side of the rule.
|
52
49
|
# The value, an Array, is a sequence of grammar symbol names.
|
53
50
|
# The rule is created and inserted in the grammar.
|
54
51
|
# Example:
|
55
|
-
# builder.add_production('A' => ['a', 'A', 'c'])
|
52
|
+
# builder.add_production('A' => ['a', 'A', 'c'])
|
53
|
+
# @param aProductionRepr [Hash] A Hash-based representation of production
|
56
54
|
def add_production(aProductionRepr)
|
57
55
|
aProductionRepr.each_pair do |(lhs_name, rhs_repr)|
|
58
56
|
lhs = get_nonterminal(lhs_name)
|
@@ -358,13 +358,14 @@ SNIPPET
|
|
358
358
|
t_plus = Syntax::VerbatimSymbol.new('+')
|
359
359
|
t_star = Syntax::VerbatimSymbol.new('*')
|
360
360
|
|
361
|
-
builder = Syntax::GrammarBuilder.new
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
361
|
+
builder = Syntax::GrammarBuilder.new do
|
362
|
+
add_terminals(t_int, t_plus, t_star)
|
363
|
+
rule 'P' => 'S'
|
364
|
+
rule 'S' => %w(S + S)
|
365
|
+
rule 'S' => %w(S * S)
|
366
|
+
rule 'S' => 'L'
|
367
|
+
rule 'L' => 'integer'
|
368
|
+
end
|
368
369
|
input_sequence = [
|
369
370
|
{ '2' => 'integer' },
|
370
371
|
'+',
|
@@ -603,12 +604,13 @@ MSG
|
|
603
604
|
t_lparen = Syntax::VerbatimSymbol.new('(')
|
604
605
|
t_rparen = Syntax::VerbatimSymbol.new(')')
|
605
606
|
|
606
|
-
builder = Syntax::GrammarBuilder.new
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
607
|
+
builder = Syntax::GrammarBuilder.new do
|
608
|
+
add_terminals(t_int, t_plus, t_lparen, t_rparen)
|
609
|
+
rule 'S' => 'E'
|
610
|
+
rule 'E' => 'int'
|
611
|
+
rule 'E' => %w(( E + E ))
|
612
|
+
rule 'E' => %w(E + E)
|
613
|
+
end
|
612
614
|
input_sequence = [
|
613
615
|
{ '7' => 'int' },
|
614
616
|
'+',
|
@@ -713,15 +715,16 @@ MSG
|
|
713
715
|
t_star = Syntax::VerbatimSymbol.new('*')
|
714
716
|
t_slash = Syntax::VerbatimSymbol.new('/')
|
715
717
|
|
716
|
-
builder = Syntax::GrammarBuilder.new
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
|
724
|
-
|
718
|
+
builder = Syntax::GrammarBuilder.new do
|
719
|
+
add_terminals(t_a, t_star, t_slash)
|
720
|
+
rule 'Z' => 'E'
|
721
|
+
rule 'E' => %w(E Q F)
|
722
|
+
rule 'E' => 'F'
|
723
|
+
rule 'F' => t_a
|
724
|
+
rule 'Q' => t_star
|
725
|
+
rule 'Q' => t_slash
|
726
|
+
rule 'Q' => [] # Empty production
|
727
|
+
end
|
725
728
|
|
726
729
|
tokens = build_token_sequence(%w(a a / a), builder.grammar)
|
727
730
|
instance = GFGEarleyParser.new(builder.grammar)
|
@@ -20,16 +20,17 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
20
20
|
include ExpectationHelper # Mix-in with expectation on parse entry sets
|
21
21
|
|
22
22
|
let(:sample_grammar) do
|
23
|
-
builder = Rley::Syntax::GrammarBuilder.new
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
23
|
+
builder = Rley::Syntax::GrammarBuilder.new do
|
24
|
+
add_terminals('N', 'V', 'Pro') # N(oun), V(erb), Pro(noun)
|
25
|
+
add_terminals('Det', 'P') # Det(erminer), P(reposition)
|
26
|
+
rule 'S' => %w(NP VP)
|
27
|
+
rule 'NP' => %w(Det N)
|
28
|
+
rule 'NP' => %w(Det N PP)
|
29
|
+
rule 'NP' => 'Pro'
|
30
|
+
rule 'VP' => %w(V NP)
|
31
|
+
rule 'VP' => %w(VP PP)
|
32
|
+
rule 'PP' => %w(P NP)
|
33
|
+
end
|
33
34
|
builder.grammar
|
34
35
|
end
|
35
36
|
|
@@ -21,15 +21,16 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
21
21
|
# "SPPF=Style Parsing From Earley Recognizers" in
|
22
22
|
# Notes in Theoretical Computer Science 203, (2008), pp. 53-67
|
23
23
|
# contains a hidden left recursion and a cycle
|
24
|
-
builder = Syntax::GrammarBuilder.new
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
24
|
+
builder = Syntax::GrammarBuilder.new do
|
25
|
+
add_terminals('a', 'b')
|
26
|
+
rule 'Phi' => 'S'
|
27
|
+
rule 'S' => %w(A T)
|
28
|
+
rule 'S' => %w(a T)
|
29
|
+
rule 'A' => 'a'
|
30
|
+
rule 'A' => %w(B A)
|
31
|
+
rule 'B' => []
|
32
|
+
rule 'T' => %w(b b b)
|
33
|
+
end
|
33
34
|
builder.grammar
|
34
35
|
end
|
35
36
|
|
@@ -20,15 +20,16 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
20
20
|
# "SPPF-Style Parsing From Earley Recognizers" in
|
21
21
|
# Notes in Theoretical Computer Science 203, (2008), pp. 53-67
|
22
22
|
# contains a hidden left recursion and a cycle
|
23
|
-
builder = Syntax::GrammarBuilder.new
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
23
|
+
builder = Syntax::GrammarBuilder.new do
|
24
|
+
add_terminals('a', 'b')
|
25
|
+
rule 'Phi' => 'S'
|
26
|
+
rule 'S' => %w(A T)
|
27
|
+
rule 'S' => %w(a T)
|
28
|
+
rule 'A' => 'a'
|
29
|
+
rule 'A' => %w(B A)
|
30
|
+
rule 'B' => []
|
31
|
+
rule 'T' => %w(b b b)
|
32
|
+
end
|
32
33
|
builder.grammar
|
33
34
|
end
|
34
35
|
|
@@ -8,11 +8,12 @@ module AmbiguousGrammarHelper
|
|
8
8
|
# expression grammar.
|
9
9
|
# (based on an example from Fisher and LeBlanc: "Crafting a Compiler")
|
10
10
|
def grammar_builder()
|
11
|
-
builder = Rley::Syntax::GrammarBuilder.new
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
11
|
+
builder = Rley::Syntax::GrammarBuilder.new do
|
12
|
+
add_terminals('+', 'id')
|
13
|
+
rule 'S' => 'E'
|
14
|
+
rule 'E' => %w(E + E)
|
15
|
+
rule 'E' => 'id'
|
16
|
+
end
|
16
17
|
builder
|
17
18
|
end
|
18
19
|
|
@@ -5,11 +5,12 @@ module GrammarABCHelper
|
|
5
5
|
# Factory method. Creates a grammar builder for a simple grammar.
|
6
6
|
# (based on example in N. Wirth "Compiler Construction" book, p. 6)
|
7
7
|
def grammar_abc_builder()
|
8
|
-
builder = Rley::Syntax::GrammarBuilder.new
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
8
|
+
builder = Rley::Syntax::GrammarBuilder.new do
|
9
|
+
add_terminals('a', 'b', 'c')
|
10
|
+
rule 'S' => 'A'
|
11
|
+
rule 'A' => %w(a A c)
|
12
|
+
rule 'A' => 'b'
|
13
|
+
end
|
13
14
|
|
14
15
|
return builder
|
15
16
|
end
|
@@ -9,13 +9,14 @@ module GrammarAmbig01Helper
|
|
9
9
|
# Grammar 3: An ambiguous arithmetic expression language
|
10
10
|
# (based on example in article on Earley's algorithm in Wikipedia)
|
11
11
|
def grammar_ambig01_builder()
|
12
|
-
builder = Rley::Syntax::GrammarBuilder.new
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
12
|
+
builder = Rley::Syntax::GrammarBuilder.new do
|
13
|
+
add_terminals('integer', '+', '*')
|
14
|
+
rule 'P' => 'S'
|
15
|
+
rule 'S' => %w(S + S)
|
16
|
+
rule 'S' => %w(S * S)
|
17
|
+
rule 'S' => 'L'
|
18
|
+
rule 'L' => 'integer'
|
19
|
+
end
|
19
20
|
builder
|
20
21
|
end
|
21
22
|
|
@@ -8,14 +8,15 @@ module GrammarBExprHelper
|
|
8
8
|
# expression grammar.
|
9
9
|
# (based on the article about Earley's algorithm in Wikipedia)
|
10
10
|
def grammar_expr_builder()
|
11
|
-
builder = Rley::Syntax::GrammarBuilder.new
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
11
|
+
builder = Rley::Syntax::GrammarBuilder.new do
|
12
|
+
add_terminals('+', '*', 'integer')
|
13
|
+
rule 'P' => 'S'
|
14
|
+
rule 'S' => %w(S + M)
|
15
|
+
rule 'S' => 'M'
|
16
|
+
rule 'M' => %w(M * T)
|
17
|
+
rule 'M' => 'T'
|
18
|
+
rule 'T' => 'integer'
|
19
|
+
end
|
19
20
|
builder
|
20
21
|
end
|
21
22
|
|
@@ -10,20 +10,21 @@ module GrammarL0Helper
|
|
10
10
|
# It defines the syntax of a sentence in a language with a
|
11
11
|
# very limited syntax and lexicon in the context of airline reservation.
|
12
12
|
def grammar_l0_builder()
|
13
|
-
builder = Rley::Syntax::GrammarBuilder.new
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
13
|
+
builder = Rley::Syntax::GrammarBuilder.new do
|
14
|
+
add_terminals('Noun', 'Verb', 'Pronoun', 'Proper-Noun')
|
15
|
+
add_terminals('Determiner', 'Preposition')
|
16
|
+
rule 'S' => %w(NP VP)
|
17
|
+
rule 'NP' => 'Pronoun'
|
18
|
+
rule 'NP' => 'Proper-Noun'
|
19
|
+
rule 'NP' => %w(Determiner Nominal)
|
20
|
+
rule 'Nominal' => %w(Nominal Noun)
|
21
|
+
rule 'Nominal' => 'Noun'
|
22
|
+
rule 'VP' => 'Verb'
|
23
|
+
rule 'VP' => %w(Verb NP)
|
24
|
+
rule 'VP' => %w(Verb NP PP)
|
25
|
+
rule 'VP' => %w(Verb PP)
|
26
|
+
rule 'PP' => %w(Preposition PP)
|
27
|
+
end
|
27
28
|
builder
|
28
29
|
end
|
29
30
|
|
@@ -9,15 +9,16 @@ module GrammarSPPFHelper
|
|
9
9
|
# Notes in Theoretical Computer Science 203, (2008), pp. 53-67
|
10
10
|
# contains a hidden left recursion and a cycle
|
11
11
|
def grammar_sppf_builder()
|
12
|
-
builder = Rley::Syntax::GrammarBuilder.new
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
12
|
+
builder = Rley::Syntax::GrammarBuilder.new do
|
13
|
+
add_terminals('a', 'b')
|
14
|
+
rule 'Phi' => 'S'
|
15
|
+
rule 'S' => %w(A T)
|
16
|
+
rule 'S' => %w(a T)
|
17
|
+
rule 'A' => 'a'
|
18
|
+
rule 'A' => %w(B A)
|
19
|
+
rule 'B' => []
|
20
|
+
rule 'T' => %w(b b b)
|
21
|
+
end
|
21
22
|
|
22
23
|
return builder
|
23
24
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rley
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.12
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dimitri Geshef
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-12-
|
11
|
+
date: 2016-12-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -130,10 +130,14 @@ files:
|
|
130
130
|
- README.md
|
131
131
|
- Rakefile
|
132
132
|
- examples/NLP/mini_en_demo.rb
|
133
|
+
- examples/data_formats/JSON/JSON_demo.rb
|
133
134
|
- examples/data_formats/JSON/JSON_grammar.rb
|
134
135
|
- examples/data_formats/JSON/JSON_lexer.rb
|
135
136
|
- examples/data_formats/JSON/JSON_parser.rb
|
136
|
-
- examples/
|
137
|
+
- examples/general/calc/calc_demo.rb
|
138
|
+
- examples/general/calc/calc_grammar.rb
|
139
|
+
- examples/general/calc/calc_lexer.rb
|
140
|
+
- examples/general/calc/calc_parser.rb
|
137
141
|
- lib/rley.rb
|
138
142
|
- lib/rley/constants.rb
|
139
143
|
- lib/rley/formatter/base_formatter.rb
|