Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
P
parser-fplo
Manage
Activity
Members
Code
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Deploy
Releases
Container registry
Model registry
Analyze
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
This is an archived project. Repository and other project resources are read-only.
Show more breadcrumbs
nomad-lab
parser-fplo
Commits
3f6166e2
Commit
3f6166e2
authored
8 years ago
by
Henning Glawe
Browse files
Options
Downloads
Patches
Plain Diff
AST implementation for declarations / LHS of assignments
parent
215852f7
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
parser/parser-fplo/FploInputParser.py
+152
-1
152 additions, 1 deletion
parser/parser-fplo/FploInputParser.py
with
152 additions
and
1 deletion
parser/parser-fplo/FploInputParser.py
+
152
−
1
View file @
3f6166e2
...
...
@@ -205,6 +205,84 @@ token_bad_input.highlight_start = ANSI.BEGIN_INVERT + ANSI.FG_BRIGHT_RED
token_flag_value
.
highlight_start
=
ANSI
.
FG_MAGENTA
class
AST_node
(
dict
):
"""
base class for abstract syntax tree nodes
"""
def
__init__
(
self
,
name
=
None
):
self
.
name
=
name
self
.
child
=
[]
def
indented_str
(
self
,
indent
=
''
):
result
=
ANSI
.
BG_YELLOW
+
indent
+
ANSI
.
RESET
+
(
'
%-20s
'
%
(
self
.
__class__
.
__name__
))
if
self
.
name
is
not
None
:
result
=
result
+
'
'
+
self
.
name
result
=
result
+
'
\n
'
child_indent
=
indent
+
'
'
for
child
in
self
.
child
:
if
child
is
not
None
:
result
=
result
+
child
.
indented_str
(
child_indent
)
return
result
def
append
(
self
,
newchild
):
self
.
child
.
append
(
newchild
)
def
__len__
(
self
):
return
len
(
self
.
child
)
class
AST_block
(
AST_node
):
"""
generic block (sequence of statements) in AST
"""
def
append_block
(
self
,
src_block
):
for
src_child
in
src_block
.
child
:
self
.
append
(
src_child
)
class
AST_section
(
AST_block
):
"""
section block (sequence of statements) in AST
"""
pass
class
AST_datatype
(
AST_node
):
pass
class
AST_datatype_primitive
(
AST_datatype
):
pass
class
AST_datatype_struct
(
AST_datatype
):
def
__init__
(
self
,
name
=
None
):
AST_datatype
.
__init__
(
self
,
name
=
'
struct
'
)
def
append_block
(
self
,
src_block
):
for
src_child
in
src_block
.
child
:
self
.
append
(
src_child
)
class
AST_declaration
(
AST_node
):
"""
variable declaration in abstract syntax tree
"""
# children:
# 0 - shape
# 1 - datatype
def
__init__
(
self
,
name
,
datatype
,
shape
=
None
):
AST_node
.
__init__
(
self
,
name
)
self
.
child
.
append
(
shape
)
self
.
child
.
append
(
datatype
)
def
set_shape
(
self
,
shape
):
if
self
.
child
[
0
]
is
not
None
:
raise
RuntimeError
(
'
already has shape: %s
'
,
self
.
name
)
self
.
child
[
0
]
=
shape
class
AST_shape
(
AST_node
):
# children are ints without indented_str method
def
indented_str
(
self
,
indent
=
''
):
result
=
ANSI
.
BG_YELLOW
+
indent
+
ANSI
.
RESET
+
(
'
%-20s [
'
%
(
self
.
__class__
.
__name__
))
result
=
result
+
'
,
'
.
join
(
map
(
str
,
self
.
child
))
result
=
result
+
'
]
\n
'
return
result
class
concrete_node
(
object
):
def
__init__
(
self
,
parent
):
self
.
items
=
[]
...
...
@@ -262,6 +340,48 @@ class concrete_statement(concrete_node):
else
:
LOGGER
.
error
(
"
no idea what to do with statement starting with %s
"
,
str
(
self
.
items
[
0
]))
def
to_AST
(
self
):
if
len
(
self
.
items
)
<
1
:
return
None
result
=
None
end_of_declaration
=
0
# check declarations
if
isinstance
(
self
.
items
[
0
],
token_keyword
):
if
self
.
items
[
0
].
value
==
'
section
'
:
result
=
AST_section
(
self
.
items
[
1
].
value
)
# name of section
result
.
append_block
(
self
.
items
[
2
].
to_AST
())
# section-block
end_of_declaration
=
2
if
self
.
items
[
0
].
value
==
'
struct
'
:
struct
=
AST_datatype_struct
()
struct
.
append_block
(
self
.
items
[
1
].
to_AST
())
result
=
AST_declaration
(
self
.
items
[
2
].
value
,
struct
)
end_of_declaration
=
2
elif
isinstance
(
self
.
items
[
0
],
token_datatype
):
primtype
=
AST_datatype_primitive
(
self
.
items
[
0
].
value
)
if
primtype
.
name
==
'
char
'
and
isinstance
(
self
.
items
[
1
],
concrete_subscript
):
# ignore char length for now
# not correct in C, but all declared chars in FPLO input
# are char arrays
declaration_name
=
self
.
items
[
2
].
value
end_of_declaration
=
2
else
:
declaration_name
=
self
.
items
[
1
].
value
end_of_declaration
=
1
result
=
AST_declaration
(
declaration_name
,
primtype
)
if
(
(
len
(
self
.
items
)
-
1
>
end_of_declaration
)
and
isinstance
(
self
.
items
[
end_of_declaration
+
1
],
concrete_subscript
)
):
# subscript in LHS declares shape
if
not
isinstance
(
result
,
AST_declaration
):
raise
RuntimeError
(
'
encountered subscript on non-declaration
'
)
end_of_declaration
=
end_of_declaration
+
1
result
.
set_shape
(
self
.
items
[
end_of_declaration
].
to_AST_shape
())
if
len
(
self
.
items
)
-
1
>
end_of_declaration
:
LOGGER
.
error
(
"
token following declaration: %s
"
,
str
(
self
.
items
[
end_of_declaration
+
1
]))
# else:
# LOGGER.error("token following declaration: None")
return
result
class
concrete_block
(
concrete_node
):
...
...
@@ -271,6 +391,17 @@ class concrete_block(concrete_node):
for
item
in
self
.
items
:
item
.
nomadmetainfo
(
prefix
,
indent
)
def
to_AST
(
self
):
if
len
(
self
.
items
)
<
1
:
return
None
result
=
AST_block
()
for
item
in
self
.
items
:
item_AST
=
item
.
to_AST
()
if
item_AST
is
not
None
:
result
.
append
(
item_AST
)
if
len
(
result
)
is
not
None
:
return
result
return
None
class
concrete_subscript
(
concrete_statement
):
def
__str__
(
self
):
...
...
@@ -289,6 +420,22 @@ class concrete_subscript(concrete_statement):
)
return
"
%10s %s
"
%
(
self
.
__class__
.
__name__
,
result
)
def
to_AST_shape
(
self
):
result
=
AST_shape
()
for
item
in
self
.
items
:
if
isinstance
(
item
,
token_literal
)
and
isinstance
(
item
.
value
,
int
):
result
.
append
(
item
.
value
)
elif
isinstance
(
item
,
token_operator
)
and
item
.
value
==
'
*
'
:
# denote variable-length dimension by -1
result
.
append
(
int
(
-
1
))
elif
isinstance
(
item
,
token_identifier
):
# TODO: check if length from identifier needs to be respected
# for now treat as variable-length
result
.
append
(
int
(
-
1
))
else
:
raise
Exception
(
"
unknown purpose of item in shape: %s
"
%
(
repr
(
item
)))
return
result
class
FploInputParser
(
object
):
"""
Parser for C-like FPLO input
...
...
@@ -396,7 +543,11 @@ class FploInputParser(object):
sys
.
stdout
.
flush
()
sys
.
stderr
.
flush
()
# sys.stderr.write(self.concrete_statements.indented_dump('')) # json.dumps(self.concrete_statements, sort_keys=True, indent=4, separators=(',', ': ')))
self
.
concrete_statements
.
nomadmetainfo
(
'
x_fplo_in
'
,
''
)
# self.concrete_statements.nomadmetainfo('x_fplo_in','')
AST
=
self
.
concrete_statements
.
to_AST
()
sys
.
stderr
.
write
(
'
AST:
\n
'
)
sys
.
stderr
.
flush
()
sys
.
stderr
.
write
(
AST
.
indented_str
(
''
))
if
__name__
==
"
__main__
"
:
parser
=
FploInputParser
(
sys
.
argv
[
1
],
annotateFile
=
sys
.
stdout
)
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
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!
Save comment
Cancel
Please
register
or
sign in
to comment