0

I am modifying the oil file using python script. I have written EBNF grammar to convert oil file to AST using Grako. And generate oil file back from AST using codegen but the Oil file is not indent (generate in one line).

Sample Oil file:

CPU dummy 
{
    OS StdOS 
    {
      SCALABILITYCLASS = SC1;
      STATUS = EXTENDED;
    };
};

Generated Oil:

CPUdummy{OSStdOS{SCALABILITYCLASS=SC1;STATUS=EXTENDED;};};

EBNF grammer: file = [{Comments_option}] OIL_version Includes [implementation_definition] application_definition {object_definition_list};

Includes
         = "#include"  include_name ;

include_name
         = ?/[!-_A-Za-z0-9]+/? ;

OIL_version
         = "OIL_VERSION" "=" version description ";" ;

version  =  '"' ver '"';

implementation_definition
         = "IMPLEMENTATION" name "{" implementation_spec_list "}" description ";";

implementation_spec_list
        = [implementation_spec] ;

implementation_spec
         = object "{" implementation_def "}" description ";";

object   = "OS"
            "TASK"
            "COUNTER"
            "ALARM"
            "RESOURCE"
            "EVENT"
            "ISR"
            "MESSAGE"
            "COM"
            "NM"
            "APPMODE"
            "IPDU"
            "APPLICATION";

implementation_list
        =  [implementation_def]
        | [implementation_list implementation_def] ;

implementation_def
         = impl_attr_def
           | impl_ref_def;

impl_attr_def
         = "UINT32" auto_specifier number_range attribute_name multiple_specifier default_number description ";"
         | ( "INT32" | "UINT64" | "INT64" ) auto_specifier number_range attribute_name multiple_specifier default_number description ";"
         | "FLOAT" auto_specifier float_range attribute_name multiple_specifier default_float description ";"
         | "ENUM" auto_specifier enumeration attribute_name multiple_specifier default_name description ";"
         | "STRING" auto_specifier attribute_name multiple_specifier default_string description ";"
         | "BOOLEAN" auto_specifier bool_values attribute_name multiple_specifier default_bool description ";" ;

impl_parameter_list
         = [( "{" {implementation_def} [implementation_def] "}" )] ;

auto_specifier
         = ["WITH_AUTO"];

number_range
         = [( "[" ( number ".." | ( number ) ) number "]" )];

number_list 
         = number
         | number_list "," number ;

default_number
         = [( "=" ( number | "NO_DEFAULT" | "AUTO" ) )];

description
         = [( ":" '"' comments '"' )] ;

float_range
         = [( "[" float ".." float "]" )] ;

default_float
         = [( "=" ( float | "NO_DEFAULT" | "AUTO" ) )] ;

enumeration
         = "[" enumerator_list "]";

enumerator_list
         =  enumerator
         | enumerator_list  "," enumerator ;

enumerator
         = name [impl_parameter_list]  description;

bool_values
         = [( "[" "TRUE" impl_parameter_list description "," "FALSE" impl_parameter_list description "]" )] ;

default_name
         = [( "=" ( name | "NO_DEFAULT" | "AUTO" ) )] ;

default_string
         = [( "=" ( string | "NO_DEFAULT" | "AUTO" ) )] ;

default_bool
         = [( "=" ( boolean | "NO_DEFAULT" | "AUTO" ) )] ;

impl_ref_def
         = object_ref_type reference_name multiple_specifier description ";";

object_ref_type
         = "OS_TYPE"
           | "TASK_TYPE"
           | "COUNTER_TYPE"
           | "ALARM_TYPE"
           | "RESOURCE_TYPE"
           | "EVENT_TYPE"
           | "ISR_TYPE"
           | "MESSAGE_TYPE"
           | "COM_TYPE"
           | "NM_TYPE"
           | "APPMODE_TYPE"
           | "IPDU_TYPE";

reference_name
         = name
           | object;

multiple_specifier
         = [( "[" "]" )] ;

application_definition
         = "CPU" name "{" [Includes] { ( parameter_list Comments_option ) }  "}" description ";" ;

object_definition_list
         = [object_definition];

Comment_list
         =  object_definition | parameter comments ;

object_definition
         = object_name "{" { parameter_list Comments_option }  "}" description ";" ;

object_name
         = object name;

parameter_list
         = [parameter];

parameter
         = attribute_name "=" attribute_value [ "{" { ( parameter [Comments_option] ) } "}" ] description ";" ;

attribute_name
         = name
           | object;

attribute_value
         = boolean
           | float
           | number
           | string
           | "AUTO"
           | '"' string '"';

Comments_option
         = ( Single_line Multi_line );

Single_line = {"//" comments};

Multi_line  = {"/*@*" Comment_list "*@*/"};

name     = ?/[-_A-Za-z0-9]+/?;

string   = ?/[-_A-Za-z0-9_*, ]+/?;

ver      = ?/[0-9.0-9]+/?;

comments = ?/[-_A-Za-z0-9 *@]+/? ;

boolean  = "FALSE"
           | "TRUE";

number   = dec_number
           | hex_number;

dec_number
         = sign int_digits;

sign     = [( "+" | "-" )] ;

int_digits
         = zero_digit
           | pos_digit 
           | pos_digit dec_digits ;

dec_digits
         = {dec_digit}  [dec_digit] ;

float    = ver;

exponent = [( ( "e" | "E" ) sign dec_digits )] ;

zero_digit
         = "0";

pos_digit
         = "1"
           | "2"
           | "3"
           | "4"
           | "5"
           | "6"
           | "7"
           | "8"
           | "9";

dec_digit
         = zero_digit
           | pos_digit;

hex_number
         = "0x" {hex_digit};

hex_digit
         = "A"
           | "B"
           | "C"
           | "D"
           | "E"
           | "F"
           | "a"
           | "b"
           | "c"
           | "d"
           | "e"
           | "f"
           | "0"
           | "1"
           | "2"
           | "3"
           | "4"
           | "5"
           | "6"
           | "7"
           | "8"
           | "9";

For indentation grako to be taken care or codegen. How to indent the generated code. Thanks.

1 Answers1

1
import json
from grako.util import asjson

print(json.dumps(asjson(myast), indent=4))
Apalala
  • 9,017
  • 3
  • 30
  • 48
  • Thanks. Now the ast is printing the list as it is in the console with indentation. I want the ast to be write to a file not as a list (as a source file) – Ravi Shankar Mar 16 '15 at 10:38
  • You can do whatever you want with the string ``json.dumps()`` genrates. There's also a [json.dump()](https://docs.python.org/3.3/library/json.html#json.dump) that saves to a file object. – Apalala Mar 16 '15 at 16:12