Open fujidana opened 1 month ago
The Igor Pro language contains many ambiguities and for most of them it is quite difficult to write simple grammar rules for them. By the time you further develop your grammar, you will definitely find more.
Because it is (almost) impossible to write simple grammar rules, you have to write general grammar rules that matches all possible variants and then validates at a later stage.
In your case you can do something like this (pseudo code):
call_or_wave_access = <name> <call_or_access_args> (<access_args>)*
At a later stage you have to check if <name>
is defined as a function or as a wave and can then decide if additional <access_args>
were allowed. You also have to validate the <call_or_access_args>
, because foo(opt=1)
is not allowed for wave access and foo(1, 2; 3)
is not allowed for function calls. These checks cant be done at the parsing stage, because it will be very unlikely that you have additional data like a symbol table available, that is required at this point.
I think it is very nice that you further extend your grammar and provide useful information before I have to compile it in Igor, but I don't think you have to match 100% of the Igor language, because you aren't creating a full compiler or a tool that is expected to read and understand everything. A rough understanding and just telling errors if you found some or are against reasonable coding guidelines (e.g. https://github.com/byte-physics/igor-pro-coding-conventions) are enough.
For example, another thing that will trigger several ambiguities. In Igor are commas ,
optional in many places:
Function test()
string msg
sprintf msg "%d" 1
End
I think it is okay if you require a good style and report missing commas as an error. Doing this, you will also be a part in making future Igor code more cleaner. (Oh boy I can tell you there is a lot of weird code in the wild!)
Back to your topic. Just parse the code roughly with general rules and then check your AST nodes at a later point in time if they are sensible. If you break something, you will definitely hear something (from me ๐).
@Garados007 , thanks for your advice.
The current parser implementation is far from perfect. Considering my skill and spare time for developing the extension, it will be (at least for a while) difficult to build a context-sensitive intelligent parser. Instead, I will try to refine the current simple and opportunistic parser. I will appreciate it if you (or someone) could tell me any problems.
I have known the guideline you linked since a few years ago but haven't known that you provide it. In fact, I've tried to keep these rules in my code since I knew this doc. Thanks a lot for providing this well-designed guideline.
but haven't known that you provide it.
In fact its not me but the company I am working for. ๐
I will appreciate it if you (or someone) could tell me any problems.
Yes, I will do it. If you ever encounter some problems, feel free to ask them. ๐
foo(bar)
in Igor Pro code can be interpreted as both a function call and a wave element using scaled index.Recently I found the parser diagnosed a line such as
myNewWave = sourceWave(x)(y)
in an IPF file as an error because the parser regardedsourceWave(x)
as a function call and failed to parse the remaining(y)
.I think the best solution for this problem is that the parser manages a list of defined wave references or functions and parses the grammar contextually. However, to implement this behavior it will need entire modification on the current parser code.
As of 23cdf42 (2024-08-04), the parser regards
foo(bar)
as a wave element if it precedes extra(...)
or[...]
and otherwise tokenizes it as a function call. This workaround avoids code such assourceWave(a)(b)
being diagnosed as an error, while the syntax tree can be semantically inaccurate.I would appreciate it if anyone gives me any advices or opinions.