-
Notifications
You must be signed in to change notification settings - Fork 0
/
convert_aa_to_ebnf.rb
116 lines (99 loc) · 3.07 KB
/
convert_aa_to_ebnf.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
require "FileUtils"
# convert ambigous ABAP syntax from https://help.sap.com/doc/abapdocu_751_index_htm/7.51/en-US/index.htm to EBNF
require_relative "rubyutility.rb"
$map ={
"identifier"=>"(field|attr|etab|ole|meth|wa|clnt|entity|dbcur|evt|itab|itab_type|struc|bdc_tab|rtab|stab|variant|ptab|group|dref|idx|lang|dynnr|prog|otab|dset|oref|dobj|dtype|blob|clob|abap_type|type|comp|key_name|didentifier|primary_key|dbtab|view)",
"number"=>"(width|pos|len|dec|n|line|dynnr)",
"Expresion"=>"(expr)",
"string1"=>"(text|title|cntry|mod|col)",
"Statements"=>"(statement_block)",
"Typing"=>"(typing)"
}
fname = $*[0]
p "file #{fname}"
if !fname
# fname = "abapref.txt"
fname = "abap_syntax.txt"
end
s = read_file(fname)
print s
print "\n"
def convert(str)
# remove comments
str = str.gsub(/^\#.*?$/m, "")
print "str->#{str}"
ar = str.split(/\n\s*\n/)
list = {}
ar.each{|s|
s = s.strip
next if s == ""
# get keyword
keyword = nil
s.scan(/[A-Z][A-Z0-9_-]+/){|m|
keyword = m
break
}
print("\n-----------\n")
print (s+"\n")
print("\n-----------\n")
p "keyword:#{keyword}"
if list[keyword] == nil
list[keyword] = []
end
# convert upcase word (Keyword) to quoated
s = s.gsub(/\b([A-Z][A-Z0-9_-]+)\b/, '"\1"')
# replace non-keyword
$map.keys().each{|k|
reg = Regexp.new("\\b#{$map[k]}\\d?\\b")
p "regexp=#{reg}"
s = s.gsub(reg, k)
}
s.gsub!("{","(")
s.gsub!("}",")")
# tackle with ...
s.scan(/([a-z][a-z0-9_-]+\s+)+\.\.\./){|m|
p m.inspect
}
s.gsub!(/([a-z][a-z0-9_-]+\s+)+\.\.\./, '\1')
if s.index("...")
raise ("... is not parsed")
end
print("==>#{keyword}:#{s}\n")
s = s.gsub(".", "\".\"")
s = s.gsub(/,\@\~\*\+=/, '"\1"')
print("==>2#{keyword}:#{s}\n")
list[keyword].push(s)
}
ret = []
# merge rule of same keyword
rulelist = []
list.each{|k,v|
rulename= k.gsub("-", "_")
rulelist.push(rulename)
if v.size >1
t=""
v.each{|l|
if !l.strip.start_with?("\"#{k}\"")
raise "error: '#{l}' not start with keyword #{k}"
end
if !l.strip.end_with?("\".\"")
raise "error: '#{l}' not end with keyword \".\""
end
t += " | " if t != ""
l = l.gsub(/\"\.\"$/,"")
t += l[k.size+2..l.size-1]
}
ret.push("#{rulename} = \"#{k}\"( #{t} ) \".\".")
else
ret.push("#{rulename} = #{v[0]}.")
end
}
# list keywords
print "key list:\n"
print rulelist.join("\n| ")
print("\n")
return ret
end
p "==== result ===="
r = convert(s).join("\n\n")
save_to_file(r, "convert_result")