Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
T
trs
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Taddeüs Kroes
trs
Commits
4ffbcb2c
Commit
4ffbcb2c
authored
Dec 12, 2011
by
Sander Mathijs van Veen
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fixed negation/substraction n-ary bug and added error location tracking.
parent
1dccfdee
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
58 additions
and
30 deletions
+58
-30
external/pybison
external/pybison
+1
-1
src/node.py
src/node.py
+11
-11
src/parser.py
src/parser.py
+46
-18
No files found.
pybison
@
930b44e0
Subproject commit
eb1d1da4c21cc3f48cabe19485381e3f7e80f279
Subproject commit
930b44e0021b0ecac97c37ac8078867b84d09e98
src/node.py
View file @
4ffbcb2c
...
...
@@ -37,10 +37,10 @@ TYPE_MAP = {
str
:
TYPE_IDENTIFIER
,
}
OPT_MAP
=
{
OP_MAP
=
{
'+'
:
OP_ADD
,
'-'
:
OP_SUB
,
# Either substitution or negation. Skip the operator sign in 'x' (= 2).
'-'
:
lambda
x
:
OP_SUB
if
len
(
x
)
>
2
else
OP_NEG
,
'*'
:
OP_MUL
,
'/'
:
OP_DIV
,
'^'
:
OP_POW
,
...
...
@@ -54,7 +54,10 @@ class ExpressionNode(Node):
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
(
ExpressionNode
,
self
).
__init__
(
*
args
,
**
kwargs
)
self
.
type
=
TYPE_OPERATOR
self
.
opt
=
OPT_MAP
[
args
[
0
]]
self
.
op
=
OP_MAP
[
args
[
0
]]
if
hasattr
(
self
.
op
,
'__call__'
):
self
.
op
=
self
.
op
(
args
)
def
__str__
(
self
):
# pragma: nocover
return
generate_line
(
self
)
...
...
@@ -69,10 +72,10 @@ class ExpressionNode(Node):
self
.
parent
=
None
def
is_power
(
self
):
return
self
.
op
t
==
OP_POW
return
self
.
op
==
OP_POW
def
is_nary
(
self
):
return
self
.
op
t
in
[
OP_ADD
,
OP_SUB
,
OP_MUL
]
return
self
.
op
in
[
OP_ADD
,
OP_SUB
,
OP_MUL
]
def
get_order
(
self
):
if
self
.
is_power
()
and
self
[
0
].
is_identifier
()
\
...
...
@@ -91,7 +94,7 @@ class ExpressionNode(Node):
scope
=
[]
for
child
in
self
:
if
not
isinstance
(
child
,
Leaf
)
and
child
.
op
t
==
self
.
opt
:
if
not
isinstance
(
child
,
Leaf
)
and
child
.
op
==
self
.
op
:
scope
+=
child
.
get_scope
()
else
:
scope
.
append
(
child
)
...
...
@@ -103,10 +106,7 @@ class ExpressionLeaf(Leaf):
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
(
ExpressionLeaf
,
self
).
__init__
(
*
args
,
**
kwargs
)
for
data_type
,
type_repr
in
TYPE_MAP
.
iteritems
():
if
isinstance
(
args
[
0
],
data_type
):
self
.
type
=
type_repr
break
self
.
type
=
TYPE_MAP
[
type
(
args
[
0
])]
def
get_order
(
self
):
if
self
.
is_identifier
():
...
...
src/parser.py
View file @
4ffbcb2c
...
...
@@ -19,10 +19,30 @@ sys.path.insert(1, EXTERNAL_MODS)
from
pybison
import
BisonParser
,
BisonSyntaxError
from
graph_drawing.graph
import
generate_graph
from
node
import
TYPE_OPERATOR
,
OP_ADD
,
OP_MUL
,
OP_SUB
,
OP_NEG
# Check for n-ary operator in child nodes
def
combine
(
op
,
n
):
return
n
.
nodes
if
n
.
title
()
==
op
else
[
n
]
def
combine
(
op
,
op_type
,
*
nodes
):
# At least return the operator.
res
=
[
op
]
for
n
in
nodes
:
try
:
assert
n
.
type
!=
TYPE_OPERATOR
or
n
.
op
!=
OP_NEG
or
len
(
n
.
nodes
)
==
1
assert
n
.
type
!=
TYPE_OPERATOR
or
n
.
op
!=
OP_SUB
or
len
(
n
.
nodes
)
>
1
except
AssertionError
:
print
n
,
type
(
n
),
n
.
type
,
OP_NEG
,
OP_SUB
,
n
.
nodes
,
len
(
n
.
nodes
)
raise
# Merge the children for all nodes which have the same operator.
if
n
.
type
==
TYPE_OPERATOR
and
n
.
op
==
op_type
:
res
+=
n
.
nodes
else
:
res
.
append
(
n
)
return
res
class
Parser
(
BisonParser
):
"""
...
...
@@ -68,7 +88,7 @@ class Parser(BisonParser):
return
''
try
:
return
raw_input
(
'>>> '
)
+
'
\
n
'
return
raw_input
(
'>>> '
if
self
.
interactive
else
''
)
+
'
\
n
'
except
EOFError
:
return
''
...
...
@@ -235,15 +255,13 @@ class Parser(BisonParser):
"""
if
option
==
0
:
# rule: exp PLUS exp
return
Node
(
'+'
,
*
(
combine
(
'+'
,
values
[
0
])
+
combine
(
'+'
,
values
[
2
])))
return
Node
(
*
(
combine
(
'+'
,
OP_ADD
,
values
[
0
],
values
[
2
])))
if
option
==
1
:
# rule: exp MINUS exp
return
Node
(
'-'
,
values
[
0
],
values
[
2
]
)
return
Node
(
*
(
combine
(
'-'
,
OP_SUB
,
values
[
0
],
values
[
2
]))
)
if
option
==
2
:
# rule: exp TIMES exp
return
Node
(
'*'
,
*
(
combine
(
'*'
,
values
[
0
])
+
combine
(
'*'
,
values
[
2
])))
return
Node
(
*
(
combine
(
'*'
,
OP_MUL
,
values
[
0
],
values
[
2
])))
if
option
==
3
:
# rule: exp DIVIDE exp
return
Node
(
'/'
,
values
[
0
],
values
[
2
])
...
...
@@ -293,7 +311,6 @@ class Parser(BisonParser):
# -----------------------------------------
lexscript
=
r"""
%{
//int yylineno = 0;
#include "Python.h"
#define YYSTYPE void *
#include "tokens.h"
...
...
@@ -305,9 +322,20 @@ class Parser(BisonParser):
#define YY_INPUT(buf,result,max_size) { \
(*py_input)(py_parser, buf, &result, max_size); \
}
int yycolumn = 0;
#define YY_USER_ACTION \
yylloc.first_line = yylloc.last_line = yylineno; \
yylloc.first_column = yycolumn; \
yylloc.last_column = yycolumn + yyleng; \
yycolumn += yyleng;
/*[a-zA-Z][0-9]+ { returntoken(CONCAT_POW); }*/
%}
%option yylineno
%%
[0-9]+ { returntoken(NUMBER); }
...
...
@@ -320,14 +348,13 @@ class Parser(BisonParser):
"^" { returntoken(POW); }
"/" { returntoken(DIVIDE); }
"," { returntoken(COMMA); }
"quit" {
printf("lex: got QUIT\n");
yyterminate(); returntoken(QUIT); }
"quit" { yyterminate(); returntoken(QUIT); }
"raise" { returntoken(RAISE); }
"graph" { returntoken(GRAPH); }
[ \t\v\f] {}
[\n] {yylineno++; returntoken(NEWLINE); }
. { printf("unknown char %c ignored, yytext=%p\n",
yytext[0], yytext); /* ignore bad chars */}
[ \t\v\f] { }
[\n] { yycolumn = 0; returntoken(NEWLINE); }
. { printf("unknown char %c ignored.\n", yytext[0]); }
%%
...
...
@@ -350,15 +377,16 @@ def get_args():
def
main
():
args
=
get_args
()
interactive
=
not
args
.
batch
and
sys
.
stdin
.
isatty
()
p
=
Parser
(
verbose
=
args
.
verbose
,
keepfiles
=
args
.
keepfiles
,
interactive
=
not
args
.
batch
)
interactive
=
interactive
)
node
=
p
.
run
(
debug
=
args
.
debug
)
# Clear the line, when the shell exits.
if
not
args
.
batch
:
if
interactive
:
print
return
node
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a 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