[Home] [Downloads] [Search] [Help/forum]

Gammon Software Solutions forum

See www.mushclient.com/spam for dealing with forum spam. Please read the MUSHclient FAQ!

[Folder]  Entire forum
-> [Folder]  Programming
. -> [Folder]  General
. . -> [Subject]  Expression parser

Home  |  Users  |  Search  |  FAQ
Username:
Register forum user name
Password:
Forgotten password?
(New message)
Subject: Expression parser
Name:
Your forum user name.
Register forum user name
Password:
Your forum password.
Forgotten password?
Message:
Message to be posted (in English, please).
Forum codes:
Check this if your message uses 'forum codes' or templates (auto-detected for new posts).
Forum codes Templates

Save this message ...


Subject review (reverse sequence)

Pages: 1 2  3  4  5  

Posted by Thierry   (2 posts)  [Biography] bio
Date Sat 08 Sep 2012 07:03 AM (UTC)  quote  ]
Message
Hello

Yes, I need to get the information at run time. I scan the symbols map, update the values and call Evaluate a second time .... Working fine !!!

Thanks for that great class ... It will be used in the next release of a freeware called Genesis (www.tgmdev.be), an OPC data acquisition utility for people involved in process automation.

Thierry
[Go to top] top

Posted by Nick Gammon   Australia  (18,770 posts)  [Biography] bio   Forum Administrator
Date Fri 07 Sep 2012 11:50 PM (UTC)  quote  ]

Amended on Sat 08 Sep 2012 07:51 AM (UTC) by Nick Gammon

Message
It's not designed to do that right now. I gather you want to have it "query" for a variable value at runtime, is that right?

Non-defined variables currently default to zero. In particular around line 509:


      // not a function? must be a symbol in the symbol table
      double & v = symbols_ [word]; // get REFERENCE to symbol table entry


This creates the symbol if it doesn't exist, and it will default to zero. You would need to alter that line to do a lookup to see if the symbol exists, and if not have some way of obtaining it (eg. a callback function).

What might work could be to parse twice. First time you get zeroes for each symbol. Then look at the symbol table list to see what symbols get added. Change their values, and re-parse.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by Thierry   (2 posts)  [Biography] bio
Date Fri 07 Sep 2012 08:53 PM (UTC)  quote  ]
Message
Hello

Suppose a user enters an expression like this: (TT_123 * 10)/PT_870

How can I list the two parameters (TT_123 and PT_870) before evaluation to add the assignment
p[TT_123] = 100.0; (for example)
p[PT_870] = 0.56; (for example)

Thanks for your help

Thierry
[Go to top] top

Posted by Nick Gammon   Australia  (18,770 posts)  [Biography] bio   Forum Administrator
Date Wed 03 Nov 2010 08:39 PM (UTC)  quote  ]
Message
The whole design is based on the way C++ works (like, getting variables by reference). To do it for C would be a rewrite.

Would the controller support Lua? That compiles in C. However I believe some micro chips have a different architecture that doesn't work with Lua.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by Georgios   (1 post)  [Biography] bio
Date Wed 03 Nov 2010 08:03 PM (UTC)  quote  ]
Message
Hello Nick

As I can read from your comments and forum messages your expression parser is what I am looking for. The only problem is that I have to use it in a micro controller (ATMEL AVR) in C language.
A post from Jorick at 7th August 2007 has a similar situation (to change from c++ to c).
Have you the code in c ? Or any suggestion to port your code in c ?

Best regards
Georgios
[Go to top] top

Posted by Bernhard   (18 posts)  [Biography] bio
Date Thu 06 May 2010 09:18 PM (UTC)  quote  ]
Message
Thank you Nick and David. I will switch to lua then.

Nick Gammon said:

However if this (0 = true) completely throws people out you have a couple of options:

*For variables that are supposed to be boolean (ie from your internal context) throw an error if they don't supply a boolean (in particular, the number 0 could be ambiguous - did they really mean "false"?)

*Or, for booleans simply convert 0 to false as you process the variable.

You need range-checking anyway (eg. what happens if they make maxUsers to be -100?). So checking booleans have a valid value is just another check.


I'm not sure if I should do that, because it makes conditions internal to lua behave different than the conditions which are passed on to C/C++. If I consider 'return 0' as false when the caller was a C function, it is still true in case the caller was a lua function.


lua_genpcall(L, "if (0) then print '0 is true' end", "");

will allways print '0 is true' unless I change lua itself and make my own dialect ... so I better instruct the users to keep this in mind and tell them something like:

David Haley said:

It's true that you'll have to deal with 0 being 'true' in Lua, but, well, that's life.


;-)

[Go to top] top

Posted by Nick Gammon   Australia  (18,770 posts)  [Biography] bio   Forum Administrator
Date Wed 05 May 2010 09:57 PM (UTC)  quote  ]
Message
Bernhard said:


lua looks quite promising, the only thing I hate is that it considers 0 as true while most (all?) other languages do not - I can already her the users complaining.


The other thing is that I don't know about this being totally true. After all, 0 is a number and false is a boolean. They are different types for a start. Just as an example, in SQL, it uses NULL to represent "no data" in the same way Lua uses nil.

As an example, say on a database you wanted to know how many children someone has. The answer NULL could mean "that number is unknown (and could be anything)" whereas 0 means "we know the answer, and the answer is zero".

Thus trying to make NULL and zero have the same meaning would not be useful.

Similarly with Lua, variables themselves are untyped (the values are typed, not the variable). Thus numerically typed values have to be able to hold any number (including zero) without being mistaken for a boolean typed value.

There is an interesting discussion here:

http://en.wikipedia.org/wiki/Boolean_data_type

Amongst other things it says:

Wikipedia said:

In Ruby programming language, on the other hand, only the null object and a special false object are "false", everything else (including the integer 0) is "true".


So in Ruby, at least, it also does not treat 0 as false.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by Nick Gammon   Australia  (18,770 posts)  [Biography] bio   Forum Administrator
Date Wed 05 May 2010 09:03 PM (UTC)  quote  ]

Amended on Wed 05 May 2010 09:45 PM (UTC) by Nick Gammon

Message
Bernhard said:


lua looks quite promising, the only thing I hate is that it considers 0 as true while most (all?) other languages do not - I can already her the users complaining.


I don't think it is too bad personally. After all, having 0 be false and non-zero to be true is really a throwback to the way C does it (and remember VB used to use -1 for true which is kind of confusing too).

Just say, "for booleans use true and false". It makes sense really.

However if this completely throws people out you have a couple of options:


  • For variables that are supposed to be boolean (ie from your internal context) throw an error if they don't supply a boolean (in particular, the number 0 could be ambiguous - did they really mean "false"?)

  • Or, for booleans simply convert 0 to false as you process the variable.


You need range-checking anyway (eg. what happens if they make maxUsers to be -100?). So checking booleans have a valid value is just another check.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by David Haley   USA  (3,881 posts)  [Biography] bio   Moderator
Date Wed 05 May 2010 08:34 PM (UTC)  quote  ]
Message
It turns out that Lua was originally designed precisely as a configuration language. You can easily extend C/C++ with Lua, as Nick said, and then have config files that look like this:


use_ui = false 


-- high level search settings
directional_increment = 0.05
probabilistic_roadmap_size = 250

probabilistic_focus_roadmap_points_per_point = 5
probabilistic_focus_roadmap_spread_x = 0.10
probabilistic_focus_roadmap_spread_y = 0.10
use_highlevel_smoothing = false

roadmap_predicate_thresholdz_init = 0.01
roadmap_predicate_thresholdz_inc  = 0.01
roadmap_predicate_thresholdz_max  = 0.05

roadmap_predicate_maxside_threshold_init =  0.030
roadmap_predicate_maxside_threshold_inc  =  0.005
roadmap_predicate_maxside_threshold_max  =  0.050

highlevel_goal_proximity = 0.05
highlevel_goal_proximity_factor = 0.3

highlevel_thresholdz_maxjump = 1.5

terrain_polling_num_samples = 50

goal_cost_bias = 0.95
goal_heur_bias = 0.95

highlevel_cost_function = "HighLevelCostFunction"
highlevel_heur_function = "HighLevelHeurFunction"
highlevel_pred_function = "RoadmapVisibilityPredicate"
highlevel_lua_func_file = "highlevel.lua"

-- debugger settings
debug_astar = true
debug_class = true
debug_sim = true
debug_train = true


Or as a more complicated example, like this:

