Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
TASTE
asn1-value-editor
Commits
ea5b4744
Commit
ea5b4744
authored
Jul 16, 2015
by
Maxime Perrotin
Browse files
Parse VDM values
parent
f1e29439
Changes
1
Hide whitespace changes
Inline
Side-by-side
asn1_value_editor/vdm_vn.py
View file @
ea5b4744
...
...
@@ -34,182 +34,119 @@ from pyparsing import(Word, QuotedString, Literal, Combine, Optional,
import
string
# TBC in VDM - Keep ASN.1 Value Notation
BitStringLiteral
=
(
'"'
+
Word
(
"01"
)
+
'"B'
).
setResultsName
(
'BITSTRING'
)
# TBC in VDM - Keep ASN.1 Value Notation
OctetStringLiteral
=
(
'"'
+
Word
(
string
.
hexdigits
)
+
'"H'
).
setResultsName
(
'OCTETSTRING'
)
# QuotedString's first parameter = quote type..+multiline to support \n => OK
# Support embedded quotes as per GSER standard (""embedded quoted text"")
StringLiteral
=
QuotedString
(
'"'
,
escQuote
=
'""'
,
multiline
=
True
,).
setResultsName
(
'QUOTEDSTRING'
)
# QuotedString's first parameter = quote type..+multiline to support \n
# Support embedded quotes (""embedded quoted text"")
STRINGLITERAL
=
QuotedString
(
'"'
,
escQuote
=
'""'
,
multiline
=
True
,)
TRUE
=
Literal
(
"true"
).
setResultsName
(
'TRUE'
)
FALSE
=
Literal
(
"false"
).
setResultsName
(
'FALSE'
)
NULL
=
Literal
(
"nil"
)
# TBC in VDM
NULL
=
Literal
(
"NULL"
).
setResultsName
(
'NULL'
)
COMMA
=
Literal
(
','
).
suppress
()
# TBC in VDM
PLUS_INFINITY
=
Literal
(
"PLUS-INFINITY"
).
setResultsName
(
'PLUS-INFINITY'
)
MINUS_INFINITY
=
Literal
(
"MINUS-INFINITY"
).
setResultsName
(
'MINUS-INFINITY'
)
# EMPTY_LIST:
LBRACKET
=
Literal
(
'{'
).
suppress
()
RBRACKET
=
Literal
(
'}'
).
suppress
()
# Square brackets
LSBRACKET
=
Literal
(
'['
).
suppress
()
RSBRACKET
=
Literal
(
']'
).
suppress
()
# Parenthesis
LPAREN
=
Literal
(
'('
).
suppress
()
RPAREN
=
Literal
(
')'
).
suppress
()
# INTEGER
IN
T
=
Combine
(
Optional
(
oneOf
(
"+ -"
))
+
(
Word
(
srange
(
"[1-9]"
),
nums
)
|
Literal
(
'0'
))).
setResultsName
(
'INTEGER'
)
LT
=
Literal
(
'<'
).
suppress
()
G
T
=
Literal
(
'>'
).
suppress
(
)
# This one is correct:
# a lowercase followed by a-zA-z and -
#LID = Word(string.lowercase, string.letters+string.digits+'-')
# Update MP 21/11/12: made it tolerant to uppercase for the first character
LID
=
Word
(
string
.
letters
,
string
.
letters
+
string
.
digits
+
'-'
)
identifier
=
LID
.
setResultsName
(
'IDENTIFIER'
)
INT
=
Combine
(
Optional
(
oneOf
(
"+ -"
))
+
(
Word
(
srange
(
"[1-9]"
),
nums
)
|
Literal
(
'0'
))).
setResultsName
(
'INTEGER'
)
# Value reference is in practice used to identify enumerated values
valuereference
=
LID
.
setResultsName
(
'VALUE_REF'
)
LID
=
Word
(
string
.
lowercase
,
string
.
letters
+
string
.
digits
+
'_'
)
ID
=
Word
(
string
.
letters
+
string
.
digits
+
'_'
)
MKPREFIX
=
Literal
(
"mk_"
).
suppress
()
# FloatingPointLiteral
DOT
=
Literal
(
'.'
)
DOUBLE_DOT
=
Literal
(
'..'
)
# Exponent (e.g. e+10)
Exponent
=
oneOf
(
"e E"
)
+
Optional
(
oneOf
(
"+ -"
))
+
OneOrMore
(
Word
(
nums
))
# Thefirst (INT + DOUBLE_DOT) is unclear (e.g. "5..").
FloatingPointLiteral
=
(
INT
+
DOUBLE_DOT
|
Combine
(
INT
+
DOT
+
Optional
(
Word
(
nums
))
+
Optional
(
Exponent
))
FloatingPointLiteral
=
(
Combine
(
INT
+
Optional
(
DOT
)
+
Optional
(
Word
(
nums
))
+
Optional
(
Exponent
))
|
INT
).
setResultsName
(
'REAL1'
)
# Numeric value2 (eg. { mantissa 3, base 4, exponent 5 })
# Does this noataion exist in VDM ?
MANTISSA
=
Literal
(
'mantissa'
).
suppress
()
BASE
=
Literal
(
'base'
).
suppress
()
EXPONENT
=
Literal
(
'exponent'
).
suppress
()
NUMERIC_VALUE2
=
(
nestedExpr
(
'{'
,
'}'
,
MANTISSA
+
INT
+
COMMA
+
BASE
+
INT
+
COMMA
+
EXPONENT
+
INT
)).
setResultsName
(
'REAL2'
)
# Forward allows to use recursive constructs
NAMED_VALUE_LIST
=
Forward
()
SEQUENCE
=
Forward
()
SETOF
=
Forward
()
VALUE_LIST
=
Forward
()
choiceValue
=
Forward
()
ENUM
=
Forward
()
SEQOF
=
Forward
()
# Support for "Any" value (using a star)
AnyValueLiteral
=
Keyword
(
'*'
).
setResultsName
(
'ANY'
)
# ASN.1 Value Notation: only missing construct are OID references
# Ambiguity: FloatingPointLiteral contains INT -> INT will never be parsed as REAL
value
=
(
BitStringLiteral
|
OctetStringLiteral
|
TRUE
value
=
(
TRUE
|
FALSE
|
StringLiteral
|
NULL
|
PLUS_INFINITY
|
MINUS_INFINITY
|
NAMED_VALUE_LIST
|
VALUE_LIST
|
STRINGLITERAL
|
SEQUENCE
|
SEQOF
|
SETOF
|
(
valuereference
^
choiceValue
)
|
ENUM
|
(
INT
^
FloatingPointLiteral
)
|
NUMERIC_VALUE2
|
AnyValueLiteral
)
# ASN.1 CHOICE --> TBC in VDM
choiceValue
<<
(
identifier
+
':'
+
value
).
setResultsName
(
'CHOICE'
)
# SEQUENCE
NAMED_VALUE_LIST
<<
LPAREN
+
delimitedList
(
value
)
+
RPAREN
)
# VDM SEQUENCE OF
VALUE_LIST
<<
LSBRACKET
+
Optional
(
delimitedList
(
value
))
+
RSBRACKET
# SET OF
SEQUENCE
<<
MKPREFIX
+
Optional
(
ID
.
suppress
())
\
+
LPAREN
+
delimitedList
(
value
)
+
RPAREN
SEQOF
<<
LSBRACKET
+
Optional
(
delimitedList
(
value
))
+
RSBRACKET
SETOF
<<
LBRACKET
+
Optional
(
delimitedList
(
value
))
+
RBRACKET
ENUM
<<
LT
+
ID
+
GT
# Parse actions allow to
modify the AST to be compliant with the ASN.1 Editor input
NAMED_VALUE_LIST
.
setParseAction
(
lambda
s
,
l
,
t
:
[
t
.
asList
()])
VALUE_LIST
.
setParseAction
(
lambda
s
,
l
,
t
:
[
t
.
asList
()])
# Parse actions allow to
transform the AST on the fly
SEQUENCE
.
setParseAction
(
lambda
s
,
l
,
t
:
[
t
.
asList
()])
SEQOF
.
setParseAction
(
lambda
s
,
l
,
t
:
[
t
.
asList
()])
SETOF
.
setParseAction
(
lambda
s
,
l
,
t
:
[
t
.
asList
()])
choiceValue
.
setParseAction
(
lambda
s
,
l
,
t
:
{
'Choice'
:
t
[
0
].
replace
(
'-'
,
'_'
),
t
[
0
].
replace
(
'-'
,
'_'
):
t
[
2
]})
valuereference
.
setParseAction
(
lambda
s
,
l
,
t
:
{
'Enum'
:
t
[
0
].
replace
(
'-'
,
'_'
)})
ENUM
.
setParseAction
(
lambda
s
,
l
,
t
:
{
'Enum'
:
t
[
0
].
replace
(
'-'
,
'_'
)})
FloatingPointLiteral
.
setParseAction
(
lambda
s
,
l
,
t
:
float
(
t
[
0
]))
INT
.
setParseAction
(
lambda
s
,
l
,
t
:
int
(
t
[
0
]))
TRUE
.
setParseAction
(
lambda
s
,
l
,
t
:
True
)
FALSE
.
setParseAction
(
lambda
s
,
l
,
t
:
False
)
AnyValueLiteral
.
setParseAction
(
lambda
s
,
l
,
t
:
{
'Any'
:
t
[
0
]})
OctetStringLiteral
.
setParseAction
(
lambda
s
,
l
,
t
:
''
.
join
([
chr
(
int
(
t
[
1
][
i
:
i
+
2
],
16
))
for
i
in
range
(
0
,
len
(
t
[
1
]),
2
)]))
# BitString Warning: will only work with series of 8 bits
BitStringLiteral
.
setParseAction
(
lambda
s
,
l
,
t
:
''
.
join
([
chr
(
int
(
t
[
1
][
i
:
i
+
9
],
2
))
for
i
in
range
(
0
,
len
(
t
[
1
]),
2
)]))
NULL
.
setParseAction
(
lambda
s
,
l
,
t
:
"NULL"
)
def
parse_vdm
(
varName
=
'vdm'
,
string
=
''
):
''' Return a variable compatible with the ASN.1 Editor from a VDM string'''
try
:
return
{
varName
:
value
.
parseString
(
string
,
True
)[
0
]}
except
ParseException
as
err
:
print
'[parse_vdm] Parsing error:'
,
string
raise
print
'[parse_vdm] Parsing error:'
,
string
,
str
(
err
)
def
toASN1ValueNotation
(
val
):
''' Create a GSER reprentation of the Python variable '''
result
=
''
def
pyside_to_vdm
(
val
,
sort
=
None
,
ASN1_AST
=
None
):
''' Create a VDM reprentation of the Python variable '''
if
isinstance
(
val
,
dict
):
if
'Choice'
in
val
:
result
+=
val
[
'Choice'
].
replace
(
'_'
,
'-'
).
strip
()
+
':'
result
+=
toASN1ValueNotation
(
val
[
val
[
'Choice'
]])
result
=
pyside_to_vdm
(
val
[
val
[
'Choice'
]])
elif
'Enum'
in
val
:
result
+=
unicode
(
val
[
'Enum'
]).
replace
(
'_'
,
'-'
).
strip
()
else
:
# SEQUENCE and SET
result
+=
' { '
needsComa
=
False
for
seqElem
in
val
:
if
needsComa
:
result
+=
', '
result
+=
seqElem
.
replace
(
'_'
,
'-'
).
strip
()
+
' '
result
+=
toASN1ValueNotation
(
val
[
seqElem
])
needsComa
=
True
result
+=
' }'
result
=
'<{}>'
.
format
(
unicode
(
val
[
'Enum'
]).
strip
())
else
:
# SEQUENCE
# We need the typename XXX
values
=
(
pyside_to_vdm
(
field
)
for
_
,
field
in
val
.
viewitems
())
result
=
'mk_TypeName({})'
.
format
(
', '
.
join
(
values
))
elif
isinstance
(
val
,
list
):
# SEQUENCE OF or SET OF
result
+=
' { '
needsComa
=
False
for
seqOfElem
in
val
:
if
needsComa
:
result
+=
', '
result
+=
toASN1ValueNotation
(
seqOfElem
)
needsComa
=
True
result
+=
' }'
# We need to know the type (SEQOF and SETOF are different in VDM)
values
=
(
pyside_to_vdm
(
item
)
for
item
in
val
)
result
=
'[{}]'
.
format
(
', '
.
join
(
values
))
# SEQ OF
#result = '{{{}}'.format(', '.join(values)) # SET OF
elif
isinstance
(
val
,
bool
):
# boolean are in
upp
er case in
ASN.1
result
+
=
str
(
val
).
upp
er
()
# boolean are in
low
er case in
VDM
result
=
str
(
val
).
low
er
()
elif
isinstance
(
val
,
basestring
):
# Strings: add quotes
, and if string contain non-displayable chars, use repr() to get a visible string
# Strings: add quotes
if
all
(
c
in
string
.
printable
for
c
in
val
):
result
=
'"
'
+
val
+
'"'
result
=
'"
{}"'
.
format
(
val
)
else
:
result
=
'"'
for
c
in
val
:
result
+=
'%02x'
%
ord
(
c
)
result
+=
'"H'
result
=
"ERROR! String with invalid characters"
else
:
result
=
str
(
val
)
# INTEGER and REAL
return
result
def
v
alueNotationToS
wig
(
gser
,
dest
,
sort
,
ASN1Swig
,
ASN1_AST
,
var
=
None
):
''' Parse a
GSER
value and fill a SWIG variable with it
def
v
dm_to_s
wig
(
gser
,
dest
,
sort
,
ASN1Swig
,
ASN1_AST
,
var
=
None
):
''' Parse a
VDM
value and fill a SWIG variable with it
Inputs:
gser : input GSER string
dest : output SWIG instance to be filled
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment