-
Notifications
You must be signed in to change notification settings - Fork 0
Case: How to extend WRITE keyword
-
You need have ruby >=2.6.3
-
Clone this repo
git clone https://github.com/jackieju/abap2ruby.git
- Clone CPP2Ruby
cd .. git clone https://github.com/jackieju/CPP2Ruby.git cd abap2ruby
- Strongly recommend:
Install syntax highlight for EBNF file(.atg) on you code editor(textmate, sublime...)
You can download it here https://github.com/jackieju/abap2ruby/tree/master/ebnf_cocor_syntax_highlight.txt
The abap.code:
... WRITE SY-ABCDE . ...
Please open cocoR/abap.atg, find rule for 'WriteStatement':
WriteStatement = "WRITE" ( {["AT"] ["/"][number][ "(" (Expression | "*" | "**") ")" ]} [Expression] ... ["DD/MM/YY"|"MM/DD/YY"|"DD/MM/YYYY"|"MM/DD/YYYY"|"DDMMYY"|"MMDDYY"|"YYMMDD"] ) "." .
If you do nothing, the translator will generate original ABAP code.
WRITE SY-ABCDE
Now Let's put some code in abap.atg
WriteStatement = (. param_hash = {} .) "WRITE" ( {["AT"] ["/"][number][ "(" (Expression | "*" | "**") ")" ]} [Expression] (. param_hash["s"] = lus .) { ... ["DD/MM/YY"|"MM/DD/YY"|"DD/MM/YYYY"|"MM/DD/YYYY"|"DDMMYY"|"MMDDYY"|"YYMMDD"] ) "." (. params = [] param_hash.each{|k,v| params.push "#{k}: #{v}" } src("write(#{params.join(", ")})\n") .) .
Save abap.atg, and run ./go under cocoR/, will regenerate the translator.
The code between "(." and ".)" will be placed in generated parser. You can find it in cparser.rb
The first code block initialize a hash.
The 2nd code block get value from last parsed unterminal and store it into the hash.
"lus" means last unterminal string, the string value return from last unterminal.
The last code block set the translation result for current rule.
"src()" set the result for current parsing unterminal(rule).
Then run "ruby translate.rb ", It will generate ruby code:
write(s: sy.abcde)
Done !
Now you'd like this translator can work for more syntax of WRITE keyword. e.g.
WRITE /5 'SY-ABCDE' .
To make this work, you just add more code in the rule for WriteStatement:
WriteStatement = (. param_hash = {} .) "WRITE"
(
{["AT"] ["/"][number
(. param_hash["col"] = curString().to_i .)
][ "(" (Expression | "*" | "**") ")" ]} [Expression]
(.
param_hash["s"] = lus
.)
{
This will generate code:
write(col: 0, s: 'SY-ABCDE')
Done !
e.g.
stASSERT = "ASSERT" [ ["ID" identifier ["SUBKEY" identifier]] ["FIELDS" identifier ] "CONDITION" ] LogExp "." (.make.) .
It will translate ASSERT statment to ruby code
assert()
But it's actually an empty call. So you can add more work in abap.atg
stASSERT = "ASSERT" [ ["ID" identifier (.cp[:id]=prevString.)["SUBKEY" identifier(.cp[:subkey]=prevString.)]] ["FIELDS" identifier (.cp[:fields]=lus.)] "CONDITION" ] LogExp (.cp[:o]=lus.) "." (.make.) .
then it will translate the real assert statment. e.g.
ASSERT sy-subrc = 0.
will output ruby code:
assert(o:sy.subrc == 0)