0

我正在使用 python 脚本修改油文件。我已经编写了 EBNF 语法来使用 Grako 将油文件转换为 AST。并使用 codegen 从 AST 生成油文件,但油文件不缩进(在一行中生成)。

样品油文件:

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

生成的油:

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

EBNF 语法:file = [{Comments_option}] OIL_version 包括 [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";

缩进 grako 要小心或 codegen。如何缩进生成的代码。谢谢。

4

1 回答 1

1
import json
from grako.util import asjson

print(json.dumps(asjson(myast), indent=4))
于 2015-03-15T02:19:46.257 回答