Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Parser #262

Merged
merged 65 commits into from
Jan 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
483de42
[parser] Initial design concept for a new parser that supports BNF-st…
AntonLydike Dec 8, 2022
8f39dbd
[parser] fixes for some correctnes issues with the parsing and error …
AntonLydike Dec 9, 2022
86fb17c
[parser] basic parsing of operation working
AntonLydike Dec 9, 2022
7de6326
[parser] cleanup of backtracking error reporting
AntonLydike Dec 10, 2022
1f0cecb
[parser] improved region and attribute parsing, building
AntonLydike Dec 10, 2022
0560fde
[parser] fixes true/false switcheroo
AntonLydike Dec 10, 2022
3bdf8aa
[parser] minor fixes in integer and float type parsing
AntonLydike Dec 10, 2022
b5123e8
[parser] yapf formatted to make CI happy
AntonLydike Dec 10, 2022
57091bc
[parser] improve error logging and add docstrings to methods
AntonLydike Dec 12, 2022
d416eff
[parser] Add basics for parsing xDSL
AntonLydike Jan 6, 2023
48b92a1
[parser] separate MLIR and xDSL parsing into two separate classes
AntonLydike Jan 9, 2023
2940b98
[parser] fixed bug in EOL handling for span context printing + order …
AntonLydike Jan 9, 2023
33d59fa
[parser] now able to parse some MLIR and xDSL code successfully
AntonLydike Jan 10, 2023
881f8d0
[parser] clean up lots of unused or unnecessary parts
AntonLydike Jan 10, 2023
280d7ee
[parser] clean up lots of unused or unnecessary parts
AntonLydike Jan 10, 2023
3073039
parser: remove BNF stuff for now
AntonLydike Jan 10, 2023
4464c32
parser: unify code style and apply yapf
AntonLydike Jan 10, 2023
cfd5c62
parser: a lot more cleanup in various places and correctnes fixes
AntonLydike Jan 11, 2023
7f41009
parser: add proper handling of forward references to blocks
AntonLydike Jan 11, 2023
4404ffc
parser: improved compatibility layer to support parsing of cmath.xdsl
AntonLydike Jan 11, 2023
3a06393
parser: fixed a bug with expect_brackets in parse_paramattr_parameters
AntonLydike Jan 12, 2023
7b94084
xdsl: disallow invalid ssa value name hints in the class
AntonLydike Jan 12, 2023
ed3a997
parser: fixing tests to work with the new parser
AntonLydike Jan 13, 2023
34157f5
parser: fixed all remaining tests
AntonLydike Jan 13, 2023
649e43a
parser: yapf formatting run
AntonLydike Jan 13, 2023
a4bb049
parser: fixed xdsl_opt tests
AntonLydike Jan 13, 2023
af8cebf
parser: fix all tests failing after rebase
AntonLydike Jan 17, 2023
64ac94e
parser: run yapf one last time before PR is done
AntonLydike Jan 17, 2023
c51e7a9
tests: fix broken float parsing filecheck
AntonLydike Jan 17, 2023
7782654
parser: fix xdsl-opt command to properly use new parser class
AntonLydike Jan 17, 2023
d77fa27
parser: fix UnregisteredOp interaction with new parser
AntonLydike Jan 17, 2023
b415f6a
parser: add function_type as possible value for parse_attribute
AntonLydike Jan 17, 2023
ba39207
parser: fix parsing of symbol reference
AntonLydike Jan 17, 2023
1e9ccc8
printer: fix printing of strings containing special characters
AntonLydike Jan 17, 2023
e21d7a0
parser: fix some more failing tests
AntonLydike Jan 17, 2023
9365029
parser: add opaque attribute and fix lots of small issues
AntonLydike Jan 18, 2023
684c809
parser+tests: fix module-op at top level error
AntonLydike Jan 18, 2023
c49fc29
parser: added memref support
AntonLydike Jan 18, 2023
0420b56
parser: change type annotations to make python3.11 happy
AntonLydike Jan 18, 2023
b58143a
parser: fixed special attribute-entry parsing for UnitAttr
AntonLydike Jan 18, 2023
58339bc
xdsl: fix how the parser is used in tests
AntonLydike Jan 20, 2023
d0b5a5b
xdsl: fix typo in Block.delcared_at
AntonLydike Jan 20, 2023
41049fe
xdsl: fixed errorneous type hints on DictionaryAttr
AntonLydike Jan 20, 2023
7fda7e0
tests: fix tests that don't wrap their input in a builtin.module
AntonLydike Jan 20, 2023
70ecada
parser: fix a typo
AntonLydike Jan 20, 2023
8e5ce88
parser: add docstring to tokenizer
AntonLydike Jan 20, 2023
6968619
parser: remove BacktrackingAbort
AntonLydike Jan 20, 2023
ebbc7bc
parser: add docstring for BacktrackingHistory
AntonLydike Jan 20, 2023
56490fd
parser: renamed begin_parse to parse_module
AntonLydike Jan 20, 2023
932e403
parser: added return type to get_block_from_name
AntonLydike Jan 20, 2023
4e985cd
parser: fix typos and alignement issues
AntonLydike Jan 23, 2023
ea9a75b
parser: removed get_nth_line_bounds - unused function
AntonLydike Jan 23, 2023
db7c4cb
parser: fix minor nitpicks in tests
AntonLydike Jan 23, 2023
4e27ede
xdsl: revert back to a callable interface for xdsl-opt frontends
AntonLydike Jan 23, 2023
7a40bf2
tests: removed a bunch of unneeded arguments for the parser
AntonLydike Jan 23, 2023
46fee68
parser: move stuff around, fix formatting
AntonLydike Jan 23, 2023
2f09883
parser: uppercase comments
AntonLydike Jan 23, 2023
91a8d12
parser: make a bunch of methods private
AntonLydike Jan 23, 2023
85810fc
tests: clean up imports and unused vars in test_parse_error
AntonLydike Jan 23, 2023
54a7788
tools: removed assertion text - off topic
AntonLydike Jan 23, 2023
9db3804
tests: fix docstring
AntonLydike Jan 23, 2023
868e509
xdsl: removed must_ prefix from parser methods
AntonLydike Jan 23, 2023
de5fa12
formatting: run yapf
AntonLydike Jan 23, 2023
cc67615
formatting: fixed typos and other minor issues
AntonLydike Jan 23, 2023
3c4349a
formatting: yapf run
AntonLydike Jan 23, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions tests/filecheck/parser-printer/float_parsing.xdsl
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@ builtin.module() {
%1 : !f32 = arith.constant() ["value" = -42.0 : !f32]
// CHECK-NEXT: %{{.*}} : !f32 = arith.constant() ["value" = -42.0 : !f32]

%2 : !f32 = arith.constant() ["value" = 34e0 : !f32]
%2 : !f32 = arith.constant() ["value" = 34.e0 : !f32]
// CHECK-NEXT: %{{.*}} : !f32 = arith.constant() ["value" = 34.0 : !f32]

%3 : !f32 = arith.constant() ["value" = 34e-23 : !f32]
%3 : !f32 = arith.constant() ["value" = 34.e-23 : !f32]
// CHECK-NEXT: %{{.*}} : !f32 = arith.constant() ["value" = 3.4e-22 : !f32]

%4 : !f32 = arith.constant() ["value" = 34e12 : !f32]
%4 : !f32 = arith.constant() ["value" = 34.e12 : !f32]
// CHECK-NEXT: %{{.*}} : !f32 = arith.constant() ["value" = 34000000000000.0 : !f32]

%5 : !f32 = arith.constant() ["value" = -34e-12 : !f32]
%5 : !f32 = arith.constant() ["value" = -34.e-12 : !f32]
// CHECK-NEXT: %{{.*}} : !f32 = arith.constant() ["value" = -3.4e-11 : !f32]

func.return()
Expand Down
12 changes: 6 additions & 6 deletions tests/test_attribute_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from xdsl.ir import ParametrizedAttribute, Data
from xdsl.irdl import irdl_attr_definition, builder
from xdsl.parser import Parser
from xdsl.parser import BaseParser
from xdsl.printer import Printer
from xdsl.utils.exceptions import BuilderNotFoundException

Expand Down Expand Up @@ -34,7 +34,7 @@ def from_int(data: int) -> OneBuilderAttr:
return OneBuilderAttr(str(data))

@staticmethod
def parse_parameter(parser: Parser) -> str:
def parse_parameter(parser: BaseParser) -> str:
raise NotImplementedError()

@staticmethod
Expand Down Expand Up @@ -72,7 +72,7 @@ def from_int(data1: int, data2: str) -> OneBuilderAttr:
return OneBuilderAttr(str(data1) + data2)

@staticmethod
def parse_parameter(parser: Parser) -> str:
def parse_parameter(parser: BaseParser) -> str:
raise NotImplementedError()

@staticmethod
Expand Down Expand Up @@ -105,7 +105,7 @@ def from_str(s: str) -> TwoBuildersAttr:
return TwoBuildersAttr(s)

@staticmethod
def parse_parameter(parser: Parser) -> str:
def parse_parameter(parser: BaseParser) -> str:
raise NotImplementedError()

@staticmethod
Expand Down Expand Up @@ -145,7 +145,7 @@ def from_int(data1: int,
return BuilderDefaultArgAttr(f"{data1}, {data2}, {data3}")

@staticmethod
def parse_parameter(parser: Parser) -> str:
def parse_parameter(parser: BaseParser) -> str:
raise NotImplementedError()

@staticmethod
Expand Down Expand Up @@ -188,7 +188,7 @@ def from_int(data: str | int) -> BuilderUnionArgAttr:
return BuilderUnionArgAttr(str(data))

@staticmethod
def parse_parameter(parser: Parser) -> str:
def parse_parameter(parser: BaseParser) -> str:
raise NotImplementedError()

@staticmethod
Expand Down
27 changes: 13 additions & 14 deletions tests/test_attribute_definition.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from xdsl.irdl import (AttrConstraint, GenericData, ParameterDef,
irdl_attr_definition, builder, irdl_to_attr_constraint,
AnyAttr, BaseAttr, ParamAttrDef)
from xdsl.parser import Parser
from xdsl.parser import BaseParser
from xdsl.printer import Printer
from xdsl.utils.exceptions import VerifyException

Expand All @@ -31,14 +31,13 @@ class BoolData(Data[bool]):
name = "bool"

@staticmethod
def parse_parameter(parser: Parser) -> bool:
val = parser.parse_optional_ident()
if val == "True":
def parse_parameter(parser: BaseParser) -> bool:
val = parser.tokenizer.next_token_of_pattern('(True|False)')
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest having code like

if parser.parse_optional_string("True") is not None:
    ...
parser.parse_string("False")
...

Which is what MLIR people usually write, and to me makes more sense in that case (since we only have 2 cases).
However, we should definitely keep the regex for other use cases.

if val is None or val.text not in ('True', 'False'):
parser.raise_error("Expected True or False literal")
if val.text == "True":
return True
elif val == "False":
return False
else:
raise Exception("Wrong argument passed to BoolAttr.")
return False

@staticmethod
def print_parameter(data: bool, printer: Printer):
Expand All @@ -51,7 +50,7 @@ class IntData(Data[int]):
name = "int"

@staticmethod
def parse_parameter(parser: Parser) -> int:
def parse_parameter(parser: BaseParser) -> int:
return parser.parse_int_literal()

@staticmethod
Expand All @@ -65,7 +64,7 @@ class StringData(Data[str]):
name = "str"

@staticmethod
def parse_parameter(parser: Parser) -> str:
def parse_parameter(parser: BaseParser) -> str:
return parser.parse_str_literal()

@staticmethod
Expand Down Expand Up @@ -102,7 +101,7 @@ class IntListMissingVerifierData(Data[list[int]]):
name = "missing_verifier_data"

@staticmethod
def parse_parameter(parser: Parser) -> list[int]:
def parse_parameter(parser: BaseParser) -> list[int]:
raise NotImplementedError()

@staticmethod
Expand Down Expand Up @@ -134,7 +133,7 @@ class IntListData(Data[list[int]]):
name = "int_list"

@staticmethod
def parse_parameter(parser: Parser) -> list[int]:
def parse_parameter(parser: BaseParser) -> list[int]:
raise NotImplementedError()

@staticmethod
Expand Down Expand Up @@ -431,7 +430,7 @@ class MissingGenericDataData(Data[_MissingGenericDataData]):
name = "missing_genericdata"

@staticmethod
def parse_parameter(parser: Parser) -> _MissingGenericDataData:
def parse_parameter(parser: BaseParser) -> _MissingGenericDataData:
raise NotImplementedError()

@staticmethod
Expand Down Expand Up @@ -484,7 +483,7 @@ class ListData(GenericData[list[A]]):
name = "list"

@staticmethod
def parse_parameter(parser: Parser) -> list[A]:
def parse_parameter(parser: BaseParser) -> list[A]:
raise NotImplementedError()

@staticmethod
Expand Down
10 changes: 5 additions & 5 deletions tests/test_ir.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from xdsl.dialects.arith import Addi, Subi, Constant
from xdsl.dialects.builtin import i32, IntegerAttr, ModuleOp
from xdsl.dialects.scf import If
from xdsl.parser import Parser
from xdsl.parser import XDSLParser
from xdsl.dialects.builtin import Builtin
from xdsl.dialects.func import Func
from xdsl.dialects.arith import Arith
Expand Down Expand Up @@ -203,10 +203,10 @@ def test_is_structurally_equivalent(args: list[str], expected_result: bool):
ctx.register_dialect(Arith)
ctx.register_dialect(Cf)

parser = Parser(ctx, args[0])
parser = XDSLParser(ctx, args[0])
lhs: Operation = parser.parse_op()

parser = Parser(ctx, args[1])
parser = XDSLParser(ctx, args[1])
rhs: Operation = parser.parse_op()

assert lhs.is_structurally_equivalent(rhs) == expected_result
Expand All @@ -231,8 +231,8 @@ def test_is_structurally_equivalent_incompatible_ir_nodes():
ctx.register_dialect(Arith)
ctx.register_dialect(Cf)

parser = Parser(ctx, program_func)
program: ModuleOp = parser.parse_op()
parser = XDSLParser(ctx, program_func)
program: ModuleOp = parser.parse_operation()

assert program.is_structurally_equivalent(program.regions[0]) == False
assert program.is_structurally_equivalent(
Expand Down
6 changes: 3 additions & 3 deletions tests/test_irdl.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

from xdsl.ir import Attribute, Data, ParametrizedAttribute
from xdsl.irdl import AllOf, AnyAttr, AnyOf, AttrConstraint, BaseAttr, EqAttrConstraint, ParamAttrConstraint, ParameterDef, irdl_attr_definition
from xdsl.parser import Parser
from xdsl.parser import BaseParser
from xdsl.printer import Printer
from xdsl.utils.exceptions import VerifyException

Expand All @@ -16,7 +16,7 @@ class BoolData(Data[bool]):
name = "bool"

@staticmethod
def parse_parameter(parser: Parser) -> bool:
def parse_parameter(parser: BaseParser) -> bool:
raise NotImplementedError()

@staticmethod
Expand All @@ -30,7 +30,7 @@ class IntData(Data[int]):
name = "int"

@staticmethod
def parse_parameter(parser: Parser) -> int:
def parse_parameter(parser: BaseParser) -> int:
return parser.parse_int_literal()

@staticmethod
Expand Down
4 changes: 2 additions & 2 deletions tests/test_mlir_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from xdsl.dialects.affine import Affine
from xdsl.dialects.arith import Arith

from xdsl.parser import Parser
from xdsl.parser import XDSLParser
from xdsl.ir import MLContext
from xdsl.dialects.builtin import Builtin

Expand All @@ -23,7 +23,7 @@ def convert_and_verify(test_prog: str):
ctx.register_dialect(Scf)
ctx.register_dialect(MemRef)

parser = Parser(ctx, test_prog)
parser = XDSLParser(ctx, test_prog)
module = parser.parse_op()
module.verify()

Expand Down
19 changes: 8 additions & 11 deletions tests/test_mlir_printer.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import re
from io import StringIO
from typing import Annotated
import re

from xdsl.dialects.builtin import Builtin
from xdsl.dialects.memref import MemRef
from xdsl.dialects.func import Func
from xdsl.ir import Attribute, Data, MLContext, MLIRType, Operation, ParametrizedAttribute
from xdsl.irdl import (AnyAttr, ParameterDef, RegionDef, VarOpResult,
VarOperand, irdl_attr_definition, irdl_op_definition)
from xdsl.parser import Parser
from xdsl.irdl import (AnyAttr, ParameterDef, RegionDef, irdl_attr_definition,
irdl_op_definition, VarOperand, VarOpResult)
from xdsl.parser import BaseParser, XDSLParser
from xdsl.printer import Printer


Expand All @@ -33,7 +30,7 @@ class DataAttr(Data[int]):
name = "data_attr"

@staticmethod
def parse_parameter(parser: Parser) -> int:
def parse_parameter(parser: BaseParser) -> int:
return parser.parse_int_literal()

@staticmethod
Expand All @@ -47,7 +44,7 @@ class DataType(Data[int], MLIRType):
name = "data_type"

@staticmethod
def parse_parameter(parser: Parser) -> int:
def parse_parameter(parser: BaseParser) -> int:
return parser.parse_int_literal()

@staticmethod
Expand Down Expand Up @@ -92,8 +89,8 @@ def print_as_mlir_and_compare(test_prog: str, expected: str):
ctx.register_attr(ParamAttrWithParam)
ctx.register_attr(ParamAttrWithCustomFormat)

parser = Parser(ctx, test_prog)
module = parser.parse_op()
parser = XDSLParser(ctx, test_prog)
module = parser.parse_operation()

res = StringIO()
printer = Printer(target=Printer.Target.MLIR, stream=res)
Expand Down
58 changes: 32 additions & 26 deletions tests/test_parser.py
Original file line number Diff line number Diff line change
@@ -1,37 +1,43 @@
from io import StringIO

import pytest

from xdsl.ir import MLContext
from xdsl.parser import Parser
from xdsl.printer import Printer
from xdsl.ir import MLContext, Attribute
from xdsl.parser import XDSLParser
from xdsl.dialects.builtin import IntAttr, DictionaryAttr, StringAttr, ArrayAttr, Builtin


@pytest.mark.parametrize("input,expected", [("0, 1, 1", [0, 1, 1]),
("1, 0, 1", [1, 0, 1]),
("1, 1, 0", [1, 1, 0])])
def test_int_list_parser(input: str, expected: list[int]):
ctx = MLContext()
parser = Parser(ctx, input)

int_list = parser.parse_list(parser.parse_int_literal)
assert int_list == expected


@pytest.mark.parametrize("input,expected", [('{"A"=0, "B"=1, "C"=2}', {
"A": 0,
"B": 1,
"C": 2
}), ('{"MA"=10, "BR"=7, "Z"=3}', {
"MA": 10,
"BR": 7,
"Z": 3
}), ('{"Q"=77, "VV"=12, "AA"=-8}', {
"Q": 77,
"VV": 12,
"AA": -8
})])
def test_int_dictionary_parser(input: str, expected: dict[str, int]):
parser = XDSLParser(ctx, input)

int_list = parser.parse_list_of(parser.try_parse_integer_literal, '')
assert [int(span.text) for span in int_list] == expected


@pytest.mark.parametrize('data', [
dict(a=IntAttr.from_int(1), b=IntAttr.from_int(2), c=IntAttr.from_int(3)),
dict(a=StringAttr.from_str('hello'),
b=IntAttr.from_int(2),
c=ArrayAttr.from_list(
[IntAttr.from_int(2),
StringAttr.from_str('world')])),
dict(),
])
def test_dictionary_attr(data: dict[str, Attribute]):
attr = DictionaryAttr.from_dict(data)

with StringIO() as io:
Printer(io).print(attr)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this makes sense as this makes the Parser tests depend on the Printer. I feel that parser tests should really take strings and the data structure that is expected in order to test.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Valid point. I'll change that

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just noticed that most of the printer tests rely on the parser as well. What's up with that? Why is that more okay?

text = io.getvalue()

ctx = MLContext()
parser = Parser(ctx, input)
ctx.register_dialect(Builtin)

attr = XDSLParser(ctx, text).parse_attribute()

int_dict = parser.parse_dictionary(parser.parse_str_literal,
parser.parse_int_literal)
assert int_dict == expected
assert attr.data == data
Loading