TerrainTypes = {
        beach = { name = "beach", tileImage = "tiles/world/beach.png"},
        densewoods = { name = "densewoods", tileImage = "tiles/world/dense_woods.png" },
        densewoods_snow = { name = "densewoods_snow", tileImage = "tiles/world/dense_woods_snow.png" },
        desert = { name = "desert", tileImage = "tiles/world/desert.png" },
        farmland = { name = "farmland", tileImage = "tiles/world/farmland.png" },
        fields = { name = "fields", tileImage = "tiles/world/fields.png" },
        ice = { name = "ice", tileImage = "tiles/world/ice.png" },
        jungle = { name = "jungle", tileImage = "tiles/world/jungle.png" },
        lightwoods = { name = "lightwoods", tileImage = "tiles/world/light_woods.png" },
        lightwoods_snow = { name = "lightwoods_snow", tileImage = "tiles/world/light_woods_snow.png" },
        mountain = { name = "mountain", tileImage = "tiles/world/mountain.png" },
        ocean = { name = "ocean", tileImage = "tiles/world/ocean.png" },
        pass = { name = "pass", tileImage = "tiles/world/pass.png" },
        plains = { name = "plains", tileImage = "tiles/world/plains.png" },
        range = { name = "range", tileImage = "tiles/world/range.png" },
        river = { name = "river", tileImage = "tiles/world/river.png" },
        rocky = { name = "rocky", tileImage = "tiles/world/rocky.png" },
        savannah = { name = "savannah", tileImage = "tiles/world/savannah.png" },
        snow = { name = "snow", tileImage = "tiles/world/snow.png" },
        swamp = { name = "swamp", tileImage = "tiles/world/swamp.png" },
        tundra = { name = "tundra", tileImage = "tiles/world/tundra.png" },
        wasteland = { name = "wasteland", tileImage = "tiles/world/wasteland.png" },
}


The user doesn't have to even know that they're using Lua; I think that the above examples, especially the first one, show that you can have a config file that is Lua but looks very simple. They can even do variables and have if statements in there, if they want to.

Anyhow, you can have the simple syntax as shown above by loading the script and executing it in a special environment. Then, all assignments to "global" variables will be made into that environment table, and you can pick them out of it later.

It's true that you'll have to deal with 0 being 'true' in Lua, but, well, that's life.



You can do similar things in Python, like this:

name = "Building_Wall"
image = "gfx/Buildings/Wall.bmp"
transparency = (255, 0, 255)

# Cap naming convention: cap_<NESW>
#
# Joint naming convention: joint_<direction in which there is no cap>
#
# Base naming convenition: base_<WE>

tiles = {
    
    'cap_0110': (0, 0, 20, 20),
    'cap_0111': (40, 0, 20, 20),
    'cap_0011': (80, 0, 20, 20),

    'cap_1110': (0, 40, 20, 20),
    'cap_1111': (40, 40, 20, 20),
    'cap_1011': (80, 40, 20, 20),

    'cap_1100': (0, 80, 20, 20),
    'cap_1101': (40, 80, 20, 20),
    'cap_1001': (80, 80, 20, 20),

    'cap_1100_baseleft': (240, 0, 20, 20),
    'cap_1110_baseleft': (240, 40, 20, 20),

    'joint_northeast': (0, 140, 20, 20),
    'joint_northwest': (40, 140, 20, 20),
    'joint_southeast': (80, 140, 20, 20),
    'joint_southwest': (120, 140, 20, 20),

    'base_01': (0, 100, 20, 20),
    'base_11': (40, 100, 20, 20),
    'base_10': (80, 100, 20, 20),

    'dummy': (20, 0, 20, 20),
    
}


but Lua is easier to embed (and much more lightweight) than Python.

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
[Go to top] top

Posted by Bernhard   (18 posts)  [Biography] bio
Date Wed 05 May 2010 08:18 PM (UTC)  quote  ]
Message

