summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJuergen Bocklage-Ryannel <juergen.bocklage-ryannel@pelagicore.com>2017-04-03 20:30:31 +0200
committerJuergen Bocklage-Ryannel <juergen.bocklage-ryannel@pelagicore.com>2017-04-03 20:30:31 +0200
commit4b99d5ebd4727b3394a52c251bbce84b1ce1cf4f (patch)
treeddecfcddf1fe117c2d6f39408a87cffafa08befc
parented428a06bbd665e4fe97ffc02a81620c5676e424 (diff)
parent808254b0c88d2bc7672cf01891a9f774bea641a7 (diff)
downloadqtivi-qface-4b99d5ebd4727b3394a52c251bbce84b1ce1cf4f.tar.gz
Merge branch 'release/1.1'1.1
-rw-r--r--LICENSE21
-rw-r--r--LICENSE.GPLV3684
-rw-r--r--README.md2
-rwxr-xr-xcli.py13
-rw-r--r--docs/annotations.rst87
-rw-r--r--docs/grammar.rst71
-rw-r--r--docs/index.rst2
-rw-r--r--docs/yaml.rst139
-rw-r--r--qface/__about__.py2
-rwxr-xr-xqface/builtin/qtcpp/qtcpp.py4
-rw-r--r--qface/builtin/qtcpp/templates/abstractinterface.h2
-rw-r--r--qface/builtin/qtcpp/templates/interface.h2
-rw-r--r--qface/builtin/qtcpp/templates/module.h2
-rw-r--r--qface/builtin/qtcpp/templates/structmodel.h2
-rw-r--r--qface/builtin/qtcpp/templates/variantmodel.h2
-rwxr-xr-xqface/builtin/qtqml/qtqml.py4
-rw-r--r--qface/generator.py18
-rw-r--r--qface/idl/domain.py6
-rw-r--r--qface/idl/listener.py43
-rw-r--r--qface/idl/parser/T.g45
-rw-r--r--qface/idl/parser/T.tokens19
-rw-r--r--qface/idl/parser/TLexer.py244
-rw-r--r--qface/idl/parser/TLexer.tokens19
-rw-r--r--qface/idl/parser/TParser.py496
-rw-r--r--qface/utils.py10
-rw-r--r--qface/watch.py15
-rw-r--r--requirements.txt1
-rw-r--r--setup.py1
-rw-r--r--tests/in/com.pelagicore.ivi.tuner.qface8
-rw-r--r--tests/in/com.pelagicore.ivi.tuner.yaml6
-rw-r--r--tests/in/com.pelagicore.test.qface2
-rw-r--r--tests/test_comments.py2
-rw-r--r--tests/test_parser.py2
-rw-r--r--tests/test_tags.py15
34 files changed, 779 insertions, 1172 deletions
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..c5dc4ac
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2017 Pelagicore AG
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/LICENSE.GPLV3 b/LICENSE.GPLV3
deleted file mode 100644
index 846b5ed..0000000
--- a/LICENSE.GPLV3
+++ /dev/null
@@ -1,684 +0,0 @@
- GNU GENERAL PUBLIC LICENSE
-
- QFace is Copyright (C) 2016 Pelagicore AB
- Contact: http://www.pelagicore.com/
-
- You may use, distribute and copy QFace under the terms of the
- GNU General Public License version 3, which is displayed below.
-
--------------------------------------------------------------------------
-
- GNU GENERAL PUBLIC LICENSE
- Version 3, 29 June 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The GNU General Public License is a free, copyleft license for
-software and other kinds of works.
-
- The licenses for most software and other practical works are designed
-to take away your freedom to share and change the works. By contrast,
-the GNU General Public License is intended to guarantee your freedom to
-share and change all versions of a program--to make sure it remains free
-software for all its users. We, the Free Software Foundation, use the
-GNU General Public License for most of our software; it applies also to
-any other work released this way by its authors. You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-them if you wish), that you receive source code or can get it if you
-want it, that you can change the software or use pieces of it in new
-free programs, and that you know you can do these things.
-
- To protect your rights, we need to prevent others from denying you
-these rights or asking you to surrender the rights. Therefore, you have
-certain responsibilities if you distribute copies of the software, or if
-you modify it: responsibilities to respect the freedom of others.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must pass on to the recipients the same
-freedoms that you received. You must make sure that they, too, receive
-or can get the source code. And you must show them these terms so they
-know their rights.
-
- Developers that use the GNU GPL protect your rights with two steps:
-(1) assert copyright on the software, and (2) offer you this License
-giving you legal permission to copy, distribute and/or modify it.
-
- For the developers' and authors' protection, the GPL clearly explains
-that there is no warranty for this free software. For both users' and
-authors' sake, the GPL requires that modified versions be marked as
-changed, so that their problems will not be attributed erroneously to
-authors of previous versions.
-
- Some devices are designed to deny users access to install or run
-modified versions of the software inside them, although the manufacturer
-can do so. This is fundamentally incompatible with the aim of
-protecting users' freedom to change the software. The systematic
-pattern of such abuse occurs in the area of products for individuals to
-use, which is precisely where it is most unacceptable. Therefore, we
-have designed this version of the GPL to prohibit the practice for those
-products. If such problems arise substantially in other domains, we
-stand ready to extend this provision to those domains in future versions
-of the GPL, as needed to protect the freedom of users.
-
- Finally, every program is threatened constantly by software patents.
-States should not allow patents to restrict development and use of
-software on general-purpose computers, but in those that do, we wish to
-avoid the special danger that patents applied to a free program could
-make it effectively proprietary. To prevent this, the GPL assures that
-patents cannot be used to render the program non-free.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- TERMS AND CONDITIONS
-
- 0. Definitions.
-
- "This License" refers to version 3 of the GNU General Public License.
-
- "Copyright" also means copyright-like laws that apply to other kinds of
-works, such as semiconductor masks.
-
- "The Program" refers to any copyrightable work licensed under this
-License. Each licensee is addressed as "you". "Licensees" and
-"recipients" may be individuals or organizations.
-
- To "modify" a work means to copy from or adapt all or part of the work
-in a fashion requiring copyright permission, other than the making of an
-exact copy. The resulting work is called a "modified version" of the
-earlier work or a work "based on" the earlier work.
-
- A "covered work" means either the unmodified Program or a work based
-on the Program.
-
- To "propagate" a work means to do anything with it that, without
-permission, would make you directly or secondarily liable for
-infringement under applicable copyright law, except executing it on a
-computer or modifying a private copy. Propagation includes copying,
-distribution (with or without modification), making available to the
-public, and in some countries other activities as well.
-
- To "convey" a work means any kind of propagation that enables other
-parties to make or receive copies. Mere interaction with a user through
-a computer network, with no transfer of a copy, is not conveying.
-
- An interactive user interface displays "Appropriate Legal Notices"
-to the extent that it includes a convenient and prominently visible
-feature that (1) displays an appropriate copyright notice, and (2)
-tells the user that there is no warranty for the work (except to the
-extent that warranties are provided), that licensees may convey the
-work under this License, and how to view a copy of this License. If
-the interface presents a list of user commands or options, such as a
-menu, a prominent item in the list meets this criterion.
-
- 1. Source Code.
-
- The "source code" for a work means the preferred form of the work
-for making modifications to it. "Object code" means any non-source
-form of a work.
-
- A "Standard Interface" means an interface that either is an official
-standard defined by a recognized standards body, or, in the case of
-interfaces specified for a particular programming language, one that
-is widely used among developers working in that language.
-
- The "System Libraries" of an executable work include anything, other
-than the work as a whole, that (a) is included in the normal form of
-packaging a Major Component, but which is not part of that Major
-Component, and (b) serves only to enable use of the work with that
-Major Component, or to implement a Standard Interface for which an
-implementation is available to the public in source code form. A
-"Major Component", in this context, means a major essential component
-(kernel, window system, and so on) of the specific operating system
-(if any) on which the executable work runs, or a compiler used to
-produce the work, or an object code interpreter used to run it.
-
- The "Corresponding Source" for a work in object code form means all
-the source code needed to generate, install, and (for an executable
-work) run the object code and to modify the work, including scripts to
-control those activities. However, it does not include the work's
-System Libraries, or general-purpose tools or generally available free
-programs which are used unmodified in performing those activities but
-which are not part of the work. For example, Corresponding Source
-includes interface definition files associated with source files for
-the work, and the source code for shared libraries and dynamically
-linked subprograms that the work is specifically designed to require,
-such as by intimate data communication or control flow between those
-subprograms and other parts of the work.
-
- The Corresponding Source need not include anything that users
-can regenerate automatically from other parts of the Corresponding
-Source.
-
- The Corresponding Source for a work in source code form is that
-same work.
-
- 2. Basic Permissions.
-
- All rights granted under this License are granted for the term of
-copyright on the Program, and are irrevocable provided the stated
-conditions are met. This License explicitly affirms your unlimited
-permission to run the unmodified Program. The output from running a
-covered work is covered by this License only if the output, given its
-content, constitutes a covered work. This License acknowledges your
-rights of fair use or other equivalent, as provided by copyright law.
-
- You may make, run and propagate covered works that you do not
-convey, without conditions so long as your license otherwise remains
-in force. You may convey covered works to others for the sole purpose
-of having them make modifications exclusively for you, or provide you
-with facilities for running those works, provided that you comply with
-the terms of this License in conveying all material for which you do
-not control copyright. Those thus making or running the covered works
-for you must do so exclusively on your behalf, under your direction
-and control, on terms that prohibit them from making any copies of
-your copyrighted material outside their relationship with you.
-
- Conveying under any other circumstances is permitted solely under
-the conditions stated below. Sublicensing is not allowed; section 10
-makes it unnecessary.
-
- 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
-
- No covered work shall be deemed part of an effective technological
-measure under any applicable law fulfilling obligations under article
-11 of the WIPO copyright treaty adopted on 20 December 1996, or
-similar laws prohibiting or restricting circumvention of such
-measures.
-
- When you convey a covered work, you waive any legal power to forbid
-circumvention of technological measures to the extent such circumvention
-is effected by exercising rights under this License with respect to
-the covered work, and you disclaim any intention to limit operation or
-modification of the work as a means of enforcing, against the work's
-users, your or third parties' legal rights to forbid circumvention of
-technological measures.
-
- 4. Conveying Verbatim Copies.
-
- You may convey verbatim copies of the Program's source code as you
-receive it, in any medium, provided that you conspicuously and
-appropriately publish on each copy an appropriate copyright notice;
-keep intact all notices stating that this License and any
-non-permissive terms added in accord with section 7 apply to the code;
-keep intact all notices of the absence of any warranty; and give all
-recipients a copy of this License along with the Program.
-
- You may charge any price or no price for each copy that you convey,
-and you may offer support or warranty protection for a fee.
-
- 5. Conveying Modified Source Versions.
-
- You may convey a work based on the Program, or the modifications to
-produce it from the Program, in the form of source code under the
-terms of section 4, provided that you also meet all of these conditions:
-
- a) The work must carry prominent notices stating that you modified
- it, and giving a relevant date.
-
- b) The work must carry prominent notices stating that it is
- released under this License and any conditions added under section
- 7. This requirement modifies the requirement in section 4 to
- "keep intact all notices".
-
- c) You must license the entire work, as a whole, under this
- License to anyone who comes into possession of a copy. This
- License will therefore apply, along with any applicable section 7
- additional terms, to the whole of the work, and all its parts,
- regardless of how they are packaged. This License gives no
- permission to license the work in any other way, but it does not
- invalidate such permission if you have separately received it.
-
- d) If the work has interactive user interfaces, each must display
- Appropriate Legal Notices; however, if the Program has interactive
- interfaces that do not display Appropriate Legal Notices, your
- work need not make them do so.
-
- A compilation of a covered work with other separate and independent
-works, which are not by their nature extensions of the covered work,
-and which are not combined with it such as to form a larger program,
-in or on a volume of a storage or distribution medium, is called an
-"aggregate" if the compilation and its resulting copyright are not
-used to limit the access or legal rights of the compilation's users
-beyond what the individual works permit. Inclusion of a covered work
-in an aggregate does not cause this License to apply to the other
-parts of the aggregate.
-
- 6. Conveying Non-Source Forms.
-
- You may convey a covered work in object code form under the terms
-of sections 4 and 5, provided that you also convey the
-machine-readable Corresponding Source under the terms of this License,
-in one of these ways:
-
- a) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by the
- Corresponding Source fixed on a durable physical medium
- customarily used for software interchange.
-
- b) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by a
- written offer, valid for at least three years and valid for as
- long as you offer spare parts or customer support for that product
- model, to give anyone who possesses the object code either (1) a
- copy of the Corresponding Source for all the software in the
- product that is covered by this License, on a durable physical
- medium customarily used for software interchange, for a price no
- more than your reasonable cost of physically performing this
- conveying of source, or (2) access to copy the
- Corresponding Source from a network server at no charge.
-
- c) Convey individual copies of the object code with a copy of the
- written offer to provide the Corresponding Source. This
- alternative is allowed only occasionally and noncommercially, and
- only if you received the object code with such an offer, in accord
- with subsection 6b.
-
- d) Convey the object code by offering access from a designated
- place (gratis or for a charge), and offer equivalent access to the
- Corresponding Source in the same way through the same place at no
- further charge. You need not require recipients to copy the
- Corresponding Source along with the object code. If the place to
- copy the object code is a network server, the Corresponding Source
- may be on a different server (operated by you or a third party)
- that supports equivalent copying facilities, provided you maintain
- clear directions next to the object code saying where to find the
- Corresponding Source. Regardless of what server hosts the
- Corresponding Source, you remain obligated to ensure that it is
- available for as long as needed to satisfy these requirements.
-
- e) Convey the object code using peer-to-peer transmission, provided
- you inform other peers where the object code and Corresponding
- Source of the work are being offered to the general public at no
- charge under subsection 6d.
-
- A separable portion of the object code, whose source code is excluded
-from the Corresponding Source as a System Library, need not be
-included in conveying the object code work.
-
- A "User Product" is either (1) a "consumer product", which means any
-tangible personal property which is normally used for personal, family,
-or household purposes, or (2) anything designed or sold for incorporation
-into a dwelling. In determining whether a product is a consumer product,
-doubtful cases shall be resolved in favor of coverage. For a particular
-product received by a particular user, "normally used" refers to a
-typical or common use of that class of product, regardless of the status
-of the particular user or of the way in which the particular user
-actually uses, or expects or is expected to use, the product. A product
-is a consumer product regardless of whether the product has substantial
-commercial, industrial or non-consumer uses, unless such uses represent
-the only significant mode of use of the product.
-
- "Installation Information" for a User Product means any methods,
-procedures, authorization keys, or other information required to install
-and execute modified versions of a covered work in that User Product from
-a modified version of its Corresponding Source. The information must
-suffice to ensure that the continued functioning of the modified object
-code is in no case prevented or interfered with solely because
-modification has been made.
-
- If you convey an object code work under this section in, or with, or
-specifically for use in, a User Product, and the conveying occurs as
-part of a transaction in which the right of possession and use of the
-User Product is transferred to the recipient in perpetuity or for a
-fixed term (regardless of how the transaction is characterized), the
-Corresponding Source conveyed under this section must be accompanied
-by the Installation Information. But this requirement does not apply
-if neither you nor any third party retains the ability to install
-modified object code on the User Product (for example, the work has
-been installed in ROM).
-
- The requirement to provide Installation Information does not include a
-requirement to continue to provide support service, warranty, or updates
-for a work that has been modified or installed by the recipient, or for
-the User Product in which it has been modified or installed. Access to a
-network may be denied when the modification itself materially and
-adversely affects the operation of the network or violates the rules and
-protocols for communication across the network.
-
- Corresponding Source conveyed, and Installation Information provided,
-in accord with this section must be in a format that is publicly
-documented (and with an implementation available to the public in
-source code form), and must require no special password or key for
-unpacking, reading or copying.
-
- 7. Additional Terms.
-
- "Additional permissions" are terms that supplement the terms of this
-License by making exceptions from one or more of its conditions.
-Additional permissions that are applicable to the entire Program shall
-be treated as though they were included in this License, to the extent
-that they are valid under applicable law. If additional permissions
-apply only to part of the Program, that part may be used separately
-under those permissions, but the entire Program remains governed by
-this License without regard to the additional permissions.
-
- When you convey a copy of a covered work, you may at your option
-remove any additional permissions from that copy, or from any part of
-it. (Additional permissions may be written to require their own
-removal in certain cases when you modify the work.) You may place
-additional permissions on material, added by you to a covered work,
-for which you have or can give appropriate copyright permission.
-
- Notwithstanding any other provision of this License, for material you
-add to a covered work, you may (if authorized by the copyright holders of
-that material) supplement the terms of this License with terms:
-
- a) Disclaiming warranty or limiting liability differently from the
- terms of sections 15 and 16 of this License; or
-
- b) Requiring preservation of specified reasonable legal notices or
- author attributions in that material or in the Appropriate Legal
- Notices displayed by works containing it; or
-
- c) Prohibiting misrepresentation of the origin of that material, or
- requiring that modified versions of such material be marked in
- reasonable ways as different from the original version; or
-
- d) Limiting the use for publicity purposes of names of licensors or
- authors of the material; or
-
- e) Declining to grant rights under trademark law for use of some
- trade names, trademarks, or service marks; or
-
- f) Requiring indemnification of licensors and authors of that
- material by anyone who conveys the material (or modified versions of
- it) with contractual assumptions of liability to the recipient, for
- any liability that these contractual assumptions directly impose on
- those licensors and authors.
-
- All other non-permissive additional terms are considered "further
-restrictions" within the meaning of section 10. If the Program as you
-received it, or any part of it, contains a notice stating that it is
-governed by this License along with a term that is a further
-restriction, you may remove that term. If a license document contains
-a further restriction but permits relicensing or conveying under this
-License, you may add to a covered work material governed by the terms
-of that license document, provided that the further restriction does
-not survive such relicensing or conveying.
-
- If you add terms to a covered work in accord with this section, you
-must place, in the relevant source files, a statement of the
-additional terms that apply to those files, or a notice indicating
-where to find the applicable terms.
-
- Additional terms, permissive or non-permissive, may be stated in the
-form of a separately written license, or stated as exceptions;
-the above requirements apply either way.
-
- 8. Termination.
-
- You may not propagate or modify a covered work except as expressly
-provided under this License. Any attempt otherwise to propagate or
-modify it is void, and will automatically terminate your rights under
-this License (including any patent licenses granted under the third
-paragraph of section 11).
-
- However, if you cease all violation of this License, then your
-license from a particular copyright holder is reinstated (a)
-provisionally, unless and until the copyright holder explicitly and
-finally terminates your license, and (b) permanently, if the copyright
-holder fails to notify you of the violation by some reasonable means
-prior to 60 days after the cessation.
-
- Moreover, your license from a particular copyright holder is
-reinstated permanently if the copyright holder notifies you of the
-violation by some reasonable means, this is the first time you have
-received notice of violation of this License (for any work) from that
-copyright holder, and you cure the violation prior to 30 days after
-your receipt of the notice.
-
- Termination of your rights under this section does not terminate the
-licenses of parties who have received copies or rights from you under
-this License. If your rights have been terminated and not permanently
-reinstated, you do not qualify to receive new licenses for the same
-material under section 10.
-
- 9. Acceptance Not Required for Having Copies.
-
- You are not required to accept this License in order to receive or
-run a copy of the Program. Ancillary propagation of a covered work
-occurring solely as a consequence of using peer-to-peer transmission
-to receive a copy likewise does not require acceptance. However,
-nothing other than this License grants you permission to propagate or
-modify any covered work. These actions infringe copyright if you do
-not accept this License. Therefore, by modifying or propagating a
-covered work, you indicate your acceptance of this License to do so.
-
- 10. Automatic Licensing of Downstream Recipients.
-
- Each time you convey a covered work, the recipient automatically
-receives a license from the original licensors, to run, modify and
-propagate that work, subject to this License. You are not responsible
-for enforcing compliance by third parties with this License.
-
- An "entity transaction" is a transaction transferring control of an
-organization, or substantially all assets of one, or subdividing an
-organization, or merging organizations. If propagation of a covered
-work results from an entity transaction, each party to that
-transaction who receives a copy of the work also receives whatever
-licenses to the work the party's predecessor in interest had or could
-give under the previous paragraph, plus a right to possession of the
-Corresponding Source of the work from the predecessor in interest, if
-the predecessor has it or can get it with reasonable efforts.
-
- You may not impose any further restrictions on the exercise of the
-rights granted or affirmed under this License. For example, you may
-not impose a license fee, royalty, or other charge for exercise of
-rights granted under this License, and you may not initiate litigation
-(including a cross-claim or counterclaim in a lawsuit) alleging that
-any patent claim is infringed by making, using, selling, offering for
-sale, or importing the Program or any portion of it.
-
- 11. Patents.
-
- A "contributor" is a copyright holder who authorizes use under this
-License of the Program or a work on which the Program is based. The
-work thus licensed is called the contributor's "contributor version".
-
- A contributor's "essential patent claims" are all patent claims
-owned or controlled by the contributor, whether already acquired or
-hereafter acquired, that would be infringed by some manner, permitted
-by this License, of making, using, or selling its contributor version,
-but do not include claims that would be infringed only as a
-consequence of further modification of the contributor version. For
-purposes of this definition, "control" includes the right to grant
-patent sublicenses in a manner consistent with the requirements of
-this License.
-
- Each contributor grants you a non-exclusive, worldwide, royalty-free
-patent license under the contributor's essential patent claims, to
-make, use, sell, offer for sale, import and otherwise run, modify and
-propagate the contents of its contributor version.
-
- In the following three paragraphs, a "patent license" is any express
-agreement or commitment, however denominated, not to enforce a patent
-(such as an express permission to practice a patent or covenant not to
-sue for patent infringement). To "grant" such a patent license to a
-party means to make such an agreement or commitment not to enforce a
-patent against the party.
-
- If you convey a covered work, knowingly relying on a patent license,
-and the Corresponding Source of the work is not available for anyone
-to copy, free of charge and under the terms of this License, through a
-publicly available network server or other readily accessible means,
-then you must either (1) cause the Corresponding Source to be so
-available, or (2) arrange to deprive yourself of the benefit of the
-patent license for this particular work, or (3) arrange, in a manner
-consistent with the requirements of this License, to extend the patent
-license to downstream recipients. "Knowingly relying" means you have
-actual knowledge that, but for the patent license, your conveying the
-covered work in a country, or your recipient's use of the covered work
-in a country, would infringe one or more identifiable patents in that
-country that you have reason to believe are valid.
-
- If, pursuant to or in connection with a single transaction or
-arrangement, you convey, or propagate by procuring conveyance of, a
-covered work, and grant a patent license to some of the parties
-receiving the covered work authorizing them to use, propagate, modify
-or convey a specific copy of the covered work, then the patent license
-you grant is automatically extended to all recipients of the covered
-work and works based on it.
-
- A patent license is "discriminatory" if it does not include within
-the scope of its coverage, prohibits the exercise of, or is
-conditioned on the non-exercise of one or more of the rights that are
-specifically granted under this License. You may not convey a covered
-work if you are a party to an arrangement with a third party that is
-in the business of distributing software, under which you make payment
-to the third party based on the extent of your activity of conveying
-the work, and under which the third party grants, to any of the
-parties who would receive the covered work from you, a discriminatory
-patent license (a) in connection with copies of the covered work
-conveyed by you (or copies made from those copies), or (b) primarily
-for and in connection with specific products or compilations that
-contain the covered work, unless you entered into that arrangement,
-or that patent license was granted, prior to 28 March 2007.
-
- Nothing in this License shall be construed as excluding or limiting
-any implied license or other defenses to infringement that may
-otherwise be available to you under applicable patent law.
-
- 12. No Surrender of Others' Freedom.
-
- If conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot convey a
-covered work so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you may
-not convey it at all. For example, if you agree to terms that obligate you
-to collect a royalty for further conveying from those to whom you convey
-the Program, the only way you could satisfy both those terms and this
-License would be to refrain entirely from conveying the Program.
-
- 13. Use with the GNU Affero General Public License.
-
- Notwithstanding any other provision of this License, you have
-permission to link or combine any covered work with a work licensed
-under version 3 of the GNU Affero General Public License into a single
-combined work, and to convey the resulting work. The terms of this
-License will continue to apply to the part which is the covered work,
-but the special requirements of the GNU Affero General Public License,
-section 13, concerning interaction through a network will apply to the
-combination as such.
-
- 14. Revised Versions of this License.
-
- The Free Software Foundation may publish revised and/or new versions of
-the GNU General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
- Each version is given a distinguishing version number. If the
-Program specifies that a certain numbered version of the GNU General
-Public License "or any later version" applies to it, you have the
-option of following the terms and conditions either of that numbered
-version or of any later version published by the Free Software
-Foundation. If the Program does not specify a version number of the
-GNU General Public License, you may choose any version ever published
-by the Free Software Foundation.
-
- If the Program specifies that a proxy can decide which future
-versions of the GNU General Public License can be used, that proxy's
-public statement of acceptance of a version permanently authorizes you
-to choose that version for the Program.
-
- Later license versions may give you additional or different
-permissions. However, no additional obligations are imposed on any
-author or copyright holder as a result of your choosing to follow a
-later version.
-
- 15. Disclaimer of Warranty.
-
- THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
-APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
-HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
-OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
-IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
-ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
- 16. Limitation of Liability.
-
- IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
-THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
-GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
-USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
-DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
-PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
-EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGES.
-
- 17. Interpretation of Sections 15 and 16.
-
- If the disclaimer of warranty and limitation of liability provided
-above cannot be given local legal effect according to their terms,
-reviewing courts shall apply local law that most closely approximates
-an absolute waiver of all civil liability in connection with the
-Program, unless a warranty or assumption of liability accompanies a
-copy of the Program in return for a fee.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-state the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
- <one line to give the program's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-Also add information on how to contact you by electronic and paper mail.
-
- If the program does terminal interaction, make it output a short
-notice like this when it starts in an interactive mode:
-
- <program> Copyright (C) <year> <name of author>
- This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, your program's commands
-might be different; for a GUI interface, you would use an "about box".
-
- You should also get your employer (if you work as a programmer) or school,
-if any, to sign a "copyright disclaimer" for the program, if necessary.
-For more information on this, and how to apply and follow the GNU GPL, see
-<http://www.gnu.org/licenses/>.
-
- The GNU General Public License does not permit incorporating your program
-into proprietary programs. If your program is a subroutine library, you
-may consider it more useful to permit linking proprietary applications with
-the library. If this is what you want to do, use the GNU Lesser General
-Public License instead of this License. But first, please read
-<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/README.md b/README.md
index 6b56c0e..d0eb57e 100644
--- a/README.md
+++ b/README.md
@@ -34,7 +34,7 @@ git clone git@github.com:Pelagicore/qface.git
Copyright (C) 2016 Pelagicore AG
-The source code in this repository is subject to the terms of the GPLv3 licence, please see included "LICENSE" file for details.
+The source code in this repository is subject to the terms of the MIT license, please see included "LICENSE" file for details.
## QFace Example
diff --git a/cli.py b/cli.py
index 9c0f4fb..c04cbac 100755
--- a/cli.py
+++ b/cli.py
@@ -11,6 +11,8 @@ import os
import yaml
import logging
import logging.config
+from livereload import Server, shell
+
here = os.path.dirname(__file__)
@@ -166,10 +168,19 @@ def uninstall():
@cli.command()
def upload():
dist = Path('dist')
- dist.rmdir_p()
+ if dist.exists():
+ dist.rmdir_p()
+ dist.makedirs_p()
sh('python3 setup.py bdist_wheel')
sh('twine upload dist/*')
+@cli.command()
+def docs_serve():
+ server = Server()
+ server.watch('docs/*.rst', shell('make html', cwd='docs'))
+ server.serve(root='docs/_build/html', open_url=True)
+
+
if __name__ == '__main__':
cli()
diff --git a/docs/annotations.rst b/docs/annotations.rst
new file mode 100644
index 0000000..1092f6e
--- /dev/null
+++ b/docs/annotations.rst
@@ -0,0 +1,87 @@
+***********
+Annotations
+***********
+
+Annotations is a way to add meta information to your interface definition. It
+is available to each symbol in the interface.
+
+Annotations allows an interface author to extend the existing interface with additional meta information, called tags, aka annotations. One or several annotations can precede a module, ``interface``, ``struct`` or ``enum``. They are also allowed before an ``operation``, ``property`` or ``signal``. Everywhere where a documentation comment is allowed you can also add annotations.
+
+An annotation looks like this
+
+.. code-block:: python
+
+ @service: {port: 12345}
+ interface Tuner {
+ }
+
+
+An in code annotation precedes a symbol and it starts with an ``@`` sign. A symbol can have more than one one annotation line. Each line should be one individual annotation. The content is YAML content. All ``@`` signs preceding a symbol are collected and then evaluated using a YAML parser.
+
+For larger annotations you can use the external annotation document feature.
+
+.. code-block:: python
+
+ @singleton: yes
+ @data: [1,2,3]
+ @config: { values: [LEFT, RIGHT, TOP] }
+
+This will be result into a YAML content of
+
+
+.. code-block:: yaml
+
+ singleton: yes
+ data: [1,2,3]
+ config: { values: [LEFT, RIGHT, TOP] }
+
+And the result as Python object would be
+
+.. code-block:: python
+
+ {
+ "data": [ 1, 2, 3 ],
+ "singleton": true,
+ "config": {
+ "values": [ "LEFT", "RIGHT", "TOP" ]
+ }
+ }
+
+Annotation Documents
+====================
+
+QFace allows also to specify these annotations in external documents using the `YAML` syntax. For this you need to create a document with the same name as the QFace document but with the extension `.yaml`. It should have roughly the following format
+
+.. code-block:: yaml
+
+ com.pelagicore.ivi.Tuner:
+ service:
+ port: 12345
+
+On the root level should be a fully qualified name of a symbol. The symbol will be looked up and the following annotation information merged with the existing annotations from the QFace document.
+
+Merging Annotations
+===================
+
+The external annotations will be merged on top of the embedded annotations on per symbol base. Dictionaries will be merged. If a merge can not be done then the external document based annotations will override the embedded annotations.
+
+Generators
+==========
+
+The annotation are available later when navigating the domain model.
+
+.. code-block:: jinja2
+
+ {% if "service" in interface.tags %}
+ interface {{interface}} is served on port: {{interface.tags.service.port}}
+ {% else %}
+ interface {{interface}} is not served
+ {% endif %}
+
+.. note:: QFace does not specify specific annotations, but defines just the annotation format. The set of annotations supported must be defined and documented by the generator.
+
+
+
+
+
+
diff --git a/docs/grammar.rst b/docs/grammar.rst
index b8abb74..e76912d 100644
--- a/docs/grammar.rst
+++ b/docs/grammar.rst
@@ -1,9 +1,13 @@
-=============
-QFace Grammar
-=============
+=======
+Grammar
+=======
QFace (Qt interface language) is an Interface Description Languge (IDL). While it is primarily designed to define an interface between Qt, QML and C++, it is intended to be flexible enough also to be used in other contexts.
+The grammar of QFace is well defined and is based on the concepts of modules as larger collection of information.
+
+A module can have several interfaces, structs and/or enums/flags.
+
.. code-block:: html
module <module> <version>
@@ -35,6 +39,33 @@ Module
A module is identified name. A module should be normally a URI where all parts are lowercase (e.g. `entertainment.tuner`). A module may import other modules with the primary purpose being to ensure that dependencies are declared inside the QFace file.
+.. code-block:: js
+
+ // org.example.qface
+ module org.example 1.0
+
+ import org.common 1.0
+
+
+Interface
+=========
+
+An interface is a collection of properties, operation and signals. Properties carry data, whereas the operations normally modify the data. Signals are used to notify the user of changes.
+
+.. code-block:: js
+
+ interface WeatherStation {
+ real temperature;
+ void reset();
+ signal error(string message);
+ }
+
+Struct
+======
+
+Enum/Flag
+=========
+
Types
-----
@@ -104,37 +135,3 @@ Below is an example of a QFace file.
common.TimeStamp modified;
}
-
-Tags / Annotations
-==================
-
-Tags allows an interface author to extend the existing grammar with additional meta information, called tags, aka annotations. One or several annotations can stand in from of a module, interface, struct or enum. They are also allowed before an operation, property or signal. Everywhere where a documentation comment is allowed you can also add annotations.
-
-An annotation looks like this::
-
- @service(port=12345)
- interface Tuner {
- }
-
-A annotation format is very similar to an operation signature prefixed with an `@` sign and no return value.
-
-The annotation are available later when navigating the domain model.
-
-.. note:: QFace does not specify specific annotations, but defines just the annotation format. The set of annotations supported must be defined and documented by the generator.
-
-.. rubric:: Annotation Documents
-
-QFace allows also to specify these annotations in external documents using the `YAML` syntax. For this you need to create a document with the same name as the QFace document but with the extension `.yaml`. It should have roughly the following format
-
-.. code-block:: yaml
-
- com.pelagicore.ivi.Tuner:
- service:
- port: 12345
-
-On the root level should be a fully qualified name of a symbol. The symbol will be looked up and the following annotation information merged with the existing annotations form the QFace document.
-
-.. warning:: External annotation with the same name will override the QFace document annotation with the same name on the specified symbol.
-
-
-
diff --git a/docs/index.rst b/docs/index.rst
index 4eff83c..c83de6d 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -11,6 +11,8 @@ QFace is a flexible Qt API generator. It uses a common IDL format (called QFace
usage
builtin
grammar
+ annotations
+ yaml
domain
extending
api
diff --git a/docs/yaml.rst b/docs/yaml.rst
new file mode 100644
index 0000000..5d70e82
--- /dev/null
+++ b/docs/yaml.rst
@@ -0,0 +1,139 @@
+***********
+YAML Primer
+***********
+
+This page provides a basic overview of the YAML syntax as used by QFace in the embedded annotations and the external annotations document.
+
+According to the official YAML website, YAML is "a human friendly data serialization standard for all programming languages".
+
+YAML Foundation
+===============
+
+For QFace every YAML file is a dictionary of values.
+
+.. code-block:: python
+
+ @singleton: true
+ @base: QObject
+ interface Heater {
+ }
+
+A dictionary in YAML is expressed like this
+
+
+In an external YAML file the key on the root level is the fully qualified name of the symbol
+
+.. code-block:: YAML
+
+ org.example.Heater:
+ singleton: true
+ base: QObject
+
+Dictionary
+==========
+
+A dictionary is a simple ``key: value`` pair with a colon followed by a space (the space is mandatory).
+
+.. code-block:: yaml
+
+ key: value
+ key2: value
+ key3:
+ key31: value
+ key32: value
+
+A nested dictionary can be achieved by a new level of indentation.
+
+An alternate form for a dictionary is this
+
+.. code-block:: yaml
+
+ key3: { key31: value, key32: value }
+
+.. rubric Template
+
+In a template the dictionay can be used as attributes of an object
+
+.. code-block:: jinja
+
+ {% if interface.tags.key == 'value' %}YES{% endif %}
+
+To test is a key exists you can use the key in dictionary form
+
+.. code-block:: jinja
+
+ {% if 'key' in interface.tags %}YES{% endif %}
+
+List
+====
+
+A list is an array of values
+
+.. code-block:: yaml
+
+ - item1
+ - item2
+ - item3:
+ - item31
+ - item32
+
+A nested list can be created by indenting the list and postfixing the parent entry with a colon.
+
+An alternate form is
+
+.. .. code-block:: yaml
+
+ [ item1, item2, item3: [item31, item32] ]
+
+Comments
+--------
+
+YAML only knows line comments. A comment starts with a ``#`` and ends with line.
+
+.. code-block:: yaml
+
+ # this is the key for the value
+ key: value
+
+Primitive Types
+---------------
+
+YAML understands different primitive types.
+
+.. rubric:: string
+
+YAML understands strings either as an identifier or quoted using ``"`` or ``'``.
+
+You can use code blocks using the ``|`` sign. The block continues until the indentation ends. Or the ``>`` folding block, where each new line is replaced with a space.
+
+.. rubric:: number
+
+YAML understands different number formats, here is a short list of the most important ones
+
+.. code-block:: yaml
+
+ # an integer
+ value: 10
+
+ # an hex value
+ value: 0xFF
+
+ # a float
+ value: 1.01
+
+.. rubric:: boolean
+
+YAML understand different values as true/false.
+
+.. code-block:: yaml
+
+ positive: yes
+ positive: true
+ negative: no
+ negative: false
+
+Besides these words it understand different writing forms (e.g. YES, Yes, Y). Same applies for the negative version.
+
+
+
+
diff --git a/qface/__about__.py b/qface/__about__.py
index 71bd751..f3a9be8 100644
--- a/qface/__about__.py
+++ b/qface/__about__.py
@@ -9,6 +9,6 @@ except NameError:
__title__ = "qface"
__summary__ = "A generator framework based on a common modern IDL"
__uri__ = "https://pelagicore.github.io/qface/"
-__version__ = "1.1b2"
+__version__ = "1.1"
__author__ = "JRyannel"
__author_email__ = "qface-generator@googlegroups.com"
diff --git a/qface/builtin/qtcpp/qtcpp.py b/qface/builtin/qtcpp/qtcpp.py
index 630e64a..283b8f6 100755
--- a/qface/builtin/qtcpp/qtcpp.py
+++ b/qface/builtin/qtcpp/qtcpp.py
@@ -71,8 +71,8 @@ def app(src, dst, reload):
"""Takes several files or directories as src and generates the code
in the given dst directory."""
if reload:
- script = '{0} {1} {2}'.format(Path(__file__).abspath(), ' '.join(src), dst)
- monitor(src, script)
+ script = Path(__file__).abspath()
+ monitor(script, src, dst)
else:
run(src, dst)
diff --git a/qface/builtin/qtcpp/templates/abstractinterface.h b/qface/builtin/qtcpp/templates/abstractinterface.h
index 09a21a6..5335632 100644
--- a/qface/builtin/qtcpp/templates/abstractinterface.h
+++ b/qface/builtin/qtcpp/templates/abstractinterface.h
@@ -20,7 +20,7 @@ WRITE set{{property|upperfirst}} {% endif %}NOTIFY {{property}}Changed)
{% endfor %}
public:
- {{class}}(QObject *parent=0);
+ {{class}}(QObject *parent = nullptr);
~{{class}}();
public Q_SLOTS:
diff --git a/qface/builtin/qtcpp/templates/interface.h b/qface/builtin/qtcpp/templates/interface.h
index cc05be2..6ada967 100644
--- a/qface/builtin/qtcpp/templates/interface.h
+++ b/qface/builtin/qtcpp/templates/interface.h
@@ -17,7 +17,7 @@ class {{class}} : public QmlAbstract{{interface}}
{
Q_OBJECT
public:
- {{class}}(QObject *parent=0);
+ {{class}}(QObject *parent = nullptr);
virtual ~{{class}}();
static void registerQmlTypes(const QString& uri, int majorVersion=1, int minorVersion=0);
diff --git a/qface/builtin/qtcpp/templates/module.h b/qface/builtin/qtcpp/templates/module.h
index 39b5026..5e9ff6f 100644
--- a/qface/builtin/qtcpp/templates/module.h
+++ b/qface/builtin/qtcpp/templates/module.h
@@ -18,7 +18,7 @@
class {{class}} : public QObject {
Q_OBJECT
public:
- {{class}}(QObject *parent=0);
+ {{class}}(QObject *parent = nullptr);
{% for enum in module.enums %}
{% set comma = joiner(",") %}
diff --git a/qface/builtin/qtcpp/templates/structmodel.h b/qface/builtin/qtcpp/templates/structmodel.h
index 96597be..ab02b25 100644
--- a/qface/builtin/qtcpp/templates/structmodel.h
+++ b/qface/builtin/qtcpp/templates/structmodel.h
@@ -17,7 +17,7 @@ class {{class}} : public QAbstractListModel
Q_PROPERTY(int count READ count NOTIFY countChanged)
public:
enum Roles { {{struct.fields|map('upperfirst')|join(', ')}} };
- {{class}}(QObject *parent=0);
+ {{class}}(QObject *parent = nullptr);
Q_INVOKABLE Qml{{struct}} get(int index);
int count() const;
void insert(int row, const Qml{{struct}} &{{struct|lower}});
diff --git a/qface/builtin/qtcpp/templates/variantmodel.h b/qface/builtin/qtcpp/templates/variantmodel.h
index 67be224..3f1bbd3 100644
--- a/qface/builtin/qtcpp/templates/variantmodel.h
+++ b/qface/builtin/qtcpp/templates/variantmodel.h
@@ -15,7 +15,7 @@ class {{class}} : public QAbstractListModel
Q_PROPERTY(int count READ count NOTIFY countChanged)
public:
enum Roles { ModelData = Qt::UserRole };
- {{class}}(QObject *parent=0);
+ {{class}}(QObject *parent = nullptr);
Q_INVOKABLE QVariant get(int index);
int count() const;
void insert(int row, const QVariant &entry);
diff --git a/qface/builtin/qtqml/qtqml.py b/qface/builtin/qtqml/qtqml.py
index b5ed136..1d00d74 100755
--- a/qface/builtin/qtqml/qtqml.py
+++ b/qface/builtin/qtqml/qtqml.py
@@ -57,8 +57,8 @@ def app(src, dst, reload):
"""Takes several files or directories as src and generates the code
in the given dst directory."""
if reload:
- script = '{0} {1} {2}'.format(Path(__file__).abspath(), ' '.join(src), dst)
- monitor(src, script)
+ script = Path(__file__).abspath()
+ monitor(script, src, dst)
else:
run(src, dst)
diff --git a/qface/generator.py b/qface/generator.py
index 476dc4e..db1235c 100644
--- a/qface/generator.py
+++ b/qface/generator.py
@@ -8,14 +8,20 @@ import shelve
import logging
import hashlib
import yaml
+import click
from .idl.parser.TLexer import TLexer
from .idl.parser.TParser import TParser
from .idl.parser.TListener import TListener
from .idl.domain import System
from .idl.listener import DomainListener
+from .utils import merge
-import click
+
+try:
+ from yaml import CLoader as Loader, CDumper as Dumper
+except ImportError:
+ from yaml import Loader, Dumper
logger = logging.getLogger(__name__)
@@ -106,7 +112,7 @@ class FileSystem(object):
logger.debug('parse document: {0}'.format(document))
stream = FileStream(str(document), encoding='utf-8')
system = FileSystem._parse_stream(stream, system)
- FileSystem.merge_annoations(system, document.stripext() + '.yaml')
+ FileSystem.merge_annotations(system, document.stripext() + '.yaml')
return system
@staticmethod
@@ -124,7 +130,7 @@ class FileSystem(object):
return system
@staticmethod
- def merge_annoations(system: System, document: Path):
+ def merge_annotations(system, document):
"""Read a YAML document and for each root symbol identifier
updates the tag information of that symbol
"""
@@ -132,14 +138,14 @@ class FileSystem(object):
return
meta = {}
try:
- meta = yaml.load(document.text())
+ meta = yaml.load(document.text(), Loader=Loader)
except yaml.YAMLError as exc:
- click.echo(exc)
+ click.secho(exc, fg='red')
click.secho('merge tags from {0}'.format(document), fg='blue')
for identifier, data in meta.items():
symbol = system.lookup(identifier)
if symbol:
- symbol.tags.update(data)
+ merge(symbol.tags, data)
@staticmethod
def parse(input, identifier: str = None, use_cache=False, clear_cache=True, pattern="*.qface"):
diff --git a/qface/idl/domain.py b/qface/idl/domain.py
index 9fc553b..c774c16 100644
--- a/qface/idl/domain.py
+++ b/qface/idl/domain.py
@@ -110,7 +110,7 @@ class Symbol(NamedElement):
super().__init__(name, module)
self.comment = ''
"""comment which appeared in QFace right before symbol"""
- self._tags = OrderedDict()
+ self._tags = dict()
self._contentMap = ChainMap()
self.type = TypeSymbol('', self)
@@ -126,7 +126,7 @@ class Symbol(NamedElement):
def add_tag(self, tag):
if tag not in self._tags:
- self._tags[tag] = OrderedDict()
+ self._tags[tag] = dict()
def add_attribute(self, tag, name, value):
self.add_tag(tag)
@@ -137,7 +137,7 @@ class Symbol(NamedElement):
return self._tags[name]
def attribute(self, tag, name):
- if tag in self._tags:
+ if tag in self._tags and name in self._tags[tag]:
return self._tags[tag][name]
@property
diff --git a/qface/idl/listener.py b/qface/idl/listener.py
index 826f44f..fc5781a 100644
--- a/qface/idl/listener.py
+++ b/qface/idl/listener.py
@@ -6,6 +6,13 @@ from .parser.TListener import TListener
from .parser.TParser import TParser
from .domain import *
from antlr4 import ParserRuleContext
+import yaml
+import click
+
+try:
+ from yaml import CLoader as Loader, CDumper as Dumper
+except ImportError:
+ from yaml import Loader, Dumper
log = logging.getLogger(__name__)
@@ -18,6 +25,7 @@ class DomainListener(TListener):
"""The domain listener is called by the parser to fill the
domain data struture. As a result a system is passed
back"""
+
def __init__(self, system):
super(DomainListener, self).__init__()
contextMap.clear()
@@ -28,7 +36,7 @@ class DomainListener(TListener):
self.enum = None # type:Enum
self.enumCounter = 0 # int
self.operation = None # type:Operation
- self.signal = None # type:Signal
+ self.signal = None # type:Signal
self.parameter = None # type:Parameter
self.property = None # type:Property
self.field = None # type:Field
@@ -40,21 +48,25 @@ class DomainListener(TListener):
type.name = 'void'
else:
if ctx.typeSymbol().primitiveTypeSymbol():
- ctxSymbol = ctx.typeSymbol().primitiveTypeSymbol() # type:TParser.PrimitiveTypeSymbolContext
+ # type:TParser.PrimitiveTypeSymbolContext
+ ctxSymbol = ctx.typeSymbol().primitiveTypeSymbol()
type.is_primitive = True
type.name = ctxSymbol.name.text
elif ctx.typeSymbol().complexTypeSymbol():
- ctxSymbol = ctx.typeSymbol().complexTypeSymbol() # type:TParser.ComplexTypeSymbolContext
+ # type:TParser.ComplexTypeSymbolContext
+ ctxSymbol = ctx.typeSymbol().complexTypeSymbol()
type.is_complex = True
type.name = ctxSymbol.name.text
elif ctx.typeSymbol().listTypeSymbol():
- ctxSymbol = ctx.typeSymbol().listTypeSymbol() # type:TParser.ListTypeSymbolContext
+ # type:TParser.ListTypeSymbolContext
+ ctxSymbol = ctx.typeSymbol().listTypeSymbol()
type.is_list = True
type.name = 'list'
type.nested = TypeSymbol("", type)
self.parse_type(ctxSymbol, type.nested)
elif ctx.typeSymbol().modelTypeSymbol():
- ctxSymbol = ctx.typeSymbol().modelTypeSymbol() # type:TParser.ModelTypeSymbolContext
+ # type:TParser.ModelTypeSymbolContext
+ ctxSymbol = ctx.typeSymbol().modelTypeSymbol()
type.is_model = True
type.name = 'model'
type.nested = TypeSymbol("", type)
@@ -63,18 +75,17 @@ class DomainListener(TListener):
log.warn('Unknown type: {0}. Missing import?'.format(type.name))
def parse_annotations(self, ctx, symbol):
+ assert ctx and symbol
if ctx.comment:
comment = ctx.comment.text
symbol.comment = comment
if ctx.tagSymbol():
- for tag in ctx.tagSymbol():
- tag_name = tag.name.text[1:]
- symbol.add_tag(tag_name)
- attrs = tag.tagAttributeSymbol()
- for attr in attrs:
- attr_name = attr.name.text
- attr_value = attr.value.text
- symbol.add_attribute(tag_name, attr_name, attr_value)
+ lines = [tag.line.text[1:] for tag in ctx.tagSymbol()]
+ try:
+ data = yaml.load('\n'.join(lines), Loader=Loader)
+ symbol._tags = data
+ except yaml.YAMLError as exc:
+ click.secho(exc, fg='red')
def enterEveryRule(self, ctx):
log.debug('enter ' + ctx.__class__.__name__)
@@ -91,7 +102,6 @@ class DomainListener(TListener):
contextMap[ctx] = self.module
self.parse_annotations(ctx, self.module)
-
def exitModuleSymbol(self, ctx: TParser.ModuleSymbolContext):
pass
@@ -118,7 +128,6 @@ class DomainListener(TListener):
def enterEnumSymbol(self, ctx: TParser.EnumSymbolContext):
assert self.module
name = ctx.name.text
- # import ipdb; ipdb.set_trace()
self.enum = Enum(name, self.module)
self.parse_annotations(ctx, self.enum)
contextMap[ctx] = self.enum
@@ -153,7 +162,7 @@ class DomainListener(TListener):
assert self.interface
name = ctx.name.text
self.signal = Signal(name, self.interface)
- self.parse_annotations(ctx, self.operation)
+ self.parse_annotations(ctx, self.signal)
contextMap[ctx] = self.signal
def exitSignalSymbol(self, ctx: TParser.SignalSymbolContext):
@@ -199,7 +208,6 @@ class DomainListener(TListener):
value = int(ctx.intSymbol().value.text, 0)
self.field.value = value
contextMap[ctx] = self.field
- # import ipdb; ipdb.set_trace()
if self.enum.is_flag:
self.enumCounter <<= 1
else:
@@ -212,7 +220,6 @@ class DomainListener(TListener):
assert self.module
name = ctx.name.text
version = ctx.version.text
- # import ipdb; ipdb.set_trace()
self.module._importMap[name] = '{0} {1}'.format(name, version)
def exitImportSymbol(self, ctx: TParser.ImportSymbolContext):
diff --git a/qface/idl/parser/T.g4 b/qface/idl/parser/T.g4
index 3782c91..4ec68c8 100644
--- a/qface/idl/parser/T.g4
+++ b/qface/idl/parser/T.g4
@@ -56,11 +56,11 @@ operationParameterSymbol
;
tagSymbol
- : name=TAGIDENTIFIER '(' tagAttributeSymbol* ')'
+ : line=TAGLINE
;
tagAttributeSymbol
- : name=IDENTIFIER ('=' value=IDENTIFIER)?
+ : name=IDENTIFIER ('=' value=IDENTIFIER)? ','?
;
typeSymbol
@@ -116,6 +116,7 @@ intSymbol
| value=HEXCONSTANT
;
+TAGLINE : '@' ~[\r\n]*;
INTCONSTANT : ('+' | '-')? '0'..'9'+;
HEXCONSTANT : '0x' ('0'..'9' | 'a'..'f' | 'A'..'F')+;
TAGIDENTIFIER : '@'[a-zA-Z_][a-zA-Z0-9_.]*;
diff --git a/qface/idl/parser/T.tokens b/qface/idl/parser/T.tokens
index 25c2f2f..86bf74a 100644
--- a/qface/idl/parser/T.tokens
+++ b/qface/idl/parser/T.tokens
@@ -23,15 +23,16 @@ T__21=22
T__22=23
T__23=24
T__24=25
-INTCONSTANT=26
-HEXCONSTANT=27
-TAGIDENTIFIER=28
-IDENTIFIER=29
-VERSION=30
-DOCCOMMENT=31
-WHITESPACE=32
-COMMENT=33
-MULTICOMM=34
+TAGLINE=26
+INTCONSTANT=27
+HEXCONSTANT=28
+TAGIDENTIFIER=29
+IDENTIFIER=30
+VERSION=31
+DOCCOMMENT=32
+WHITESPACE=33
+COMMENT=34
+MULTICOMM=35
'import'=1
';'=2
'module'=3
diff --git a/qface/idl/parser/TLexer.py b/qface/idl/parser/TLexer.py
index 167f9ef..59f1fcb 100644
--- a/qface/idl/parser/TLexer.py
+++ b/qface/idl/parser/TLexer.py
@@ -5,116 +5,121 @@ from io import StringIO
def serializedATN():
with StringIO() as buf:
- buf.write("\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\2$")
- buf.write("\u010b\b\1\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7")
+ buf.write("\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\2%")
+ buf.write("\u0114\b\1\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7")
buf.write("\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t\13\4\f\t\f\4\r\t\r")
buf.write("\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22\4\23")
buf.write("\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30")
buf.write("\4\31\t\31\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36")
- buf.write("\t\36\4\37\t\37\4 \t \4!\t!\4\"\t\"\4#\t#\3\2\3\2\3\2")
- buf.write("\3\2\3\2\3\2\3\2\3\3\3\3\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3")
- buf.write("\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\6\3\6\3\7\3\7")
- buf.write("\3\b\3\b\3\b\3\b\3\b\3\t\3\t\3\n\3\n\3\13\3\13\3\13\3")
- buf.write("\13\3\13\3\13\3\13\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f")
- buf.write("\3\r\3\r\3\16\3\16\3\17\3\17\3\17\3\17\3\17\3\20\3\20")
- buf.write("\3\20\3\20\3\21\3\21\3\21\3\21\3\21\3\22\3\22\3\22\3\22")
- buf.write("\3\22\3\22\3\22\3\23\3\23\3\23\3\23\3\24\3\24\3\24\3\24")
- buf.write("\3\24\3\25\3\25\3\26\3\26\3\27\3\27\3\27\3\27\3\27\3\27")
- buf.write("\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\31\3\31\3\31\3\31")
- buf.write("\3\31\3\32\3\32\3\32\3\32\3\32\3\33\5\33\u00bd\n\33\3")
- buf.write("\33\6\33\u00c0\n\33\r\33\16\33\u00c1\3\34\3\34\3\34\3")
- buf.write("\34\6\34\u00c8\n\34\r\34\16\34\u00c9\3\35\3\35\3\35\7")
- buf.write("\35\u00cf\n\35\f\35\16\35\u00d2\13\35\3\36\3\36\7\36\u00d6")
- buf.write("\n\36\f\36\16\36\u00d9\13\36\3\37\3\37\3\37\3\37\3 \3")
- buf.write(" \3 \3 \3 \7 \u00e4\n \f \16 \u00e7\13 \3 \3 \3 \3!\6")
- buf.write("!\u00ed\n!\r!\16!\u00ee\3!\3!\3\"\3\"\3\"\3\"\7\"\u00f7")
- buf.write("\n\"\f\"\16\"\u00fa\13\"\3\"\3\"\3#\3#\3#\3#\7#\u0102")
- buf.write("\n#\f#\16#\u0105\13#\3#\3#\3#\3#\3#\4\u00e5\u0103\2$\3")
- buf.write("\3\5\4\7\5\t\6\13\7\r\b\17\t\21\n\23\13\25\f\27\r\31\16")
- buf.write("\33\17\35\20\37\21!\22#\23%\24\'\25)\26+\27-\30/\31\61")
- buf.write("\32\63\33\65\34\67\359\36;\37= ?!A\"C#E$\3\2\t\4\2--/")
- buf.write("/\5\2\62;CHch\5\2C\\aac|\7\2\60\60\62;C\\aac|\3\2\62;")
- buf.write("\5\2\13\f\17\17\"\"\4\2\f\f\17\17\u0113\2\3\3\2\2\2\2")
- buf.write("\5\3\2\2\2\2\7\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3")
- buf.write("\2\2\2\2\17\3\2\2\2\2\21\3\2\2\2\2\23\3\2\2\2\2\25\3\2")
- buf.write("\2\2\2\27\3\2\2\2\2\31\3\2\2\2\2\33\3\2\2\2\2\35\3\2\2")
- buf.write("\2\2\37\3\2\2\2\2!\3\2\2\2\2#\3\2\2\2\2%\3\2\2\2\2\'\3")
- buf.write("\2\2\2\2)\3\2\2\2\2+\3\2\2\2\2-\3\2\2\2\2/\3\2\2\2\2\61")
- buf.write("\3\2\2\2\2\63\3\2\2\2\2\65\3\2\2\2\2\67\3\2\2\2\29\3\2")
- buf.write("\2\2\2;\3\2\2\2\2=\3\2\2\2\2?\3\2\2\2\2A\3\2\2\2\2C\3")
- buf.write("\2\2\2\2E\3\2\2\2\3G\3\2\2\2\5N\3\2\2\2\7P\3\2\2\2\tW")
- buf.write("\3\2\2\2\13a\3\2\2\2\rc\3\2\2\2\17e\3\2\2\2\21j\3\2\2")
- buf.write("\2\23l\3\2\2\2\25n\3\2\2\2\27u\3\2\2\2\31~\3\2\2\2\33")
- buf.write("\u0080\3\2\2\2\35\u0082\3\2\2\2\37\u0087\3\2\2\2!\u008b")
- buf.write("\3\2\2\2#\u0090\3\2\2\2%\u0097\3\2\2\2\'\u009b\3\2\2\2")
- buf.write(")\u00a0\3\2\2\2+\u00a2\3\2\2\2-\u00a4\3\2\2\2/\u00aa\3")
- buf.write("\2\2\2\61\u00b1\3\2\2\2\63\u00b6\3\2\2\2\65\u00bc\3\2")
- buf.write("\2\2\67\u00c3\3\2\2\29\u00cb\3\2\2\2;\u00d3\3\2\2\2=\u00da")
- buf.write("\3\2\2\2?\u00de\3\2\2\2A\u00ec\3\2\2\2C\u00f2\3\2\2\2")
- buf.write("E\u00fd\3\2\2\2GH\7k\2\2HI\7o\2\2IJ\7r\2\2JK\7q\2\2KL")
- buf.write("\7t\2\2LM\7v\2\2M\4\3\2\2\2NO\7=\2\2O\6\3\2\2\2PQ\7o\2")
- buf.write("\2QR\7q\2\2RS\7f\2\2ST\7w\2\2TU\7n\2\2UV\7g\2\2V\b\3\2")
- buf.write("\2\2WX\7k\2\2XY\7p\2\2YZ\7v\2\2Z[\7g\2\2[\\\7t\2\2\\]")
- buf.write("\7h\2\2]^\7c\2\2^_\7e\2\2_`\7g\2\2`\n\3\2\2\2ab\7}\2\2")
- buf.write("b\f\3\2\2\2cd\7\177\2\2d\16\3\2\2\2ef\7x\2\2fg\7q\2\2")
- buf.write("gh\7k\2\2hi\7f\2\2i\20\3\2\2\2jk\7*\2\2k\22\3\2\2\2lm")
- buf.write("\7+\2\2m\24\3\2\2\2no\7u\2\2op\7k\2\2pq\7i\2\2qr\7p\2")
- buf.write("\2rs\7c\2\2st\7n\2\2t\26\3\2\2\2uv\7t\2\2vw\7g\2\2wx\7")
- buf.write("c\2\2xy\7f\2\2yz\7q\2\2z{\7p\2\2{|\7n\2\2|}\7{\2\2}\30")
- buf.write("\3\2\2\2~\177\7.\2\2\177\32\3\2\2\2\u0080\u0081\7?\2\2")
- buf.write("\u0081\34\3\2\2\2\u0082\u0083\7d\2\2\u0083\u0084\7q\2")
- buf.write("\2\u0084\u0085\7q\2\2\u0085\u0086\7n\2\2\u0086\36\3\2")
- buf.write("\2\2\u0087\u0088\7k\2\2\u0088\u0089\7p\2\2\u0089\u008a")
- buf.write("\7v\2\2\u008a \3\2\2\2\u008b\u008c\7t\2\2\u008c\u008d")
- buf.write("\7g\2\2\u008d\u008e\7c\2\2\u008e\u008f\7n\2\2\u008f\"")
- buf.write("\3\2\2\2\u0090\u0091\7u\2\2\u0091\u0092\7v\2\2\u0092\u0093")
- buf.write("\7t\2\2\u0093\u0094\7k\2\2\u0094\u0095\7p\2\2\u0095\u0096")
- buf.write("\7i\2\2\u0096$\3\2\2\2\u0097\u0098\7x\2\2\u0098\u0099")
- buf.write("\7c\2\2\u0099\u009a\7t\2\2\u009a&\3\2\2\2\u009b\u009c")
- buf.write("\7n\2\2\u009c\u009d\7k\2\2\u009d\u009e\7u\2\2\u009e\u009f")
- buf.write("\7v\2\2\u009f(\3\2\2\2\u00a0\u00a1\7>\2\2\u00a1*\3\2\2")
- buf.write("\2\u00a2\u00a3\7@\2\2\u00a3,\3\2\2\2\u00a4\u00a5\7o\2")
- buf.write("\2\u00a5\u00a6\7q\2\2\u00a6\u00a7\7f\2\2\u00a7\u00a8\7")
- buf.write("g\2\2\u00a8\u00a9\7n\2\2\u00a9.\3\2\2\2\u00aa\u00ab\7")
- buf.write("u\2\2\u00ab\u00ac\7v\2\2\u00ac\u00ad\7t\2\2\u00ad\u00ae")
- buf.write("\7w\2\2\u00ae\u00af\7e\2\2\u00af\u00b0\7v\2\2\u00b0\60")
- buf.write("\3\2\2\2\u00b1\u00b2\7g\2\2\u00b2\u00b3\7p\2\2\u00b3\u00b4")
- buf.write("\7w\2\2\u00b4\u00b5\7o\2\2\u00b5\62\3\2\2\2\u00b6\u00b7")
- buf.write("\7h\2\2\u00b7\u00b8\7n\2\2\u00b8\u00b9\7c\2\2\u00b9\u00ba")
- buf.write("\7i\2\2\u00ba\64\3\2\2\2\u00bb\u00bd\t\2\2\2\u00bc\u00bb")
- buf.write("\3\2\2\2\u00bc\u00bd\3\2\2\2\u00bd\u00bf\3\2\2\2\u00be")
- buf.write("\u00c0\4\62;\2\u00bf\u00be\3\2\2\2\u00c0\u00c1\3\2\2\2")
- buf.write("\u00c1\u00bf\3\2\2\2\u00c1\u00c2\3\2\2\2\u00c2\66\3\2")
- buf.write("\2\2\u00c3\u00c4\7\62\2\2\u00c4\u00c5\7z\2\2\u00c5\u00c7")
- buf.write("\3\2\2\2\u00c6\u00c8\t\3\2\2\u00c7\u00c6\3\2\2\2\u00c8")
- buf.write("\u00c9\3\2\2\2\u00c9\u00c7\3\2\2\2\u00c9\u00ca\3\2\2\2")
- buf.write("\u00ca8\3\2\2\2\u00cb\u00cc\7B\2\2\u00cc\u00d0\t\4\2\2")
- buf.write("\u00cd\u00cf\t\5\2\2\u00ce\u00cd\3\2\2\2\u00cf\u00d2\3")
- buf.write("\2\2\2\u00d0\u00ce\3\2\2\2\u00d0\u00d1\3\2\2\2\u00d1:")
- buf.write("\3\2\2\2\u00d2\u00d0\3\2\2\2\u00d3\u00d7\t\4\2\2\u00d4")
- buf.write("\u00d6\t\5\2\2\u00d5\u00d4\3\2\2\2\u00d6\u00d9\3\2\2\2")
- buf.write("\u00d7\u00d5\3\2\2\2\u00d7\u00d8\3\2\2\2\u00d8<\3\2\2")
- buf.write("\2\u00d9\u00d7\3\2\2\2\u00da\u00db\t\6\2\2\u00db\u00dc")
- buf.write("\7\60\2\2\u00dc\u00dd\t\6\2\2\u00dd>\3\2\2\2\u00de\u00df")
- buf.write("\7\61\2\2\u00df\u00e0\7,\2\2\u00e0\u00e1\7,\2\2\u00e1")
- buf.write("\u00e5\3\2\2\2\u00e2\u00e4\13\2\2\2\u00e3\u00e2\3\2\2")
- buf.write("\2\u00e4\u00e7\3\2\2\2\u00e5\u00e6\3\2\2\2\u00e5\u00e3")
- buf.write("\3\2\2\2\u00e6\u00e8\3\2\2\2\u00e7\u00e5\3\2\2\2\u00e8")
- buf.write("\u00e9\7,\2\2\u00e9\u00ea\7\61\2\2\u00ea@\3\2\2\2\u00eb")
- buf.write("\u00ed\t\7\2\2\u00ec\u00eb\3\2\2\2\u00ed\u00ee\3\2\2\2")
- buf.write("\u00ee\u00ec\3\2\2\2\u00ee\u00ef\3\2\2\2\u00ef\u00f0\3")
- buf.write("\2\2\2\u00f0\u00f1\b!\2\2\u00f1B\3\2\2\2\u00f2\u00f3\7")
- buf.write("\61\2\2\u00f3\u00f4\7\61\2\2\u00f4\u00f8\3\2\2\2\u00f5")
- buf.write("\u00f7\n\b\2\2\u00f6\u00f5\3\2\2\2\u00f7\u00fa\3\2\2\2")
- buf.write("\u00f8\u00f6\3\2\2\2\u00f8\u00f9\3\2\2\2\u00f9\u00fb\3")
- buf.write("\2\2\2\u00fa\u00f8\3\2\2\2\u00fb\u00fc\b\"\2\2\u00fcD")
- buf.write("\3\2\2\2\u00fd\u00fe\7\61\2\2\u00fe\u00ff\7,\2\2\u00ff")
- buf.write("\u0103\3\2\2\2\u0100\u0102\13\2\2\2\u0101\u0100\3\2\2")
- buf.write("\2\u0102\u0105\3\2\2\2\u0103\u0104\3\2\2\2\u0103\u0101")
- buf.write("\3\2\2\2\u0104\u0106\3\2\2\2\u0105\u0103\3\2\2\2\u0106")
- buf.write("\u0107\7,\2\2\u0107\u0108\7\61\2\2\u0108\u0109\3\2\2\2")
- buf.write("\u0109\u010a\b#\2\2\u010aF\3\2\2\2\f\2\u00bc\u00c1\u00c9")
- buf.write("\u00d0\u00d7\u00e5\u00ee\u00f8\u0103\3\b\2\2")
+ buf.write("\t\36\4\37\t\37\4 \t \4!\t!\4\"\t\"\4#\t#\4$\t$\3\2\3")
+ buf.write("\2\3\2\3\2\3\2\3\2\3\2\3\3\3\3\3\4\3\4\3\4\3\4\3\4\3\4")
+ buf.write("\3\4\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\6\3\6\3")
+ buf.write("\7\3\7\3\b\3\b\3\b\3\b\3\b\3\t\3\t\3\n\3\n\3\13\3\13\3")
+ buf.write("\13\3\13\3\13\3\13\3\13\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3")
+ buf.write("\f\3\f\3\r\3\r\3\16\3\16\3\17\3\17\3\17\3\17\3\17\3\20")
+ buf.write("\3\20\3\20\3\20\3\21\3\21\3\21\3\21\3\21\3\22\3\22\3\22")
+ buf.write("\3\22\3\22\3\22\3\22\3\23\3\23\3\23\3\23\3\24\3\24\3\24")
+ buf.write("\3\24\3\24\3\25\3\25\3\26\3\26\3\27\3\27\3\27\3\27\3\27")
+ buf.write("\3\27\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\31\3\31\3\31")
+ buf.write("\3\31\3\31\3\32\3\32\3\32\3\32\3\32\3\33\3\33\7\33\u00c0")
+ buf.write("\n\33\f\33\16\33\u00c3\13\33\3\34\5\34\u00c6\n\34\3\34")
+ buf.write("\6\34\u00c9\n\34\r\34\16\34\u00ca\3\35\3\35\3\35\3\35")
+ buf.write("\6\35\u00d1\n\35\r\35\16\35\u00d2\3\36\3\36\3\36\7\36")
+ buf.write("\u00d8\n\36\f\36\16\36\u00db\13\36\3\37\3\37\7\37\u00df")
+ buf.write("\n\37\f\37\16\37\u00e2\13\37\3 \3 \3 \3 \3!\3!\3!\3!\3")
+ buf.write("!\7!\u00ed\n!\f!\16!\u00f0\13!\3!\3!\3!\3\"\6\"\u00f6")
+ buf.write("\n\"\r\"\16\"\u00f7\3\"\3\"\3#\3#\3#\3#\7#\u0100\n#\f")
+ buf.write("#\16#\u0103\13#\3#\3#\3$\3$\3$\3$\7$\u010b\n$\f$\16$\u010e")
+ buf.write("\13$\3$\3$\3$\3$\3$\4\u00ee\u010c\2%\3\3\5\4\7\5\t\6\13")
+ buf.write("\7\r\b\17\t\21\n\23\13\25\f\27\r\31\16\33\17\35\20\37")
+ buf.write("\21!\22#\23%\24\'\25)\26+\27-\30/\31\61\32\63\33\65\34")
+ buf.write("\67\359\36;\37= ?!A\"C#E$G%\3\2\t\4\2\f\f\17\17\4\2--")
+ buf.write("//\5\2\62;CHch\5\2C\\aac|\7\2\60\60\62;C\\aac|\3\2\62")
+ buf.write(";\5\2\13\f\17\17\"\"\u011d\2\3\3\2\2\2\2\5\3\2\2\2\2\7")
+ buf.write("\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2")
+ buf.write("\2\2\2\21\3\2\2\2\2\23\3\2\2\2\2\25\3\2\2\2\2\27\3\2\2")
+ buf.write("\2\2\31\3\2\2\2\2\33\3\2\2\2\2\35\3\2\2\2\2\37\3\2\2\2")
+ buf.write("\2!\3\2\2\2\2#\3\2\2\2\2%\3\2\2\2\2\'\3\2\2\2\2)\3\2\2")
+ buf.write("\2\2+\3\2\2\2\2-\3\2\2\2\2/\3\2\2\2\2\61\3\2\2\2\2\63")
+ buf.write("\3\2\2\2\2\65\3\2\2\2\2\67\3\2\2\2\29\3\2\2\2\2;\3\2\2")
+ buf.write("\2\2=\3\2\2\2\2?\3\2\2\2\2A\3\2\2\2\2C\3\2\2\2\2E\3\2")
+ buf.write("\2\2\2G\3\2\2\2\3I\3\2\2\2\5P\3\2\2\2\7R\3\2\2\2\tY\3")
+ buf.write("\2\2\2\13c\3\2\2\2\re\3\2\2\2\17g\3\2\2\2\21l\3\2\2\2")
+ buf.write("\23n\3\2\2\2\25p\3\2\2\2\27w\3\2\2\2\31\u0080\3\2\2\2")
+ buf.write("\33\u0082\3\2\2\2\35\u0084\3\2\2\2\37\u0089\3\2\2\2!\u008d")
+ buf.write("\3\2\2\2#\u0092\3\2\2\2%\u0099\3\2\2\2\'\u009d\3\2\2\2")
+ buf.write(")\u00a2\3\2\2\2+\u00a4\3\2\2\2-\u00a6\3\2\2\2/\u00ac\3")
+ buf.write("\2\2\2\61\u00b3\3\2\2\2\63\u00b8\3\2\2\2\65\u00bd\3\2")
+ buf.write("\2\2\67\u00c5\3\2\2\29\u00cc\3\2\2\2;\u00d4\3\2\2\2=\u00dc")
+ buf.write("\3\2\2\2?\u00e3\3\2\2\2A\u00e7\3\2\2\2C\u00f5\3\2\2\2")
+ buf.write("E\u00fb\3\2\2\2G\u0106\3\2\2\2IJ\7k\2\2JK\7o\2\2KL\7r")
+ buf.write("\2\2LM\7q\2\2MN\7t\2\2NO\7v\2\2O\4\3\2\2\2PQ\7=\2\2Q\6")
+ buf.write("\3\2\2\2RS\7o\2\2ST\7q\2\2TU\7f\2\2UV\7w\2\2VW\7n\2\2")
+ buf.write("WX\7g\2\2X\b\3\2\2\2YZ\7k\2\2Z[\7p\2\2[\\\7v\2\2\\]\7")
+ buf.write("g\2\2]^\7t\2\2^_\7h\2\2_`\7c\2\2`a\7e\2\2ab\7g\2\2b\n")
+ buf.write("\3\2\2\2cd\7}\2\2d\f\3\2\2\2ef\7\177\2\2f\16\3\2\2\2g")
+ buf.write("h\7x\2\2hi\7q\2\2ij\7k\2\2jk\7f\2\2k\20\3\2\2\2lm\7*\2")
+ buf.write("\2m\22\3\2\2\2no\7+\2\2o\24\3\2\2\2pq\7u\2\2qr\7k\2\2")
+ buf.write("rs\7i\2\2st\7p\2\2tu\7c\2\2uv\7n\2\2v\26\3\2\2\2wx\7t")
+ buf.write("\2\2xy\7g\2\2yz\7c\2\2z{\7f\2\2{|\7q\2\2|}\7p\2\2}~\7")
+ buf.write("n\2\2~\177\7{\2\2\177\30\3\2\2\2\u0080\u0081\7.\2\2\u0081")
+ buf.write("\32\3\2\2\2\u0082\u0083\7?\2\2\u0083\34\3\2\2\2\u0084")
+ buf.write("\u0085\7d\2\2\u0085\u0086\7q\2\2\u0086\u0087\7q\2\2\u0087")
+ buf.write("\u0088\7n\2\2\u0088\36\3\2\2\2\u0089\u008a\7k\2\2\u008a")
+ buf.write("\u008b\7p\2\2\u008b\u008c\7v\2\2\u008c \3\2\2\2\u008d")
+ buf.write("\u008e\7t\2\2\u008e\u008f\7g\2\2\u008f\u0090\7c\2\2\u0090")
+ buf.write("\u0091\7n\2\2\u0091\"\3\2\2\2\u0092\u0093\7u\2\2\u0093")
+ buf.write("\u0094\7v\2\2\u0094\u0095\7t\2\2\u0095\u0096\7k\2\2\u0096")
+ buf.write("\u0097\7p\2\2\u0097\u0098\7i\2\2\u0098$\3\2\2\2\u0099")
+ buf.write("\u009a\7x\2\2\u009a\u009b\7c\2\2\u009b\u009c\7t\2\2\u009c")
+ buf.write("&\3\2\2\2\u009d\u009e\7n\2\2\u009e\u009f\7k\2\2\u009f")
+ buf.write("\u00a0\7u\2\2\u00a0\u00a1\7v\2\2\u00a1(\3\2\2\2\u00a2")
+ buf.write("\u00a3\7>\2\2\u00a3*\3\2\2\2\u00a4\u00a5\7@\2\2\u00a5")
+ buf.write(",\3\2\2\2\u00a6\u00a7\7o\2\2\u00a7\u00a8\7q\2\2\u00a8")
+ buf.write("\u00a9\7f\2\2\u00a9\u00aa\7g\2\2\u00aa\u00ab\7n\2\2\u00ab")
+ buf.write(".\3\2\2\2\u00ac\u00ad\7u\2\2\u00ad\u00ae\7v\2\2\u00ae")
+ buf.write("\u00af\7t\2\2\u00af\u00b0\7w\2\2\u00b0\u00b1\7e\2\2\u00b1")
+ buf.write("\u00b2\7v\2\2\u00b2\60\3\2\2\2\u00b3\u00b4\7g\2\2\u00b4")
+ buf.write("\u00b5\7p\2\2\u00b5\u00b6\7w\2\2\u00b6\u00b7\7o\2\2\u00b7")
+ buf.write("\62\3\2\2\2\u00b8\u00b9\7h\2\2\u00b9\u00ba\7n\2\2\u00ba")
+ buf.write("\u00bb\7c\2\2\u00bb\u00bc\7i\2\2\u00bc\64\3\2\2\2\u00bd")
+ buf.write("\u00c1\7B\2\2\u00be\u00c0\n\2\2\2\u00bf\u00be\3\2\2\2")
+ buf.write("\u00c0\u00c3\3\2\2\2\u00c1\u00bf\3\2\2\2\u00c1\u00c2\3")
+ buf.write("\2\2\2\u00c2\66\3\2\2\2\u00c3\u00c1\3\2\2\2\u00c4\u00c6")
+ buf.write("\t\3\2\2\u00c5\u00c4\3\2\2\2\u00c5\u00c6\3\2\2\2\u00c6")
+ buf.write("\u00c8\3\2\2\2\u00c7\u00c9\4\62;\2\u00c8\u00c7\3\2\2\2")
+ buf.write("\u00c9\u00ca\3\2\2\2\u00ca\u00c8\3\2\2\2\u00ca\u00cb\3")
+ buf.write("\2\2\2\u00cb8\3\2\2\2\u00cc\u00cd\7\62\2\2\u00cd\u00ce")
+ buf.write("\7z\2\2\u00ce\u00d0\3\2\2\2\u00cf\u00d1\t\4\2\2\u00d0")
+ buf.write("\u00cf\3\2\2\2\u00d1\u00d2\3\2\2\2\u00d2\u00d0\3\2\2\2")
+ buf.write("\u00d2\u00d3\3\2\2\2\u00d3:\3\2\2\2\u00d4\u00d5\7B\2\2")
+ buf.write("\u00d5\u00d9\t\5\2\2\u00d6\u00d8\t\6\2\2\u00d7\u00d6\3")
+ buf.write("\2\2\2\u00d8\u00db\3\2\2\2\u00d9\u00d7\3\2\2\2\u00d9\u00da")
+ buf.write("\3\2\2\2\u00da<\3\2\2\2\u00db\u00d9\3\2\2\2\u00dc\u00e0")
+ buf.write("\t\5\2\2\u00dd\u00df\t\6\2\2\u00de\u00dd\3\2\2\2\u00df")
+ buf.write("\u00e2\3\2\2\2\u00e0\u00de\3\2\2\2\u00e0\u00e1\3\2\2\2")
+ buf.write("\u00e1>\3\2\2\2\u00e2\u00e0\3\2\2\2\u00e3\u00e4\t\7\2")
+ buf.write("\2\u00e4\u00e5\7\60\2\2\u00e5\u00e6\t\7\2\2\u00e6@\3\2")
+ buf.write("\2\2\u00e7\u00e8\7\61\2\2\u00e8\u00e9\7,\2\2\u00e9\u00ea")
+ buf.write("\7,\2\2\u00ea\u00ee\3\2\2\2\u00eb\u00ed\13\2\2\2\u00ec")
+ buf.write("\u00eb\3\2\2\2\u00ed\u00f0\3\2\2\2\u00ee\u00ef\3\2\2\2")
+ buf.write("\u00ee\u00ec\3\2\2\2\u00ef\u00f1\3\2\2\2\u00f0\u00ee\3")
+ buf.write("\2\2\2\u00f1\u00f2\7,\2\2\u00f2\u00f3\7\61\2\2\u00f3B")
+ buf.write("\3\2\2\2\u00f4\u00f6\t\b\2\2\u00f5\u00f4\3\2\2\2\u00f6")
+ buf.write("\u00f7\3\2\2\2\u00f7\u00f5\3\2\2\2\u00f7\u00f8\3\2\2\2")
+ buf.write("\u00f8\u00f9\3\2\2\2\u00f9\u00fa\b\"\2\2\u00faD\3\2\2")
+ buf.write("\2\u00fb\u00fc\7\61\2\2\u00fc\u00fd\7\61\2\2\u00fd\u0101")
+ buf.write("\3\2\2\2\u00fe\u0100\n\2\2\2\u00ff\u00fe\3\2\2\2\u0100")
+ buf.write("\u0103\3\2\2\2\u0101\u00ff\3\2\2\2\u0101\u0102\3\2\2\2")
+ buf.write("\u0102\u0104\3\2\2\2\u0103\u0101\3\2\2\2\u0104\u0105\b")
+ buf.write("#\2\2\u0105F\3\2\2\2\u0106\u0107\7\61\2\2\u0107\u0108")
+ buf.write("\7,\2\2\u0108\u010c\3\2\2\2\u0109\u010b\13\2\2\2\u010a")
+ buf.write("\u0109\3\2\2\2\u010b\u010e\3\2\2\2\u010c\u010d\3\2\2\2")
+ buf.write("\u010c\u010a\3\2\2\2\u010d\u010f\3\2\2\2\u010e\u010c\3")
+ buf.write("\2\2\2\u010f\u0110\7,\2\2\u0110\u0111\7\61\2\2\u0111\u0112")
+ buf.write("\3\2\2\2\u0112\u0113\b$\2\2\u0113H\3\2\2\2\r\2\u00c1\u00c5")
+ buf.write("\u00ca\u00d2\u00d9\u00e0\u00ee\u00f7\u0101\u010c\3\b\2")
+ buf.write("\2")
return buf.getvalue()
@@ -150,15 +155,16 @@ class TLexer(Lexer):
T__22 = 23
T__23 = 24
T__24 = 25
- INTCONSTANT = 26
- HEXCONSTANT = 27
- TAGIDENTIFIER = 28
- IDENTIFIER = 29
- VERSION = 30
- DOCCOMMENT = 31
- WHITESPACE = 32
- COMMENT = 33
- MULTICOMM = 34
+ TAGLINE = 26
+ INTCONSTANT = 27
+ HEXCONSTANT = 28
+ TAGIDENTIFIER = 29
+ IDENTIFIER = 30
+ VERSION = 31
+ DOCCOMMENT = 32
+ WHITESPACE = 33
+ COMMENT = 34
+ MULTICOMM = 35
modeNames = [ "DEFAULT_MODE" ]
@@ -169,15 +175,15 @@ class TLexer(Lexer):
"'<'", "'>'", "'model'", "'struct'", "'enum'", "'flag'" ]
symbolicNames = [ "<INVALID>",
- "INTCONSTANT", "HEXCONSTANT", "TAGIDENTIFIER", "IDENTIFIER",
+ "TAGLINE", "INTCONSTANT", "HEXCONSTANT", "TAGIDENTIFIER", "IDENTIFIER",
"VERSION", "DOCCOMMENT", "WHITESPACE", "COMMENT", "MULTICOMM" ]
ruleNames = [ "T__0", "T__1", "T__2", "T__3", "T__4", "T__5", "T__6",
"T__7", "T__8", "T__9", "T__10", "T__11", "T__12", "T__13",
"T__14", "T__15", "T__16", "T__17", "T__18", "T__19",
- "T__20", "T__21", "T__22", "T__23", "T__24", "INTCONSTANT",
- "HEXCONSTANT", "TAGIDENTIFIER", "IDENTIFIER", "VERSION",
- "DOCCOMMENT", "WHITESPACE", "COMMENT", "MULTICOMM" ]
+ "T__20", "T__21", "T__22", "T__23", "T__24", "TAGLINE",
+ "INTCONSTANT", "HEXCONSTANT", "TAGIDENTIFIER", "IDENTIFIER",
+ "VERSION", "DOCCOMMENT", "WHITESPACE", "COMMENT", "MULTICOMM" ]
grammarFileName = "T.g4"
diff --git a/qface/idl/parser/TLexer.tokens b/qface/idl/parser/TLexer.tokens
index 25c2f2f..86bf74a 100644
--- a/qface/idl/parser/TLexer.tokens
+++ b/qface/idl/parser/TLexer.tokens
@@ -23,15 +23,16 @@ T__21=22
T__22=23
T__23=24
T__24=25
-INTCONSTANT=26
-HEXCONSTANT=27
-TAGIDENTIFIER=28
-IDENTIFIER=29
-VERSION=30
-DOCCOMMENT=31
-WHITESPACE=32
-COMMENT=33
-MULTICOMM=34
+TAGLINE=26
+INTCONSTANT=27
+HEXCONSTANT=28
+TAGIDENTIFIER=29
+IDENTIFIER=30
+VERSION=31
+DOCCOMMENT=32
+WHITESPACE=33
+COMMENT=34
+MULTICOMM=35
'import'=1
';'=2
'module'=3
diff --git a/qface/idl/parser/TParser.py b/qface/idl/parser/TParser.py
index d43a416..15eadd6 100644
--- a/qface/idl/parser/TParser.py
+++ b/qface/idl/parser/TParser.py
@@ -5,8 +5,8 @@ from io import StringIO
def serializedATN():
with StringIO() as buf:
- buf.write("\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\3$")
- buf.write("\u0136\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7")
+ buf.write("\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\3%")
+ buf.write("\u0131\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7")
buf.write("\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t\13\4\f\t\f\4\r\t\r\4\16")
buf.write("\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22\4\23\t\23")
buf.write("\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31")
@@ -23,132 +23,129 @@ def serializedATN():
buf.write("\n\3\n\3\n\5\n\u00a3\n\n\3\13\5\13\u00a6\n\13\3\13\7\13")
buf.write("\u00a9\n\13\f\13\16\13\u00ac\13\13\3\13\5\13\u00af\n\13")
buf.write("\3\13\3\13\3\13\5\13\u00b4\n\13\3\f\3\f\3\f\5\f\u00b9")
- buf.write("\n\f\3\r\3\r\3\r\7\r\u00be\n\r\f\r\16\r\u00c1\13\r\3\r")
- buf.write("\3\r\3\16\3\16\3\16\5\16\u00c8\n\16\3\17\3\17\3\17\3\17")
- buf.write("\5\17\u00ce\n\17\3\20\3\20\3\21\3\21\3\21\3\21\3\21\5")
- buf.write("\21\u00d7\n\21\3\22\3\22\3\22\3\22\3\22\3\23\3\23\3\23")
- buf.write("\3\23\3\23\3\24\5\24\u00e4\n\24\3\24\7\24\u00e7\n\24\f")
- buf.write("\24\16\24\u00ea\13\24\3\24\3\24\3\24\3\24\7\24\u00f0\n")
- buf.write("\24\f\24\16\24\u00f3\13\24\3\24\3\24\5\24\u00f7\n\24\3")
- buf.write("\25\5\25\u00fa\n\25\3\25\7\25\u00fd\n\25\f\25\16\25\u0100")
- buf.write("\13\25\3\25\3\25\3\25\5\25\u0105\n\25\3\26\5\26\u0108")
- buf.write("\n\26\3\26\7\26\u010b\n\26\f\26\16\26\u010e\13\26\3\26")
- buf.write("\3\26\3\26\3\26\7\26\u0114\n\26\f\26\16\26\u0117\13\26")
- buf.write("\3\26\3\26\5\26\u011b\n\26\3\27\3\27\5\27\u011f\n\27\3")
- buf.write("\30\5\30\u0122\n\30\3\30\7\30\u0125\n\30\f\30\16\30\u0128")
- buf.write("\13\30\3\30\3\30\3\30\5\30\u012d\n\30\3\30\5\30\u0130")
- buf.write("\n\30\3\31\3\31\5\31\u0134\n\31\3\31\2\2\32\2\4\6\b\n")
- buf.write("\f\16\20\22\24\26\30\32\34\36 \"$&(*,.\60\2\2\u0153\2")
- buf.write("\62\3\2\2\2\49\3\2\2\2\6@\3\2\2\2\bG\3\2\2\2\nX\3\2\2")
- buf.write("\2\f[\3\2\2\2\16s\3\2\2\2\20v\3\2\2\2\22\u008f\3\2\2\2")
- buf.write("\24\u00a5\3\2\2\2\26\u00b5\3\2\2\2\30\u00ba\3\2\2\2\32")
- buf.write("\u00c4\3\2\2\2\34\u00cd\3\2\2\2\36\u00cf\3\2\2\2 \u00d6")
- buf.write("\3\2\2\2\"\u00d8\3\2\2\2$\u00dd\3\2\2\2&\u00e3\3\2\2\2")
- buf.write("(\u00f9\3\2\2\2*\u0107\3\2\2\2,\u011e\3\2\2\2.\u0121\3")
- buf.write("\2\2\2\60\u0133\3\2\2\2\62\66\5\4\3\2\63\65\5\n\6\2\64")
- buf.write("\63\3\2\2\2\658\3\2\2\2\66\64\3\2\2\2\66\67\3\2\2\2\67")
- buf.write("\3\3\2\2\28\66\3\2\2\29=\5\b\5\2:<\5\6\4\2;:\3\2\2\2<")
- buf.write("?\3\2\2\2=;\3\2\2\2=>\3\2\2\2>\5\3\2\2\2?=\3\2\2\2@A\7")
- buf.write("\3\2\2AB\7\37\2\2BD\7 \2\2CE\7\4\2\2DC\3\2\2\2DE\3\2\2")
- buf.write("\2E\7\3\2\2\2FH\7!\2\2GF\3\2\2\2GH\3\2\2\2HL\3\2\2\2I")
- buf.write("K\5\30\r\2JI\3\2\2\2KN\3\2\2\2LJ\3\2\2\2LM\3\2\2\2MO\3")
- buf.write("\2\2\2NL\3\2\2\2OP\7\5\2\2PQ\7\37\2\2QS\7 \2\2RT\7\4\2")
- buf.write("\2SR\3\2\2\2ST\3\2\2\2T\t\3\2\2\2UY\5\f\7\2VY\5&\24\2")
- buf.write("WY\5*\26\2XU\3\2\2\2XV\3\2\2\2XW\3\2\2\2Y\13\3\2\2\2Z")
- buf.write("\\\7!\2\2[Z\3\2\2\2[\\\3\2\2\2\\`\3\2\2\2]_\5\30\r\2^")
- buf.write("]\3\2\2\2_b\3\2\2\2`^\3\2\2\2`a\3\2\2\2ac\3\2\2\2b`\3")
- buf.write("\2\2\2cd\7\6\2\2de\7\37\2\2ei\7\7\2\2fh\5\16\b\2gf\3\2")
- buf.write("\2\2hk\3\2\2\2ig\3\2\2\2ij\3\2\2\2jl\3\2\2\2ki\3\2\2\2")
- buf.write("ln\7\b\2\2mo\7\4\2\2nm\3\2\2\2no\3\2\2\2o\r\3\2\2\2pt")
- buf.write("\5\20\t\2qt\5\24\13\2rt\5\22\n\2sp\3\2\2\2sq\3\2\2\2s")
- buf.write("r\3\2\2\2t\17\3\2\2\2uw\7!\2\2vu\3\2\2\2vw\3\2\2\2w{\3")
- buf.write("\2\2\2xz\5\30\r\2yx\3\2\2\2z}\3\2\2\2{y\3\2\2\2{|\3\2")
- buf.write("\2\2|\u0080\3\2\2\2}{\3\2\2\2~\u0081\5\34\17\2\177\u0081")
- buf.write("\7\t\2\2\u0080~\3\2\2\2\u0080\177\3\2\2\2\u0081\u0082")
- buf.write("\3\2\2\2\u0082\u0083\7\37\2\2\u0083\u0087\7\n\2\2\u0084")
- buf.write("\u0086\5\26\f\2\u0085\u0084\3\2\2\2\u0086\u0089\3\2\2")
- buf.write("\2\u0087\u0085\3\2\2\2\u0087\u0088\3\2\2\2\u0088\u008a")
- buf.write("\3\2\2\2\u0089\u0087\3\2\2\2\u008a\u008c\7\13\2\2\u008b")
- buf.write("\u008d\7\4\2\2\u008c\u008b\3\2\2\2\u008c\u008d\3\2\2\2")
- buf.write("\u008d\21\3\2\2\2\u008e\u0090\7!\2\2\u008f\u008e\3\2\2")
- buf.write("\2\u008f\u0090\3\2\2\2\u0090\u0094\3\2\2\2\u0091\u0093")
- buf.write("\5\30\r\2\u0092\u0091\3\2\2\2\u0093\u0096\3\2\2\2\u0094")
- buf.write("\u0092\3\2\2\2\u0094\u0095\3\2\2\2\u0095\u0097\3\2\2\2")
- buf.write("\u0096\u0094\3\2\2\2\u0097\u0098\7\f\2\2\u0098\u0099\7")
- buf.write("\37\2\2\u0099\u009d\7\n\2\2\u009a\u009c\5\26\f\2\u009b")
- buf.write("\u009a\3\2\2\2\u009c\u009f\3\2\2\2\u009d\u009b\3\2\2\2")
- buf.write("\u009d\u009e\3\2\2\2\u009e\u00a0\3\2\2\2\u009f\u009d\3")
- buf.write("\2\2\2\u00a0\u00a2\7\13\2\2\u00a1\u00a3\7\4\2\2\u00a2")
- buf.write("\u00a1\3\2\2\2\u00a2\u00a3\3\2\2\2\u00a3\23\3\2\2\2\u00a4")
- buf.write("\u00a6\7!\2\2\u00a5\u00a4\3\2\2\2\u00a5\u00a6\3\2\2\2")
- buf.write("\u00a6\u00aa\3\2\2\2\u00a7\u00a9\5\30\r\2\u00a8\u00a7")
- buf.write("\3\2\2\2\u00a9\u00ac\3\2\2\2\u00aa\u00a8\3\2\2\2\u00aa")
- buf.write("\u00ab\3\2\2\2\u00ab\u00ae\3\2\2\2\u00ac\u00aa\3\2\2\2")
- buf.write("\u00ad\u00af\7\r\2\2\u00ae\u00ad\3\2\2\2\u00ae\u00af\3")
- buf.write("\2\2\2\u00af\u00b0\3\2\2\2\u00b0\u00b1\5\34\17\2\u00b1")
- buf.write("\u00b3\7\37\2\2\u00b2\u00b4\7\4\2\2\u00b3\u00b2\3\2\2")
- buf.write("\2\u00b3\u00b4\3\2\2\2\u00b4\25\3\2\2\2\u00b5\u00b6\5")
- buf.write("\34\17\2\u00b6\u00b8\7\37\2\2\u00b7\u00b9\7\16\2\2\u00b8")
- buf.write("\u00b7\3\2\2\2\u00b8\u00b9\3\2\2\2\u00b9\27\3\2\2\2\u00ba")
- buf.write("\u00bb\7\36\2\2\u00bb\u00bf\7\n\2\2\u00bc\u00be\5\32\16")
- buf.write("\2\u00bd\u00bc\3\2\2\2\u00be\u00c1\3\2\2\2\u00bf\u00bd")
- buf.write("\3\2\2\2\u00bf\u00c0\3\2\2\2\u00c0\u00c2\3\2\2\2\u00c1")
- buf.write("\u00bf\3\2\2\2\u00c2\u00c3\7\13\2\2\u00c3\31\3\2\2\2\u00c4")
- buf.write("\u00c7\7\37\2\2\u00c5\u00c6\7\17\2\2\u00c6\u00c8\7\37")
- buf.write("\2\2\u00c7\u00c5\3\2\2\2\u00c7\u00c8\3\2\2\2\u00c8\33")
- buf.write("\3\2\2\2\u00c9\u00ce\5 \21\2\u00ca\u00ce\5\36\20\2\u00cb")
- buf.write("\u00ce\5\"\22\2\u00cc\u00ce\5$\23\2\u00cd\u00c9\3\2\2")
- buf.write("\2\u00cd\u00ca\3\2\2\2\u00cd\u00cb\3\2\2\2\u00cd\u00cc")
- buf.write("\3\2\2\2\u00ce\35\3\2\2\2\u00cf\u00d0\7\37\2\2\u00d0\37")
- buf.write("\3\2\2\2\u00d1\u00d7\7\20\2\2\u00d2\u00d7\7\21\2\2\u00d3")
- buf.write("\u00d7\7\22\2\2\u00d4\u00d7\7\23\2\2\u00d5\u00d7\7\24")
- buf.write("\2\2\u00d6\u00d1\3\2\2\2\u00d6\u00d2\3\2\2\2\u00d6\u00d3")
- buf.write("\3\2\2\2\u00d6\u00d4\3\2\2\2\u00d6\u00d5\3\2\2\2\u00d7")
- buf.write("!\3\2\2\2\u00d8\u00d9\7\25\2\2\u00d9\u00da\7\26\2\2\u00da")
- buf.write("\u00db\5\34\17\2\u00db\u00dc\7\27\2\2\u00dc#\3\2\2\2\u00dd")
- buf.write("\u00de\7\30\2\2\u00de\u00df\7\26\2\2\u00df\u00e0\5\34")
- buf.write("\17\2\u00e0\u00e1\7\27\2\2\u00e1%\3\2\2\2\u00e2\u00e4")
- buf.write("\7!\2\2\u00e3\u00e2\3\2\2\2\u00e3\u00e4\3\2\2\2\u00e4")
- buf.write("\u00e8\3\2\2\2\u00e5\u00e7\5\30\r\2\u00e6\u00e5\3\2\2")
- buf.write("\2\u00e7\u00ea\3\2\2\2\u00e8\u00e6\3\2\2\2\u00e8\u00e9")
- buf.write("\3\2\2\2\u00e9\u00eb\3\2\2\2\u00ea\u00e8\3\2\2\2\u00eb")
- buf.write("\u00ec\7\31\2\2\u00ec\u00ed\7\37\2\2\u00ed\u00f1\7\7\2")
- buf.write("\2\u00ee\u00f0\5(\25\2\u00ef\u00ee\3\2\2\2\u00f0\u00f3")
- buf.write("\3\2\2\2\u00f1\u00ef\3\2\2\2\u00f1\u00f2\3\2\2\2\u00f2")
- buf.write("\u00f4\3\2\2\2\u00f3\u00f1\3\2\2\2\u00f4\u00f6\7\b\2\2")
- buf.write("\u00f5\u00f7\7\4\2\2\u00f6\u00f5\3\2\2\2\u00f6\u00f7\3")
- buf.write("\2\2\2\u00f7\'\3\2\2\2\u00f8\u00fa\7!\2\2\u00f9\u00f8")
- buf.write("\3\2\2\2\u00f9\u00fa\3\2\2\2\u00fa\u00fe\3\2\2\2\u00fb")
- buf.write("\u00fd\5\30\r\2\u00fc\u00fb\3\2\2\2\u00fd\u0100\3\2\2")
- buf.write("\2\u00fe\u00fc\3\2\2\2\u00fe\u00ff\3\2\2\2\u00ff\u0101")
- buf.write("\3\2\2\2\u0100\u00fe\3\2\2\2\u0101\u0102\5\34\17\2\u0102")
- buf.write("\u0104\7\37\2\2\u0103\u0105\7\4\2\2\u0104\u0103\3\2\2")
- buf.write("\2\u0104\u0105\3\2\2\2\u0105)\3\2\2\2\u0106\u0108\7!\2")
- buf.write("\2\u0107\u0106\3\2\2\2\u0107\u0108\3\2\2\2\u0108\u010c")
- buf.write("\3\2\2\2\u0109\u010b\5\30\r\2\u010a\u0109\3\2\2\2\u010b")
- buf.write("\u010e\3\2\2\2\u010c\u010a\3\2\2\2\u010c\u010d\3\2\2\2")
- buf.write("\u010d\u010f\3\2\2\2\u010e\u010c\3\2\2\2\u010f\u0110\5")
- buf.write(",\27\2\u0110\u0111\7\37\2\2\u0111\u0115\7\7\2\2\u0112")
- buf.write("\u0114\5.\30\2\u0113\u0112\3\2\2\2\u0114\u0117\3\2\2\2")
- buf.write("\u0115\u0113\3\2\2\2\u0115\u0116\3\2\2\2\u0116\u0118\3")
- buf.write("\2\2\2\u0117\u0115\3\2\2\2\u0118\u011a\7\b\2\2\u0119\u011b")
- buf.write("\7\4\2\2\u011a\u0119\3\2\2\2\u011a\u011b\3\2\2\2\u011b")
- buf.write("+\3\2\2\2\u011c\u011f\7\32\2\2\u011d\u011f\7\33\2\2\u011e")
- buf.write("\u011c\3\2\2\2\u011e\u011d\3\2\2\2\u011f-\3\2\2\2\u0120")
- buf.write("\u0122\7!\2\2\u0121\u0120\3\2\2\2\u0121\u0122\3\2\2\2")
- buf.write("\u0122\u0126\3\2\2\2\u0123\u0125\5\30\r\2\u0124\u0123")
- buf.write("\3\2\2\2\u0125\u0128\3\2\2\2\u0126\u0124\3\2\2\2\u0126")
- buf.write("\u0127\3\2\2\2\u0127\u0129\3\2\2\2\u0128\u0126\3\2\2\2")
- buf.write("\u0129\u012c\7\37\2\2\u012a\u012b\7\17\2\2\u012b\u012d")
- buf.write("\5\60\31\2\u012c\u012a\3\2\2\2\u012c\u012d\3\2\2\2\u012d")
- buf.write("\u012f\3\2\2\2\u012e\u0130\7\16\2\2\u012f\u012e\3\2\2")
- buf.write("\2\u012f\u0130\3\2\2\2\u0130/\3\2\2\2\u0131\u0134\7\34")
- buf.write("\2\2\u0132\u0134\7\35\2\2\u0133\u0131\3\2\2\2\u0133\u0132")
- buf.write("\3\2\2\2\u0134\61\3\2\2\2\61\66=DGLSX[`insv{\u0080\u0087")
+ buf.write("\n\f\3\r\3\r\3\16\3\16\3\16\5\16\u00c0\n\16\3\16\5\16")
+ buf.write("\u00c3\n\16\3\17\3\17\3\17\3\17\5\17\u00c9\n\17\3\20\3")
+ buf.write("\20\3\21\3\21\3\21\3\21\3\21\5\21\u00d2\n\21\3\22\3\22")
+ buf.write("\3\22\3\22\3\22\3\23\3\23\3\23\3\23\3\23\3\24\5\24\u00df")
+ buf.write("\n\24\3\24\7\24\u00e2\n\24\f\24\16\24\u00e5\13\24\3\24")
+ buf.write("\3\24\3\24\3\24\7\24\u00eb\n\24\f\24\16\24\u00ee\13\24")
+ buf.write("\3\24\3\24\5\24\u00f2\n\24\3\25\5\25\u00f5\n\25\3\25\7")
+ buf.write("\25\u00f8\n\25\f\25\16\25\u00fb\13\25\3\25\3\25\3\25\5")
+ buf.write("\25\u0100\n\25\3\26\5\26\u0103\n\26\3\26\7\26\u0106\n")
+ buf.write("\26\f\26\16\26\u0109\13\26\3\26\3\26\3\26\3\26\7\26\u010f")
+ buf.write("\n\26\f\26\16\26\u0112\13\26\3\26\3\26\5\26\u0116\n\26")
+ buf.write("\3\27\3\27\5\27\u011a\n\27\3\30\5\30\u011d\n\30\3\30\7")
+ buf.write("\30\u0120\n\30\f\30\16\30\u0123\13\30\3\30\3\30\3\30\5")
+ buf.write("\30\u0128\n\30\3\30\5\30\u012b\n\30\3\31\3\31\5\31\u012f")
+ buf.write("\n\31\3\31\2\2\32\2\4\6\b\n\f\16\20\22\24\26\30\32\34")
+ buf.write("\36 \"$&(*,.\60\2\2\u014e\2\62\3\2\2\2\49\3\2\2\2\6@\3")
+ buf.write("\2\2\2\bG\3\2\2\2\nX\3\2\2\2\f[\3\2\2\2\16s\3\2\2\2\20")
+ buf.write("v\3\2\2\2\22\u008f\3\2\2\2\24\u00a5\3\2\2\2\26\u00b5\3")
+ buf.write("\2\2\2\30\u00ba\3\2\2\2\32\u00bc\3\2\2\2\34\u00c8\3\2")
+ buf.write("\2\2\36\u00ca\3\2\2\2 \u00d1\3\2\2\2\"\u00d3\3\2\2\2$")
+ buf.write("\u00d8\3\2\2\2&\u00de\3\2\2\2(\u00f4\3\2\2\2*\u0102\3")
+ buf.write("\2\2\2,\u0119\3\2\2\2.\u011c\3\2\2\2\60\u012e\3\2\2\2")
+ buf.write("\62\66\5\4\3\2\63\65\5\n\6\2\64\63\3\2\2\2\658\3\2\2\2")
+ buf.write("\66\64\3\2\2\2\66\67\3\2\2\2\67\3\3\2\2\28\66\3\2\2\2")
+ buf.write("9=\5\b\5\2:<\5\6\4\2;:\3\2\2\2<?\3\2\2\2=;\3\2\2\2=>\3")
+ buf.write("\2\2\2>\5\3\2\2\2?=\3\2\2\2@A\7\3\2\2AB\7 \2\2BD\7!\2")
+ buf.write("\2CE\7\4\2\2DC\3\2\2\2DE\3\2\2\2E\7\3\2\2\2FH\7\"\2\2")
+ buf.write("GF\3\2\2\2GH\3\2\2\2HL\3\2\2\2IK\5\30\r\2JI\3\2\2\2KN")
+ buf.write("\3\2\2\2LJ\3\2\2\2LM\3\2\2\2MO\3\2\2\2NL\3\2\2\2OP\7\5")
+ buf.write("\2\2PQ\7 \2\2QS\7!\2\2RT\7\4\2\2SR\3\2\2\2ST\3\2\2\2T")
+ buf.write("\t\3\2\2\2UY\5\f\7\2VY\5&\24\2WY\5*\26\2XU\3\2\2\2XV\3")
+ buf.write("\2\2\2XW\3\2\2\2Y\13\3\2\2\2Z\\\7\"\2\2[Z\3\2\2\2[\\\3")
+ buf.write("\2\2\2\\`\3\2\2\2]_\5\30\r\2^]\3\2\2\2_b\3\2\2\2`^\3\2")
+ buf.write("\2\2`a\3\2\2\2ac\3\2\2\2b`\3\2\2\2cd\7\6\2\2de\7 \2\2")
+ buf.write("ei\7\7\2\2fh\5\16\b\2gf\3\2\2\2hk\3\2\2\2ig\3\2\2\2ij")
+ buf.write("\3\2\2\2jl\3\2\2\2ki\3\2\2\2ln\7\b\2\2mo\7\4\2\2nm\3\2")
+ buf.write("\2\2no\3\2\2\2o\r\3\2\2\2pt\5\20\t\2qt\5\24\13\2rt\5\22")
+ buf.write("\n\2sp\3\2\2\2sq\3\2\2\2sr\3\2\2\2t\17\3\2\2\2uw\7\"\2")
+ buf.write("\2vu\3\2\2\2vw\3\2\2\2w{\3\2\2\2xz\5\30\r\2yx\3\2\2\2")
+ buf.write("z}\3\2\2\2{y\3\2\2\2{|\3\2\2\2|\u0080\3\2\2\2}{\3\2\2")
+ buf.write("\2~\u0081\5\34\17\2\177\u0081\7\t\2\2\u0080~\3\2\2\2\u0080")
+ buf.write("\177\3\2\2\2\u0081\u0082\3\2\2\2\u0082\u0083\7 \2\2\u0083")
+ buf.write("\u0087\7\n\2\2\u0084\u0086\5\26\f\2\u0085\u0084\3\2\2")
+ buf.write("\2\u0086\u0089\3\2\2\2\u0087\u0085\3\2\2\2\u0087\u0088")
+ buf.write("\3\2\2\2\u0088\u008a\3\2\2\2\u0089\u0087\3\2\2\2\u008a")
+ buf.write("\u008c\7\13\2\2\u008b\u008d\7\4\2\2\u008c\u008b\3\2\2")
+ buf.write("\2\u008c\u008d\3\2\2\2\u008d\21\3\2\2\2\u008e\u0090\7")
+ buf.write("\"\2\2\u008f\u008e\3\2\2\2\u008f\u0090\3\2\2\2\u0090\u0094")
+ buf.write("\3\2\2\2\u0091\u0093\5\30\r\2\u0092\u0091\3\2\2\2\u0093")
+ buf.write("\u0096\3\2\2\2\u0094\u0092\3\2\2\2\u0094\u0095\3\2\2\2")
+ buf.write("\u0095\u0097\3\2\2\2\u0096\u0094\3\2\2\2\u0097\u0098\7")
+ buf.write("\f\2\2\u0098\u0099\7 \2\2\u0099\u009d\7\n\2\2\u009a\u009c")
+ buf.write("\5\26\f\2\u009b\u009a\3\2\2\2\u009c\u009f\3\2\2\2\u009d")
+ buf.write("\u009b\3\2\2\2\u009d\u009e\3\2\2\2\u009e\u00a0\3\2\2\2")
+ buf.write("\u009f\u009d\3\2\2\2\u00a0\u00a2\7\13\2\2\u00a1\u00a3")
+ buf.write("\7\4\2\2\u00a2\u00a1\3\2\2\2\u00a2\u00a3\3\2\2\2\u00a3")
+ buf.write("\23\3\2\2\2\u00a4\u00a6\7\"\2\2\u00a5\u00a4\3\2\2\2\u00a5")
+ buf.write("\u00a6\3\2\2\2\u00a6\u00aa\3\2\2\2\u00a7\u00a9\5\30\r")
+ buf.write("\2\u00a8\u00a7\3\2\2\2\u00a9\u00ac\3\2\2\2\u00aa\u00a8")
+ buf.write("\3\2\2\2\u00aa\u00ab\3\2\2\2\u00ab\u00ae\3\2\2\2\u00ac")
+ buf.write("\u00aa\3\2\2\2\u00ad\u00af\7\r\2\2\u00ae\u00ad\3\2\2\2")
+ buf.write("\u00ae\u00af\3\2\2\2\u00af\u00b0\3\2\2\2\u00b0\u00b1\5")
+ buf.write("\34\17\2\u00b1\u00b3\7 \2\2\u00b2\u00b4\7\4\2\2\u00b3")
+ buf.write("\u00b2\3\2\2\2\u00b3\u00b4\3\2\2\2\u00b4\25\3\2\2\2\u00b5")
+ buf.write("\u00b6\5\34\17\2\u00b6\u00b8\7 \2\2\u00b7\u00b9\7\16\2")
+ buf.write("\2\u00b8\u00b7\3\2\2\2\u00b8\u00b9\3\2\2\2\u00b9\27\3")
+ buf.write("\2\2\2\u00ba\u00bb\7\34\2\2\u00bb\31\3\2\2\2\u00bc\u00bf")
+ buf.write("\7 \2\2\u00bd\u00be\7\17\2\2\u00be\u00c0\7 \2\2\u00bf")
+ buf.write("\u00bd\3\2\2\2\u00bf\u00c0\3\2\2\2\u00c0\u00c2\3\2\2\2")
+ buf.write("\u00c1\u00c3\7\16\2\2\u00c2\u00c1\3\2\2\2\u00c2\u00c3")
+ buf.write("\3\2\2\2\u00c3\33\3\2\2\2\u00c4\u00c9\5 \21\2\u00c5\u00c9")
+ buf.write("\5\36\20\2\u00c6\u00c9\5\"\22\2\u00c7\u00c9\5$\23\2\u00c8")
+ buf.write("\u00c4\3\2\2\2\u00c8\u00c5\3\2\2\2\u00c8\u00c6\3\2\2\2")
+ buf.write("\u00c8\u00c7\3\2\2\2\u00c9\35\3\2\2\2\u00ca\u00cb\7 \2")
+ buf.write("\2\u00cb\37\3\2\2\2\u00cc\u00d2\7\20\2\2\u00cd\u00d2\7")
+ buf.write("\21\2\2\u00ce\u00d2\7\22\2\2\u00cf\u00d2\7\23\2\2\u00d0")
+ buf.write("\u00d2\7\24\2\2\u00d1\u00cc\3\2\2\2\u00d1\u00cd\3\2\2")
+ buf.write("\2\u00d1\u00ce\3\2\2\2\u00d1\u00cf\3\2\2\2\u00d1\u00d0")
+ buf.write("\3\2\2\2\u00d2!\3\2\2\2\u00d3\u00d4\7\25\2\2\u00d4\u00d5")
+ buf.write("\7\26\2\2\u00d5\u00d6\5\34\17\2\u00d6\u00d7\7\27\2\2\u00d7")
+ buf.write("#\3\2\2\2\u00d8\u00d9\7\30\2\2\u00d9\u00da\7\26\2\2\u00da")
+ buf.write("\u00db\5\34\17\2\u00db\u00dc\7\27\2\2\u00dc%\3\2\2\2\u00dd")
+ buf.write("\u00df\7\"\2\2\u00de\u00dd\3\2\2\2\u00de\u00df\3\2\2\2")
+ buf.write("\u00df\u00e3\3\2\2\2\u00e0\u00e2\5\30\r\2\u00e1\u00e0")
+ buf.write("\3\2\2\2\u00e2\u00e5\3\2\2\2\u00e3\u00e1\3\2\2\2\u00e3")
+ buf.write("\u00e4\3\2\2\2\u00e4\u00e6\3\2\2\2\u00e5\u00e3\3\2\2\2")
+ buf.write("\u00e6\u00e7\7\31\2\2\u00e7\u00e8\7 \2\2\u00e8\u00ec\7")
+ buf.write("\7\2\2\u00e9\u00eb\5(\25\2\u00ea\u00e9\3\2\2\2\u00eb\u00ee")
+ buf.write("\3\2\2\2\u00ec\u00ea\3\2\2\2\u00ec\u00ed\3\2\2\2\u00ed")
+ buf.write("\u00ef\3\2\2\2\u00ee\u00ec\3\2\2\2\u00ef\u00f1\7\b\2\2")
+ buf.write("\u00f0\u00f2\7\4\2\2\u00f1\u00f0\3\2\2\2\u00f1\u00f2\3")
+ buf.write("\2\2\2\u00f2\'\3\2\2\2\u00f3\u00f5\7\"\2\2\u00f4\u00f3")
+ buf.write("\3\2\2\2\u00f4\u00f5\3\2\2\2\u00f5\u00f9\3\2\2\2\u00f6")
+ buf.write("\u00f8\5\30\r\2\u00f7\u00f6\3\2\2\2\u00f8\u00fb\3\2\2")
+ buf.write("\2\u00f9\u00f7\3\2\2\2\u00f9\u00fa\3\2\2\2\u00fa\u00fc")
+ buf.write("\3\2\2\2\u00fb\u00f9\3\2\2\2\u00fc\u00fd\5\34\17\2\u00fd")
+ buf.write("\u00ff\7 \2\2\u00fe\u0100\7\4\2\2\u00ff\u00fe\3\2\2\2")
+ buf.write("\u00ff\u0100\3\2\2\2\u0100)\3\2\2\2\u0101\u0103\7\"\2")
+ buf.write("\2\u0102\u0101\3\2\2\2\u0102\u0103\3\2\2\2\u0103\u0107")
+ buf.write("\3\2\2\2\u0104\u0106\5\30\r\2\u0105\u0104\3\2\2\2\u0106")
+ buf.write("\u0109\3\2\2\2\u0107\u0105\3\2\2\2\u0107\u0108\3\2\2\2")
+ buf.write("\u0108\u010a\3\2\2\2\u0109\u0107\3\2\2\2\u010a\u010b\5")
+ buf.write(",\27\2\u010b\u010c\7 \2\2\u010c\u0110\7\7\2\2\u010d\u010f")
+ buf.write("\5.\30\2\u010e\u010d\3\2\2\2\u010f\u0112\3\2\2\2\u0110")
+ buf.write("\u010e\3\2\2\2\u0110\u0111\3\2\2\2\u0111\u0113\3\2\2\2")
+ buf.write("\u0112\u0110\3\2\2\2\u0113\u0115\7\b\2\2\u0114\u0116\7")
+ buf.write("\4\2\2\u0115\u0114\3\2\2\2\u0115\u0116\3\2\2\2\u0116+")
+ buf.write("\3\2\2\2\u0117\u011a\7\32\2\2\u0118\u011a\7\33\2\2\u0119")
+ buf.write("\u0117\3\2\2\2\u0119\u0118\3\2\2\2\u011a-\3\2\2\2\u011b")
+ buf.write("\u011d\7\"\2\2\u011c\u011b\3\2\2\2\u011c\u011d\3\2\2\2")
+ buf.write("\u011d\u0121\3\2\2\2\u011e\u0120\5\30\r\2\u011f\u011e")
+ buf.write("\3\2\2\2\u0120\u0123\3\2\2\2\u0121\u011f\3\2\2\2\u0121")
+ buf.write("\u0122\3\2\2\2\u0122\u0124\3\2\2\2\u0123\u0121\3\2\2\2")
+ buf.write("\u0124\u0127\7 \2\2\u0125\u0126\7\17\2\2\u0126\u0128\5")
+ buf.write("\60\31\2\u0127\u0125\3\2\2\2\u0127\u0128\3\2\2\2\u0128")
+ buf.write("\u012a\3\2\2\2\u0129\u012b\7\16\2\2\u012a\u0129\3\2\2")
+ buf.write("\2\u012a\u012b\3\2\2\2\u012b/\3\2\2\2\u012c\u012f\7\35")
+ buf.write("\2\2\u012d\u012f\7\36\2\2\u012e\u012c\3\2\2\2\u012e\u012d")
+ buf.write("\3\2\2\2\u012f\61\3\2\2\2\61\66=DGLSX[`insv{\u0080\u0087")
buf.write("\u008c\u008f\u0094\u009d\u00a2\u00a5\u00aa\u00ae\u00b3")
- buf.write("\u00b8\u00bf\u00c7\u00cd\u00d6\u00e3\u00e8\u00f1\u00f6")
- buf.write("\u00f9\u00fe\u0104\u0107\u010c\u0115\u011a\u011e\u0121")
- buf.write("\u0126\u012c\u012f\u0133")
+ buf.write("\u00b8\u00bf\u00c2\u00c8\u00d1\u00de\u00e3\u00ec\u00f1")
+ buf.write("\u00f4\u00f9\u00ff\u0102\u0107\u0110\u0115\u0119\u011c")
+ buf.write("\u0121\u0127\u012a\u012e")
return buf.getvalue()
@@ -174,9 +171,9 @@ class TParser ( Parser ):
"<INVALID>", "<INVALID>", "<INVALID>", "<INVALID>",
"<INVALID>", "<INVALID>", "<INVALID>", "<INVALID>",
"<INVALID>", "<INVALID>", "<INVALID>", "<INVALID>",
- "<INVALID>", "<INVALID>", "INTCONSTANT", "HEXCONSTANT",
- "TAGIDENTIFIER", "IDENTIFIER", "VERSION", "DOCCOMMENT",
- "WHITESPACE", "COMMENT", "MULTICOMM" ]
+ "<INVALID>", "<INVALID>", "TAGLINE", "INTCONSTANT",
+ "HEXCONSTANT", "TAGIDENTIFIER", "IDENTIFIER", "VERSION",
+ "DOCCOMMENT", "WHITESPACE", "COMMENT", "MULTICOMM" ]
RULE_documentSymbol = 0
RULE_headerSymbol = 1
@@ -238,15 +235,16 @@ class TParser ( Parser ):
T__22=23
T__23=24
T__24=25
- INTCONSTANT=26
- HEXCONSTANT=27
- TAGIDENTIFIER=28
- IDENTIFIER=29
- VERSION=30
- DOCCOMMENT=31
- WHITESPACE=32
- COMMENT=33
- MULTICOMM=34
+ TAGLINE=26
+ INTCONSTANT=27
+ HEXCONSTANT=28
+ TAGIDENTIFIER=29
+ IDENTIFIER=30
+ VERSION=31
+ DOCCOMMENT=32
+ WHITESPACE=33
+ COMMENT=34
+ MULTICOMM=35
def __init__(self, input:TokenStream):
super().__init__(input)
@@ -305,7 +303,7 @@ class TParser ( Parser ):
self.state = 52
self._errHandler.sync(self)
_la = self._input.LA(1)
- while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << TParser.T__3) | (1 << TParser.T__22) | (1 << TParser.T__23) | (1 << TParser.T__24) | (1 << TParser.TAGIDENTIFIER) | (1 << TParser.DOCCOMMENT))) != 0):
+ while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << TParser.T__3) | (1 << TParser.T__22) | (1 << TParser.T__23) | (1 << TParser.T__24) | (1 << TParser.TAGLINE) | (1 << TParser.DOCCOMMENT))) != 0):
self.state = 49
self.definitionSymbol()
self.state = 54
@@ -510,7 +508,7 @@ class TParser ( Parser ):
self.state = 74
self._errHandler.sync(self)
_la = self._input.LA(1)
- while _la==TParser.TAGIDENTIFIER:
+ while _la==TParser.TAGLINE:
self.state = 71
self.tagSymbol()
self.state = 76
@@ -678,7 +676,7 @@ class TParser ( Parser ):
self.state = 94
self._errHandler.sync(self)
_la = self._input.LA(1)
- while _la==TParser.TAGIDENTIFIER:
+ while _la==TParser.TAGLINE:
self.state = 91
self.tagSymbol()
self.state = 96
@@ -694,7 +692,7 @@ class TParser ( Parser ):
self.state = 103
self._errHandler.sync(self)
_la = self._input.LA(1)
- while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << TParser.T__6) | (1 << TParser.T__9) | (1 << TParser.T__10) | (1 << TParser.T__13) | (1 << TParser.T__14) | (1 << TParser.T__15) | (1 << TParser.T__16) | (1 << TParser.T__17) | (1 << TParser.T__18) | (1 << TParser.T__21) | (1 << TParser.TAGIDENTIFIER) | (1 << TParser.IDENTIFIER) | (1 << TParser.DOCCOMMENT))) != 0):
+ while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << TParser.T__6) | (1 << TParser.T__9) | (1 << TParser.T__10) | (1 << TParser.T__13) | (1 << TParser.T__14) | (1 << TParser.T__15) | (1 << TParser.T__16) | (1 << TParser.T__17) | (1 << TParser.T__18) | (1 << TParser.T__21) | (1 << TParser.TAGLINE) | (1 << TParser.IDENTIFIER) | (1 << TParser.DOCCOMMENT))) != 0):
self.state = 100
self.interfaceMemberSymbol()
self.state = 105
@@ -862,7 +860,7 @@ class TParser ( Parser ):
self.state = 121
self._errHandler.sync(self)
_la = self._input.LA(1)
- while _la==TParser.TAGIDENTIFIER:
+ while _la==TParser.TAGLINE:
self.state = 118
self.tagSymbol()
self.state = 123
@@ -981,7 +979,7 @@ class TParser ( Parser ):
self.state = 146
self._errHandler.sync(self)
_la = self._input.LA(1)
- while _la==TParser.TAGIDENTIFIER:
+ while _la==TParser.TAGLINE:
self.state = 143
self.tagSymbol()
self.state = 148
@@ -1086,7 +1084,7 @@ class TParser ( Parser ):
self.state = 168
self._errHandler.sync(self)
_la = self._input.LA(1)
- while _la==TParser.TAGIDENTIFIER:
+ while _la==TParser.TAGLINE:
self.state = 165
self.tagSymbol()
self.state = 170
@@ -1187,17 +1185,10 @@ class TParser ( Parser ):
def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
super().__init__(parent, invokingState)
self.parser = parser
- self.name = None # Token
-
- def TAGIDENTIFIER(self):
- return self.getToken(TParser.TAGIDENTIFIER, 0)
-
- def tagAttributeSymbol(self, i:int=None):
- if i is None:
- return self.getTypedRuleContexts(TParser.TagAttributeSymbolContext)
- else:
- return self.getTypedRuleContext(TParser.TagAttributeSymbolContext,i)
+ self.line = None # Token
+ def TAGLINE(self):
+ return self.getToken(TParser.TAGLINE, 0)
def getRuleIndex(self):
return TParser.RULE_tagSymbol
@@ -1223,25 +1214,10 @@ class TParser ( Parser ):
localctx = TParser.TagSymbolContext(self, self._ctx, self.state)
self.enterRule(localctx, 22, self.RULE_tagSymbol)
- self._la = 0 # Token type
try:
self.enterOuterAlt(localctx, 1)
self.state = 184
- localctx.name = self.match(TParser.TAGIDENTIFIER)
- self.state = 185
- self.match(TParser.T__7)
- self.state = 189
- self._errHandler.sync(self)
- _la = self._input.LA(1)
- while _la==TParser.IDENTIFIER:
- self.state = 186
- self.tagAttributeSymbol()
- self.state = 191
- self._errHandler.sync(self)
- _la = self._input.LA(1)
-
- self.state = 192
- self.match(TParser.T__8)
+ localctx.line = self.match(TParser.TAGLINE)
except RecognitionException as re:
localctx.exception = re
self._errHandler.reportError(self, re)
@@ -1291,18 +1267,26 @@ class TParser ( Parser ):
self._la = 0 # Token type
try:
self.enterOuterAlt(localctx, 1)
- self.state = 194
+ self.state = 186
localctx.name = self.match(TParser.IDENTIFIER)
- self.state = 197
+ self.state = 189
self._errHandler.sync(self)
_la = self._input.LA(1)
if _la==TParser.T__12:
- self.state = 195
+ self.state = 187
self.match(TParser.T__12)
- self.state = 196
+ self.state = 188
localctx.value = self.match(TParser.IDENTIFIER)
+ self.state = 192
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ if _la==TParser.T__11:
+ self.state = 191
+ self.match(TParser.T__11)
+
+
except RecognitionException as re:
localctx.exception = re
self._errHandler.reportError(self, re)
@@ -1358,27 +1342,27 @@ class TParser ( Parser ):
localctx = TParser.TypeSymbolContext(self, self._ctx, self.state)
self.enterRule(localctx, 26, self.RULE_typeSymbol)
try:
- self.state = 203
+ self.state = 198
self._errHandler.sync(self)
token = self._input.LA(1)
if token in [TParser.T__13, TParser.T__14, TParser.T__15, TParser.T__16, TParser.T__17]:
self.enterOuterAlt(localctx, 1)
- self.state = 199
+ self.state = 194
self.primitiveTypeSymbol()
pass
elif token in [TParser.IDENTIFIER]:
self.enterOuterAlt(localctx, 2)
- self.state = 200
+ self.state = 195
self.complexTypeSymbol()
pass
elif token in [TParser.T__18]:
self.enterOuterAlt(localctx, 3)
- self.state = 201
+ self.state = 196
self.listTypeSymbol()
pass
elif token in [TParser.T__21]:
self.enterOuterAlt(localctx, 4)
- self.state = 202
+ self.state = 197
self.modelTypeSymbol()
pass
else:
@@ -1428,7 +1412,7 @@ class TParser ( Parser ):
self.enterRule(localctx, 28, self.RULE_complexTypeSymbol)
try:
self.enterOuterAlt(localctx, 1)
- self.state = 205
+ self.state = 200
localctx.name = self.match(TParser.IDENTIFIER)
except RecognitionException as re:
localctx.exception = re
@@ -1471,32 +1455,32 @@ class TParser ( Parser ):
localctx = TParser.PrimitiveTypeSymbolContext(self, self._ctx, self.state)
self.enterRule(localctx, 30, self.RULE_primitiveTypeSymbol)
try:
- self.state = 212
+ self.state = 207
self._errHandler.sync(self)
token = self._input.LA(1)
if token in [TParser.T__13]:
self.enterOuterAlt(localctx, 1)
- self.state = 207
+ self.state = 202
localctx.name = self.match(TParser.T__13)
pass
elif token in [TParser.T__14]:
self.enterOuterAlt(localctx, 2)
- self.state = 208
+ self.state = 203
localctx.name = self.match(TParser.T__14)
pass
elif token in [TParser.T__15]:
self.enterOuterAlt(localctx, 3)
- self.state = 209
+ self.state = 204
localctx.name = self.match(TParser.T__15)
pass
elif token in [TParser.T__16]:
self.enterOuterAlt(localctx, 4)
- self.state = 210
+ self.state = 205
localctx.name = self.match(TParser.T__16)
pass
elif token in [TParser.T__17]:
self.enterOuterAlt(localctx, 5)
- self.state = 211
+ self.state = 206
localctx.name = self.match(TParser.T__17)
pass
else:
@@ -1547,13 +1531,13 @@ class TParser ( Parser ):
self.enterRule(localctx, 32, self.RULE_listTypeSymbol)
try:
self.enterOuterAlt(localctx, 1)
- self.state = 214
+ self.state = 209
self.match(TParser.T__18)
- self.state = 215
+ self.state = 210
self.match(TParser.T__19)
- self.state = 216
+ self.state = 211
localctx.valueType = self.typeSymbol()
- self.state = 217
+ self.state = 212
self.match(TParser.T__20)
except RecognitionException as re:
localctx.exception = re
@@ -1600,13 +1584,13 @@ class TParser ( Parser ):
self.enterRule(localctx, 34, self.RULE_modelTypeSymbol)
try:
self.enterOuterAlt(localctx, 1)
- self.state = 219
+ self.state = 214
self.match(TParser.T__21)
- self.state = 220
+ self.state = 215
self.match(TParser.T__19)
- self.state = 221
+ self.state = 216
localctx.valueType = self.typeSymbol()
- self.state = 222
+ self.state = 217
self.match(TParser.T__20)
except RecognitionException as re:
localctx.exception = re
@@ -1671,47 +1655,47 @@ class TParser ( Parser ):
self._la = 0 # Token type
try:
self.enterOuterAlt(localctx, 1)
- self.state = 225
+ self.state = 220
self._errHandler.sync(self)
_la = self._input.LA(1)
if _la==TParser.DOCCOMMENT:
- self.state = 224
+ self.state = 219
localctx.comment = self.match(TParser.DOCCOMMENT)
- self.state = 230
+ self.state = 225
self._errHandler.sync(self)
_la = self._input.LA(1)
- while _la==TParser.TAGIDENTIFIER:
- self.state = 227
+ while _la==TParser.TAGLINE:
+ self.state = 222
self.tagSymbol()
- self.state = 232
+ self.state = 227
self._errHandler.sync(self)
_la = self._input.LA(1)
- self.state = 233
+ self.state = 228
self.match(TParser.T__22)
- self.state = 234
+ self.state = 229
localctx.name = self.match(TParser.IDENTIFIER)
- self.state = 235
+ self.state = 230
self.match(TParser.T__4)
- self.state = 239
+ self.state = 234
self._errHandler.sync(self)
_la = self._input.LA(1)
- while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << TParser.T__13) | (1 << TParser.T__14) | (1 << TParser.T__15) | (1 << TParser.T__16) | (1 << TParser.T__17) | (1 << TParser.T__18) | (1 << TParser.T__21) | (1 << TParser.TAGIDENTIFIER) | (1 << TParser.IDENTIFIER) | (1 << TParser.DOCCOMMENT))) != 0):
- self.state = 236
+ while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << TParser.T__13) | (1 << TParser.T__14) | (1 << TParser.T__15) | (1 << TParser.T__16) | (1 << TParser.T__17) | (1 << TParser.T__18) | (1 << TParser.T__21) | (1 << TParser.TAGLINE) | (1 << TParser.IDENTIFIER) | (1 << TParser.DOCCOMMENT))) != 0):
+ self.state = 231
self.structFieldSymbol()
- self.state = 241
+ self.state = 236
self._errHandler.sync(self)
_la = self._input.LA(1)
- self.state = 242
+ self.state = 237
self.match(TParser.T__5)
- self.state = 244
+ self.state = 239
self._errHandler.sync(self)
_la = self._input.LA(1)
if _la==TParser.T__1:
- self.state = 243
+ self.state = 238
self.match(TParser.T__1)
@@ -1775,33 +1759,33 @@ class TParser ( Parser ):
self._la = 0 # Token type
try:
self.enterOuterAlt(localctx, 1)
- self.state = 247
+ self.state = 242
self._errHandler.sync(self)
_la = self._input.LA(1)
if _la==TParser.DOCCOMMENT:
- self.state = 246
+ self.state = 241
localctx.comment = self.match(TParser.DOCCOMMENT)
- self.state = 252
+ self.state = 247
self._errHandler.sync(self)
_la = self._input.LA(1)
- while _la==TParser.TAGIDENTIFIER:
- self.state = 249
+ while _la==TParser.TAGLINE:
+ self.state = 244
self.tagSymbol()
- self.state = 254
+ self.state = 249
self._errHandler.sync(self)
_la = self._input.LA(1)
- self.state = 255
+ self.state = 250
self.typeSymbol()
- self.state = 256
+ self.state = 251
localctx.name = self.match(TParser.IDENTIFIER)
- self.state = 258
+ self.state = 253
self._errHandler.sync(self)
_la = self._input.LA(1)
if _la==TParser.T__1:
- self.state = 257
+ self.state = 252
self.match(TParser.T__1)
@@ -1872,47 +1856,47 @@ class TParser ( Parser ):
self._la = 0 # Token type
try:
self.enterOuterAlt(localctx, 1)
- self.state = 261
+ self.state = 256
self._errHandler.sync(self)
_la = self._input.LA(1)
if _la==TParser.DOCCOMMENT:
- self.state = 260
+ self.state = 255
localctx.comment = self.match(TParser.DOCCOMMENT)
- self.state = 266
+ self.state = 261
self._errHandler.sync(self)
_la = self._input.LA(1)
- while _la==TParser.TAGIDENTIFIER:
- self.state = 263
+ while _la==TParser.TAGLINE:
+ self.state = 258
self.tagSymbol()
- self.state = 268
+ self.state = 263
self._errHandler.sync(self)
_la = self._input.LA(1)
- self.state = 269
+ self.state = 264
self.enumTypeSymbol()
- self.state = 270
+ self.state = 265
localctx.name = self.match(TParser.IDENTIFIER)
- self.state = 271
+ self.state = 266
self.match(TParser.T__4)
- self.state = 275
+ self.state = 270
self._errHandler.sync(self)
_la = self._input.LA(1)
- while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << TParser.TAGIDENTIFIER) | (1 << TParser.IDENTIFIER) | (1 << TParser.DOCCOMMENT))) != 0):
- self.state = 272
+ while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << TParser.TAGLINE) | (1 << TParser.IDENTIFIER) | (1 << TParser.DOCCOMMENT))) != 0):
+ self.state = 267
self.enumMemberSymbol()
- self.state = 277
+ self.state = 272
self._errHandler.sync(self)
_la = self._input.LA(1)
- self.state = 278
+ self.state = 273
self.match(TParser.T__5)
- self.state = 280
+ self.state = 275
self._errHandler.sync(self)
_la = self._input.LA(1)
if _la==TParser.T__1:
- self.state = 279
+ self.state = 274
self.match(TParser.T__1)
@@ -1958,17 +1942,17 @@ class TParser ( Parser ):
localctx = TParser.EnumTypeSymbolContext(self, self._ctx, self.state)
self.enterRule(localctx, 42, self.RULE_enumTypeSymbol)
try:
- self.state = 284
+ self.state = 279
self._errHandler.sync(self)
token = self._input.LA(1)
if token in [TParser.T__23]:
self.enterOuterAlt(localctx, 1)
- self.state = 282
+ self.state = 277
localctx.isEnum = self.match(TParser.T__23)
pass
elif token in [TParser.T__24]:
self.enterOuterAlt(localctx, 2)
- self.state = 283
+ self.state = 278
localctx.isFlag = self.match(TParser.T__24)
pass
else:
@@ -2034,41 +2018,41 @@ class TParser ( Parser ):
self._la = 0 # Token type
try:
self.enterOuterAlt(localctx, 1)
- self.state = 287
+ self.state = 282
self._errHandler.sync(self)
_la = self._input.LA(1)
if _la==TParser.DOCCOMMENT:
- self.state = 286
+ self.state = 281
localctx.comment = self.match(TParser.DOCCOMMENT)
- self.state = 292
+ self.state = 287
self._errHandler.sync(self)
_la = self._input.LA(1)
- while _la==TParser.TAGIDENTIFIER:
- self.state = 289
+ while _la==TParser.TAGLINE:
+ self.state = 284
self.tagSymbol()
- self.state = 294
+ self.state = 289
self._errHandler.sync(self)
_la = self._input.LA(1)
- self.state = 295
+ self.state = 290
localctx.name = self.match(TParser.IDENTIFIER)
- self.state = 298
+ self.state = 293
self._errHandler.sync(self)
_la = self._input.LA(1)
if _la==TParser.T__12:
- self.state = 296
+ self.state = 291
self.match(TParser.T__12)
- self.state = 297
+ self.state = 292
self.intSymbol()
- self.state = 301
+ self.state = 296
self._errHandler.sync(self)
_la = self._input.LA(1)
if _la==TParser.T__11:
- self.state = 300
+ self.state = 295
self.match(TParser.T__11)
@@ -2118,17 +2102,17 @@ class TParser ( Parser ):
localctx = TParser.IntSymbolContext(self, self._ctx, self.state)
self.enterRule(localctx, 46, self.RULE_intSymbol)
try:
- self.state = 305
+ self.state = 300
self._errHandler.sync(self)
token = self._input.LA(1)
if token in [TParser.INTCONSTANT]:
self.enterOuterAlt(localctx, 1)
- self.state = 303
+ self.state = 298
localctx.value = self.match(TParser.INTCONSTANT)
pass
elif token in [TParser.HEXCONSTANT]:
self.enterOuterAlt(localctx, 2)
- self.state = 304
+ self.state = 299
localctx.value = self.match(TParser.HEXCONSTANT)
pass
else:
diff --git a/qface/utils.py b/qface/utils.py
new file mode 100644
index 0000000..3122d38
--- /dev/null
+++ b/qface/utils.py
@@ -0,0 +1,10 @@
+
+
+def merge(a, b):
+ "merges b into a recursively if a and b are dicts"
+ for key in b:
+ if isinstance(a.get(key), dict) and isinstance(b.get(key), dict):
+ merge(a[key], b[key])
+ else:
+ a[key] = b[key]
+ return a
diff --git a/qface/watch.py b/qface/watch.py
index 4a8512f..9129bfa 100644
--- a/qface/watch.py
+++ b/qface/watch.py
@@ -10,9 +10,9 @@ Provides an API to monitor the file system
"""
class RunScriptChangeHandler(FileSystemEventHandler):
- def __init__(self, argv):
+ def __init__(self, script):
super().__init__()
- self.argv = argv
+ self.script = script
self.is_running = False
def on_modified(self, event):
@@ -22,21 +22,20 @@ class RunScriptChangeHandler(FileSystemEventHandler):
if self.is_running:
return
self.is_running = True
- # cmd = '{0} {1}'.format(sys.executable, ' '.join(self.argv))
- sh(' '.join(self.argv), cwd=Path.getcwd())
+ sh(self.script, cwd=Path.getcwd())
self.is_running = False
-def monitor(src, argv):
+def monitor(script, src, dst):
"""
reloads the script given by argv when src files changes
"""
- script = Path(argv[0]).expand().abspath()
src = src if isinstance(src, (list, tuple)) else [src]
+ script = '{0} {1} {2}'.format(script, ' '.join(src), dst)
src = [Path(entry).expand().abspath() for entry in src]
- event_handler = RunScriptChangeHandler(argv)
+ event_handler = RunScriptChangeHandler(script)
observer = Observer()
- path = script.dirname().expand().abspath()
+ path = Path(script).dirname().expand().abspath()
click.secho('watch recursive: {0}'.format(path), fg='blue')
observer.schedule(event_handler, path, recursive=True)
for entry in src:
diff --git a/requirements.txt b/requirements.txt
index bbcf80e..c0f6959 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -3,6 +3,7 @@ jinja2
click
path.py
watchdog
+livereload
pyyaml
pytest
coverage
diff --git a/setup.py b/setup.py
index f76196d..c9815a6 100644
--- a/setup.py
+++ b/setup.py
@@ -52,6 +52,7 @@ setup(
'pyyaml',
'antlr4-python3-runtime>=4.6',
'click',
+ 'watchdog',
],
extras_require={
'dev': [
diff --git a/tests/in/com.pelagicore.ivi.tuner.qface b/tests/in/com.pelagicore.ivi.tuner.qface
index 765e9f5..c50a4c8 100644
--- a/tests/in/com.pelagicore.ivi.tuner.qface
+++ b/tests/in/com.pelagicore.ivi.tuner.qface
@@ -1,8 +1,10 @@
module com.pelagicore.ivi.tuner 1.0;
/** Service Tuner */
-@service()
-@interface()
+@service: true
+@interface: true
+@config: {private: true, b: B, c: C}
+@data: [1,2,3]
interface Tuner {
/** property currentStation */
readonly Station currentStation;
@@ -35,7 +37,7 @@ enum State {
}
/** enum Waveband */
-@default(value=FM)
+@default: {value: FM}
enum Waveband {
/** value Waveband.FM */
FM=0,
diff --git a/tests/in/com.pelagicore.ivi.tuner.yaml b/tests/in/com.pelagicore.ivi.tuner.yaml
index 948c50c..a320743 100644
--- a/tests/in/com.pelagicore.ivi.tuner.yaml
+++ b/tests/in/com.pelagicore.ivi.tuner.yaml
@@ -1,2 +1,6 @@
com.pelagicore.ivi.tuner.Tuner:
- port: 12345
+ port: 12345
+ config:
+ a: a
+ b: b
+
diff --git a/tests/in/com.pelagicore.test.qface b/tests/in/com.pelagicore.test.qface
index c3b5cbf..ae8a4f0 100644
--- a/tests/in/com.pelagicore.test.qface
+++ b/tests/in/com.pelagicore.test.qface
@@ -2,7 +2,7 @@ module com.pelagicore.test 1.0;
import common 1.0;
-@service(singleton=True)
+@service: { singleton: true}
interface ContactService {
State state;
int intValue;
diff --git a/tests/test_comments.py b/tests/test_comments.py
index 707f759..008dd0d 100644
--- a/tests/test_comments.py
+++ b/tests/test_comments.py
@@ -35,11 +35,9 @@ def test_comment():
interface = system.lookup('org.example.echo.Echo')
assert interface
o = doc.parse_doc(interface.comment)
- # import pdb; pdb.set_trace()
assert o.brief == 'the brief'
assert o.description == ['the description', 'continues {@link http://qt.io}']
assert o.deprecated is True
- # import pdb; pdb.set_trace()
assert o.see == ['org.example.echo.Echo', 'org.example', 'http://qt.io']
diff --git a/tests/test_parser.py b/tests/test_parser.py
index 2da5e44..d94a96f 100644
--- a/tests/test_parser.py
+++ b/tests/test_parser.py
@@ -99,7 +99,6 @@ def test_enum_counter():
system = load_test()
enum = system.lookup('com.pelagicore.test.State')
assert enum
- # import ipdb; ipdb.set_trace()
assert enum._memberMap['Null'].value is 0
assert enum._memberMap['Failure'].value is 3
@@ -108,7 +107,6 @@ def test_flag_counter():
system = load_test()
flag = system.lookup('com.pelagicore.test.Phase')
assert flag
- # import ipdb; ipdb.set_trace()
assert flag._memberMap['PhaseOne'].value is 1
assert flag._memberMap['PhaseTwo'].value is 2
assert flag._memberMap['PhaseThree'].value is 4
diff --git a/tests/test_tags.py b/tests/test_tags.py
index 527b623..82f2c90 100644
--- a/tests/test_tags.py
+++ b/tests/test_tags.py
@@ -3,6 +3,7 @@ import logging
import logging.config
from path import Path
+
# logging.config.fileConfig('logging.ini')
logging.basicConfig()
@@ -44,3 +45,17 @@ def test_meta_tags():
interface = system.lookup('com.pelagicore.ivi.tuner.Tuner')
assert interface
assert 'port' in interface.tags
+
+
+def test_flag():
+ system = loadTuner()
+ interface = system.lookup('com.pelagicore.ivi.tuner.Tuner')
+ assert interface
+ assert interface.attribute('config', 'private') is True
+ assert interface.attribute('config', 'a') == 'a' # use value from yaml
+ assert interface.attribute('config', 'b') == 'b' # use value from yaml
+ assert interface.attribute('config', 'c') == 'C' # use value from IDL
+ assert interface.tags['data'] == [1, 2, 3] # array annotatiom
+
+
+