|
|
|
Re: Linux kernel (ARM) dts parser. [message #1706470 is a reply to message #1706447] |
Thu, 27 August 2015 07:11 |
|
Hi Mauro,
I guess at first you were trying to copy-paste the yacc-grammar? That won't work since Xtext has a different syntax. Doing it from scratch is the way to go =)
Whitespace: To control which tokens are ignored inside a rule, use the "hidden"-clause. e.g.
Address hidden(): //<-- empty argument list means no tokens are hidden
'@' UNSIGNEDINT
;
Semantic rules are handled in your language's validator. Keep your grammar simple and lenient. That makes it easier to maintain and allows you to give more meaningful error messages.
Cheers,
Stefan
|
|
|
|
|
|
Re: Linux kernel (ARM) dts parser. [message #1706623 is a reply to message #1706572] |
Fri, 28 August 2015 08:30 |
|
Hey Mauro,
here are some suggestions:
- don't try to parse whitespace in a rule that ignores whitespace (if the whitespace is significant to the semantics, it should not be hidden. If it is just a coding convention, you can add a check in the validator)
- use terminals sparingly, just have one integer type and check value ranges in the validator (For example, 111 is a valid 8-bit integer, but would have been rejected by your grammar)
- the STRING rule clashed with the UserInclude rule. This is because as soon as the lexer sees a '"', it will consume a STRING token, but the UserInclude rule expected something different.
- don't nest you rules too deep. Every nested rule call will also lead to a nested element in the AST, making it hard to navigate (the childl and memresl rules were superflous for instance)
- the grammar was missing some expected characters like ';', so it couldn't match the example
- try to follow the Xtext naming conventions (upper camel for parser rules, upper underscore for terminal rules), that makes it easier for people to help you
See below a greatly simplified grammar that successfully matches your example. I made it inherit from terminals and use the rules from terminals as much as possible, as that gives you value converters and syntax highlighting out of the box. For your own types like SysFile and HEX, you will need to write value converters so that your AST contains the values you would expect. For instance, you probably want your HEX values converted to integers in the AST.
Cheers,
Stefan
grammar it.condarelli.devicetree.DeviceTree with org.eclipse.xtext.common.Terminals
generate deviceTree "http://www.condarelli.it/devicetree/DeviceTree"
import "http://www.eclipse.org/emf/2002/Ecore" as ecore
DeviceTree:
(includes+=Include)* '/dts-v1/' ';' (includes+=Include)* (memres+=Memres)* '/' node=Node;
Include:
'#' 'include' file=FileSpec;
Memres:
'/memreserve/' address=Number length=Number ';';
Node:
{Node} '{' (properties+=Property)* '}' ';';
Property:
CompoundProperty | SimpleProperty;
CompoundProperty:
label=Label? name=ID address=Address? node=Node;
SimpleProperty:
label=Label? name=ID ('=' value=Value)? ';';
Value:
Array | StringValue | Bytestring;
StringValue:
value=STRING;
Array:
'<' components+=Number+ '>';
Bytestring:
'[' bytes+=Number+ ']';
Address hidden():
'@' Number;
Label hidden():
ID ':';
Number:
INT | HEX;
FileSpec:
SysFile | UserFile;
SysFile:
'<' (ID | '/' | '.')* '>';
UserFile:
STRING;
terminal ID:
('a'..'z' | 'A'..'Z' | '_') ('a'..'z' | 'A'..'Z' | '_' | '-' | '0'..'9')*;
terminal HEX:
('0x' | '0X') ('0'..'9' | 'a'..'f' | 'A'..'F' | '_')+;
[Updated on: Fri, 28 August 2015 08:31] Report message to a moderator
|
|
|
Re: Linux kernel (ARM) dts parser. [message #1706702 is a reply to message #1706623] |
Fri, 28 August 2015 20:08 |
|
By the way, the #include rule was giving me lots of headaches, since it'll always clash with Strings and Arrays. And then I realized, that #include is not part of your language per se, but just taken from the C preprocessor.
So instead I made includes a terminal and added them to the hidden tokens. This way they no longer conflict with other rules and they can appear at any point in the file (before they were only allowed at specific points at the top of the file)
terminal INCLUDE:
'#include' -> '\r'? '\n'
;
|
|
|
Powered by
FUDForum. Page generated in 0.03550 seconds