My intention was to add some advanced configuration capability to my C/C++ program. Those configurations should not be written by me but by the users – so, usually by people without good programming skills. The basic configuration, let’s call it level 1, would be simple parameters like "maxUsers = 20". I can read them with GetPrivateProfileString/Int or whatever. Level 2 would allow simple expressions, e.g., configurations like "logBufferSize = maxUserSessions * 100" or conditions like "acceptEntry = (userLevel > 5) * (currentUserCount < 20)" – basically the same kind of expressions you can use in Microsoft Excel & co. (which actually allows “if”). I think your parser is perfectly suitable to add this type of configuration features to a C/C++ program. Level 3 allows some simple conditional reactions, maybe similar to state machine descriptions. That's where I ran into troubles with the 'if'. Still I think I should not burden the users with learning a full programming language. It’s beyond debate that anything more than that (level 4) requires a scripting language (vbscript, lua, ..) or (level 5) even a component/plug-in architecture in the main program – that would certainly would overshoot the mark as a configuration/customization interface for someone without proper programming skills.

Level 3 should be sufficient. On the other hand, users tend to want more and more anyway. lua will certainly satisfy even ambitious users and if it encourages someone to learn a full programming language its fine with me. lua looks quite promising, the only thing I hate is that it considers 0 as true while most (all?) other languages do not - I can already her the users complaining. I also have to allow a syntax as simple as "maxUsers = 50" if you only need configuration level 1.

What do you think?
[Go to top] top

Posted by David Haley   USA  (3,881 posts)  [Biography] bio   Moderator
Date Mon 03 May 2010 10:42 PM (UTC)  quote  ]
Message
Yes, I agree, if you want a real programming language why not just use one? What's the higher-level context here?

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
[Go to top] top

Posted by Nick Gammon   Australia  (18,770 posts)  [Biography] bio   Forum Administrator
Date Mon 03 May 2010 08:56 PM (UTC)  quote  ]
Message
Yes, well it is an expression parser, not a full statement parser. If you are going to run external scripts anyway, why not just use Lua? That has a small footprint, and can be imbedded into C or C++ with minimal effort. You can then write things in a more natural way. That would be much, much neater than trying to use this parser and shoe-horn in an external script via system calls. For example:

Template:post=6400 Please see the forum thread: http://gammon.com.au/forum/?id=6400.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by Bernhard   (18 posts)  [Biography] bio
Date Mon 03 May 2010 08:45 PM (UTC)  quote  ]
Message
The two examples in my last post were actually simplified, just to isolate the problem. My real intention (still simplified) was to implemente a sequence of statements like

if(0==eventAB, state17=1,
if(state11, state18=1,
if(state12, state19=1, ...)))
if(0==eventCD, state17=1, if(...))

Of course this can be reformulated to

state17 = if(0==eventAB, 1, state17)
state18 = if((0!=eventAB)&&(state11), 1, state18)
state19 = if((0!=eventAB)&&(0==state11)&&(state12), 1, state19)
...
state17 = if(0==eventCD, 1, state17)

unfortunately it makes the code less readable.

My other intention was to add an "exec(###)" function which calls a batch file (returning the ERRORLEVEL), so basically "return system(script###.bat)" in C. This would allow to get data from external scripts e.g., cond59=exec(11), and to trigger reactions, e.g., if(condition_for_reaction12, exec(12), 0)

[Go to top] top

Posted by Nick Gammon   Australia  (18,770 posts)  [Biography] bio   Forum Administrator
Date Tue 27 Apr 2010 08:13 PM (UTC)  quote  ]
Message
Bernhard said:

"if(something,x=x+1,x)" does not behave like I expected.


David is right. To add 1 to x under a condition you want something more like:


x = if (something, x + 1, x)


The result of the if function will be either x + 1, or x, depending on the condition, and this result is then assigned to x.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by David Haley   USA  (3,881 posts)  [Biography] bio   Moderator
Date Tue 27 Apr 2010 07:44 PM (UTC)  quote  ]
Message
'If' is a function here, not a control flow statement. So, all arguments are evaluated, as for any function, and then the function returns the expression (which, recall, has already been evaluated) matching the condition.

This is by design, this is meant to be an expression parser, not a full language.

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
[Go to top] top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


34,610 views.

This is page 1, subject is 5 pages long: 1 2  3  4  5  [Next page]

[Reply to this subject]  Reply to this subject   [New subject]  Start a new subject   [Refresh] Refresh page

Go to topic:           Search the forum


[Go to top] top

[Home]

Written by Nick Gammon - 5K

Comments to: Gammon Software support
[RH click to get RSS URL] Forum RSS feed ( http://www.gammon.com.au/rss/forum.xml )

[Best viewed with any browser - 2K]    [Internet Contents Rating Association (ICRA) - 2K]    [Web site powered by FutureQuest.Net]